Compare commits

..

No commits in common. 'persist/11.0' and 'qufenxi' have entirely different histories.

  1. 5
      .eslintrc
  2. 502
      README.md
  3. 16
      assets/scripts/dec.js
  4. 14
      babel.config.js
  5. 2
      config/jest.environment.js
  6. 21
      i18n/zh_cn.properties
  7. 8
      index.html
  8. 24
      package.json
  9. 22
      private/i18n.ts
  10. 4
      src/index.ts
  11. 2
      src/less/background.less
  12. 2
      src/less/font.less
  13. 4
      src/less/index.less
  14. 2
      src/less/lib/font.less
  15. 3
      src/modules/__test__/app.test.ts
  16. 18
      src/modules/app.model.ts
  17. 170
      src/modules/app.provider.ts
  18. 112
      src/modules/app.service.ts
  19. 78
      src/modules/app.ts
  20. 11
      src/modules/app.typings.d.ts
  21. 5
      src/modules/components/collapse/collapse.model.ts
  22. 33
      src/modules/components/collapse/collapse.ts
  23. 68
      src/modules/components/file_chooser/file_chooser.model.ts
  24. 183
      src/modules/components/file_chooser/file_chooser.ts
  25. 13
      src/modules/components/file_upload/file_upload.less
  26. 35
      src/modules/components/file_upload/file_upload.model.ts
  27. 327
      src/modules/components/file_upload/file_upload.ts
  28. 52
      src/modules/components/link_button/link.ts
  29. 5
      src/modules/components/test_status/test_status.model.ts
  30. 108
      src/modules/components/test_status/test_status.ts
  31. 6
      src/modules/components/test_status/tip_icon/tip_fail.model.ts
  32. 64
      src/modules/components/test_status/tip_icon/tip_fail.ts
  33. 14
      src/modules/components/test_status/tip_icon/tip_icon.ts
  34. 131
      src/modules/components/text_checker/text_checker.ts
  35. 41
      src/modules/components/tips_combo/tips_combo.ts
  36. 237
      src/modules/constants/constant.ts
  37. 52
      src/modules/core/checkIllegalStrings/checkIllegalStrings.ts
  38. 15
      src/modules/core/checkIllegalStrings/constant.ts
  39. 42
      src/modules/core/core.ts
  40. 1
      src/modules/core/index.ts
  41. 50
      src/modules/crud/api.ts
  42. 6
      src/modules/crud/crud.service.ts
  43. 243
      src/modules/crud/crud.typings.d.ts
  44. 131
      src/modules/crud/decision.api.ts
  45. 68
      src/modules/crud/design.api.ts
  46. 24
      src/modules/pages/__point__/connect.point.ts
  47. 14
      src/modules/pages/connection/components/form_item/form_item.ts
  48. 61
      src/modules/pages/connection/connection.model.ts
  49. 196
      src/modules/pages/connection/connection.ts
  50. 16
      src/modules/pages/connection/connection_jdbc/connection_jdbc.model.ts
  51. 579
      src/modules/pages/connection/connection_jdbc/connection_jdbc.ts
  52. 15
      src/modules/pages/connection/connection_jndi/connection_jndi.model.ts
  53. 73
      src/modules/pages/connection/connection_jndi/connection_jndi.ts
  54. 17
      src/modules/pages/connection/connection_plugin/connection_plugin.model.ts
  55. 9
      src/modules/pages/connection/connection_plugin/connection_plugin.ts
  56. 1
      src/modules/pages/connection/list/list.constant.ts
  57. 50
      src/modules/pages/connection/list/list.model.ts
  58. 40
      src/modules/pages/connection/list/list.ts
  59. 101
      src/modules/pages/connection/list/list_item/list_item.model.ts
  60. 84
      src/modules/pages/connection/list/list_item/list_item.ts
  61. 17
      src/modules/pages/connection_pool/connection_pool.model.ts
  62. 76
      src/modules/pages/connection_pool/connection_pool.ts
  63. 13
      src/modules/pages/connection_pool/list_item/list_item.model.ts
  64. 14
      src/modules/pages/connection_pool/list_item/list_item.ts
  65. 14
      src/modules/pages/connection_pool/pool/pool.model.ts
  66. 71
      src/modules/pages/connection_pool/pool/pool.ts
  67. 17
      src/modules/pages/database/database.constant.ts
  68. 37
      src/modules/pages/database/database.model.ts
  69. 117
      src/modules/pages/database/database.ts
  70. 12
      src/modules/pages/database/database.typings.d.ts
  71. 20
      src/modules/pages/database/database_type/database_type.model.ts
  72. 27
      src/modules/pages/database/database_type/database_type.ts
  73. 13
      src/modules/pages/database/filter/filter.model.ts
  74. 11
      src/modules/pages/database/filter/filter.ts
  75. 10
      src/modules/pages/index.ts
  76. 133
      src/modules/pages/maintain/components/driverselector/driverselector.model.ts
  77. 196
      src/modules/pages/maintain/components/driverselector/driverselector.ts
  78. 29
      src/modules/pages/maintain/components/form_item/form_item.ts
  79. 2677
      src/modules/pages/maintain/forms/components/form.jdbc.ts
  80. 169
      src/modules/pages/maintain/forms/components/form.jndi.ts
  81. 31
      src/modules/pages/maintain/forms/components/form.plugin.ts
  82. 43
      src/modules/pages/maintain/forms/form.model.ts
  83. 82
      src/modules/pages/maintain/forms/form.server.ts
  84. 195
      src/modules/pages/maintain/forms/form.ts
  85. 23
      src/modules/pages/maintain/maintain.model.ts
  86. 46
      src/modules/pages/maintain/maintain.ts
  87. 96
      src/modules/pages/setting/setting.ts
  88. 16
      src/modules/title/title.model.ts
  89. 42
      src/modules/title/title.ts
  90. 16
      src/modules/title/title_database/title_datebase.model.ts
  91. 29
      src/modules/title/title_database/title_datebase.ts
  92. 24
      src/modules/title/title_maintain/title_maintain.model.ts
  93. 36
      src/modules/title/title_maintain/title_maintain.ts
  94. 74
      src/ui/fineui.ts
  95. 1
      src/ui/index.ts
  96. 27
      tsconfig.json
  97. 26
      types/globals.d.ts
  98. 9
      types/request.d.ts
  99. 2
      webpack/webpack.common.js
  100. 5
      webpack/webpack.dev.js
  101. Some files were not shown because too many files have changed in this diff Show More

5
.eslintrc

@ -30,8 +30,7 @@
"no-use-before-define": [ "no-use-before-define": [
"error", "error",
{ {
"functions": false, "functions": false
"classes ": false
} }
], ],
"new-cap": [ "new-cap": [
@ -180,7 +179,7 @@
"array-bracket-spacing": ["error", "never"], // 数组紧贴括号部分不允许包含空格 "array-bracket-spacing": ["error", "never"], // 数组紧贴括号部分不允许包含空格
"object-curly-spacing": ["error", "always"], // 对象紧贴花括号部分不允许包含空格 "object-curly-spacing": ["error", "always"], // 对象紧贴花括号部分不允许包含空格
"no-regex-spaces": "error", // 禁止正则表达式字面量中出现多个空格 "no-regex-spaces": "error", // 禁止正则表达式字面量中出现多个空格
// "no-multi-spaces": "error", // 禁止出现多个空格而且不是用来作缩进的 "no-multi-spaces": "error", // 禁止出现多个空格而且不是用来作缩进的
"block-spacing": ["error", "never"], // 单行代码块中紧贴括号部分不允许包含空格 "block-spacing": ["error", "never"], // 单行代码块中紧贴括号部分不允许包含空格
"computed-property-spacing": ["error", "never"], // 禁止括号和其内部值之间的空格 "computed-property-spacing": ["error", "never"], // 禁止括号和其内部值之间的空格
"no-trailing-spaces": [ "no-trailing-spaces": [

502
README.md

@ -7,7 +7,7 @@
## 开始 ## 开始
安装依赖 安装依赖
``` ```
yarn install yarn
``` ```
开始开发 开始开发
@ -15,107 +15,8 @@ yarn install
yarn dev yarn dev
``` ```
## 决策平台开发:
### A.项目运行
#### 1. 工程`decision-webui-dev`添加代理(可跳过)
```js
webpack/webpack.config
"/plugin/dcm": {
pathRewrite: { "^/plugin/dcm": "" },
target: "http://localhost:10002",
},
```
#### 2. 工程`decision-webui-dev`引入
fr环境:`templates/bundle.report.html` bi环境:`templates/bundle.bi.html`
```html
// css 文件:
<head>
<link rel="stylesheet" type="text/css" href="/plugin/dcm/show.dev.css" />
<link rel="stylesheet" type="text/css" href="http://localhost:10002/show.dev.css" />
</head>
// js 文件
<script type="text/javascript" src="/plugin/dcm/show.dev.js"></script>
```
若未设1,将`/plugin/dcm`替换成`http://localhost:10002`亦可
#### 3. 启动工程[decision-webui-dev]以及数据连接[desicion-webui-dcm]工程
#### 4. 此时工程`decision-webui-dev`的`http://localhost:9002/#management/connnection`数据连接模块已替换成该工程
### B.插件形式添加数据连接-数据库
#### 1. 以多版本的tdsql为例 单一版本数据库不需drivers,versions,hasSchemas
```js
BI.config("dec.connection.provider.datebase", function (provider) {
BI.isFunction(provider.registerJdbcDatabase) && provider.registerJdbcDatabase({
text: 'TDSQL', // 数据库名称
databaseType: 'tdsql', // 数据库key
driver: 'org.postgresql.Driver', // 默认驱动
drivers: {
"pgsql": ["org.postgresql.Driver"],
"mysql": ["com.mysql.jdbc.Driver"]
}, // 驱动可选项,version: array[driver],[0]为该版本的默认驱动
versions: ["pgsql", "mysql"], // array[version]
urls: {
"org.postgresql.Driver": "jdbc:postgresql://hostname:port/database?finedbType=tdsql-pgsql",
"com.mysql.jdbc.Driver": "jdbc:mysql://hostname:port/database?finedbType=tdsql-mysql"
}, // urlkey : url 一个驱动对应一个url
url: 'jdbc:postgresql://hostname:port/database?finedbType=tdsql-pgsql',
commonly: false,
internal: true,
type: 'jdbc', 数据库类型
hasSchema: true, // 默认是否支持模式
hasSchemas: {
"pgsql": true,
"mysql": false,
},是否支持模式 version: boolean
kerberos: false, // 是否添加kerberos认证方式
}, function (url) {
var result = url.match(/^jdbc:(mysql|postgresql):\/\/([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?\/([0-9a-zA-Z_\\.]+)(.*)finedbType=([^&]+)(|(&.*))/i); // 匹配正则
if (result) {
return {
host: result[2], //主机
port: result[4] === "port" ? "" : result[4], // 端口
databaseName: result[5], // 数据库名称
version: result[7].split('-')[1] ?? "pgsql", // 版本 单版本不要返回这个
};
}
//适配原先tbase的url
result = url.match(/^jdbc:postgresql:\/\/([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?\/([0-9a-zA-Z_\\.]+)(.*)/i);
if (result) {
return {
host: result[1],
port: result[3] === "port" ? "" : result[3],
databaseName: result[4],
version: "pgsql",
};
}
});
});
```
### C 工程开发
#### 1. 图片资源添加
工程`decision-webui-dev`
decision-webui/dist/images/1x/icon/database
decision-webui/dist/images/2x/icon/database
#### 2. 国际化添加
工程`decision-webui-dev`
decision-i18n/decision-main-i18n/src/main/resources/com/fr/decision/web/i18n
#### 3. 版本控制
版本和平台保持一致
## 接口文档: ## 接口文档:
### A 增加数据连接类型 ### 增加数据连接类型
#### 1. 增加数据连接类型
使用`BI.config`,ConstantName名称为`dec.constant.database.conf.connect.types`,值为连接的名称 使用`BI.config`,ConstantName名称为`dec.constant.database.conf.connect.types`,值为连接的名称
例如增加`Redis`的连接: 例如增加`Redis`的连接:
@ -124,241 +25,196 @@ BI.config("dec.connection.provider.datebase", function (provider) {
BI.config(ConstantPluginTyps, (datas: string[]) => [...datas, { BI.config(ConstantPluginTyps, (datas: string[]) => [...datas, {
text: 'Redis', text: 'Redis',
databaseType: 'Redis', databaseType: 'Redis',
edit: '',
show: '',
}]); }]);
``` ```
#### 2. 数据连接填写页面 ### 数据连接填写页面
edit属性值为填写组件shortcut的名称 ConstantName名称为`dec.constant.database.conf.connect.form.${name}.edit`,值为组件shortcut的名称
#### 3. 数据连接展示页面 ### 数据连接展示页面
show属性值为组件shortcut的名称 ConstantName名称为`dec.constant.database.conf.connect.form.${name}.show`,值为组件shortcut的名称
#### 4. 示例 ### 示例
```js ```
const DataBaseConfigProvider = 'dec.connection.provider.datebase'; const ConstantRedisType = 'dec.constant.database.conf.connect.types';
const ConstantRedisShow = 'dec.constant.database.conf.connect.form.Redis.show';
const RedisShowName = 'dec.dcm.connection.plugin.redis.show'; const ConstantRedisEdit = 'dec.constant.database.conf.connect.form.Redis.edit';
const RedisEditName = 'dec.dcm.connection.plugin.redis.edit';
BI.config(DataBaseConfigProvider, function (provider) { BI.DOM.ready(() => {
provider.registerDatabaseType([{ BI.config(ConstantRedisType, datas => [...datas, {
text: "Redis", text: 'Redis',
databaseType: "Redis", databaseType: 'Redis',
edit: "dec.dcm.connection.plugin.demo.edit",
show: "dec.dcm.connection.plugin.demo.show",
}]); }]);
});
const RedisShow = BI.inherit(BI.Widget, { const RedisShowName = 'dec.dcm.connection.plugin.redis.show';
props: { const RedisShow = BI.inherit(BI.Widget, {
formData: { props: {
url: '', formData: {
port: '6379', url: '',
password: '', port: '6379',
password: '',
},
}, },
}, render() {
render() { const o = this.options;
const o = this.options;
return {
return { type: 'bi.vertical',
type: 'bi.vertical', hgap: 15,
hgap: 15, vgap: 10,
vgap: 10, items: [
items: [ {
{ type: 'bi.left',
type: 'bi.left', items: [
items: [ {
{ type: 'bi.label',
type: 'bi.label', cls: 'bi-font-bold',
cls: 'bi-font-bold', width: 100,
width: 100, textAlign: 'left',
textAlign: 'left', text: '数据库地址',
text: '数据库地址', },
}, {
{ type: 'bi.label',
type: 'bi.label', text: o.formData.url,
text: o.formData.url, },
}, ],
], },
}, {
{ type: 'bi.left',
type: 'bi.left', items: [
items: [ {
{ type: 'bi.label',
type: 'bi.label', cls: 'bi-font-bold',
cls: 'bi-font-bold', width: 100,
width: 100, textAlign: 'left',
textAlign: 'left', text: '端口号',
text: '端口号', },
}, {
{ type: 'bi.label',
type: 'bi.label', text: o.formData.port,
text: o.formData.port, },
}, ],
], },
}, {
{ type: 'bi.left',
type: 'bi.left', items: [
items: [ {
{ type: 'bi.label',
type: 'bi.label', cls: 'bi-font-bold',
cls: 'bi-font-bold', width: 100,
width: 100, textAlign: 'left',
textAlign: 'left', text: '密码',
text: '密码', },
}, {
{ type: 'bi.label',
type: 'bi.label', text: o.formData.password,
text: o.formData.password, },
}, ],
], },
}, ],
], };
}, },
}, });
});
BI.shortcut(RedisShowName, RedisShow);
const RedisEdit = BI.inherit(BI.Widget, { BI.shortcut(RedisShowName, RedisShow);
props: { BI.constant(ConstantRedisShow, RedisShowName);
value: {
url: '',
port: '6379', const RedisEditName = 'dec.dcm.connection.plugin.redis.edit';
password: '', const RedisEdit = BI.inherit(BI.Widget, {
props: {
formData: {
url: '',
port: '6379',
password: '',
},
}, },
}, render() {
render() { const o = this.options;
const o = this.options;
return {
return { type: 'bi.vertical',
type: 'bi.vertical', hgap: 15,
hgap: 15, vgap: 10,
vgap: 10, items: [
items: [ {
{ type: 'bi.left',
type: 'bi.left', items: [
items: [ {
{ type: 'bi.label',
type: 'bi.label', cls: 'bi-font-bold',
cls: 'bi-font-bold', width: 100,
width: 100, textAlign: 'left',
textAlign: 'left', text: '数据库地址',
text: '数据库地址', },
}, {
{ type: 'bi.text_editor',
type: 'bi.text_editor', width: 300,
width: 300, allowBlank: true,
allowBlank: true, ref: _ref => {
ref: _ref => { this.url = _ref;
this.url = _ref; },
text: o.formData.url,
}, },
text: o.value.url, ],
}, },
], {
}, type: 'bi.left',
{ items: [
type: 'bi.left', {
items: [ type: 'bi.label',
{ cls: 'bi-font-bold',
type: 'bi.label', width: 100,
cls: 'bi-font-bold', textAlign: 'left',
width: 100, text: '端口号',
textAlign: 'left',
text: '端口号',
},
{
type: 'bi.text_editor',
width: 300,
allowBlank: true,
ref: _ref => {
this.port = _ref;
}, },
text: o.value.port, {
}, type: 'bi.text_editor',
], width: 300,
}, allowBlank: true,
{ ref: _ref => {
type: 'bi.left', this.port = _ref;
items: [ },
{ text: o.formData.port,
type: 'bi.label',
cls: 'bi-font-bold',
width: 100,
textAlign: 'left',
text: '密码',
},
{
type: 'bi.text_editor',
width: 300,
allowBlank: true,
inputType: 'password',
ref: _ref => {
this.password = _ref;
}, },
text: o.value.password, ],
}, },
], {
}, type: 'bi.left',
], items: [
}; {
}, type: 'bi.label',
getValue() { cls: 'bi-font-bold',
return { width: 100,
url: this.url.getValue(), textAlign: 'left',
port: this.port.getValue(), text: '密码',
password: this.password.getValue(), },
}; {
}, type: 'bi.text_editor',
//可以触发组件的数据save方法,不需要则可不写 width: 300,
async save() { allowBlank: true,
let result = false; inputType: 'password',
await Promise.resolve().then(() => {result = true}); ref: _ref => {
//要求返回是否成功的boolean变量 this.password = _ref;
return result; },
}, text: o.formData.password,
},
],
},
],
};
},
getSubmitValue() {
return {
url: this.url.getValue(),
port: this.port.getValue(),
password: this.password.getValue(),
};
},
});
BI.shortcut(RedisEditName, RedisEdit);
BI.constant(ConstantRedisEdit, RedisEditName);
}); });
BI.shortcut(RedisEditName, RedisEdit);
``` ```
### B 添加数据连接实例
#### 1. 增加数据连接
```js
BI.config('dec.constant.connection.list', function (value) {
const result = [{
"connectionType": "Redis",//和databaseType一致
"connectionName": "CHART",//类似于id,唯一性
"pluginConnection": true,//表示是外来添加的插件
"connectionData": {
//表单保存数据
},
"connectionId": null,
}];
return value.concat(result);
})
```
### C 添加数据连接类型分类
#### 1. 添加分类DEMO
```js
BI.config('dec.constant.database.filter.type', (value) => {
value.push({
text:"DEMO",
value:"DEMO_VALUE"
});
return value;
});
```
#### 2. 添加数据连接类型进DEMO
```js
BI.config('dec.connection.provider.datebase', function (provider) {
text: "Redis",//必填
databaseType: "Redis",//唯一值
marker: 'DEMO_VALUE',//marker对标dec.constant.database.filter.type常量item的value,用于过滤
isHideConnection: true, //是否隐藏测试连接按钮
isNoSave: true,//是否不执行平台的保存逻辑
iconUrl:'https://work.fineres.com/secure/projectavatar?pid=10301&avatarId=10011',
driver: 'com.amazon.redshift.jdbc41.Driver',
drivers: ['com.amazon.redshift.jdbc4.Driver', 'com.amazon.redshift.jdbc41.Driver'],
url: 'jdbc:redshift://endpoint:port/database',
}
```

16
assets/scripts/dec.js

@ -6,7 +6,6 @@ window.DecCst = {
LOGIN_INFO_NOT_AVAILABLE: '21300014', LOGIN_INFO_NOT_AVAILABLE: '21300014',
LOGIN_INFO_ERROR: '21300018', LOGIN_INFO_ERROR: '21300018',
TIMEOUT: '21300001', TIMEOUT: '21300001',
LACK_DRIVER: '22400037'
}, },
Connect: { Connect: {
ConnectionType: { ConnectionType: {
@ -17,13 +16,6 @@ window.DecCst = {
OPEN: 'getConnectionStatus', OPEN: 'getConnectionStatus',
SHUTDOWN: 'shutdownConnectionStatus', SHUTDOWN: 'shutdownConnectionStatus',
} }
},
Hyperlink: {
Database: {
ODPS: "odps"
},
DECISION_HYPERLINK_CONFIG: "hyperlink",
WEBSOCKET_CONNECT: "websocket"
} }
}; };
@ -33,12 +25,6 @@ window.Dec = {
connected: false, connected: false,
}, },
personal: { personal: {
username: '', username: ''
},
system: {
hyperlink: {
websocket: "http://help.finebi.com/doc-view-183.html",
odps: "http://help.finebi.com/doc-view-183.html",
},
} }
} }

14
babel.config.js

@ -1,13 +1,3 @@
module.exports = api => { module.exports = function (api) {
const { plugins, presets, sourceType } = require("@fui/babel-preset-fineui").configs.base(api); return require("@fui/babel-preset-fineui").configs.base(api)
return {
compact: false,
presets,
sourceType,
plugins: [
...plugins,
"@babel/plugin-proposal-logical-assignment-operators",
],
};
}; };

2
config/jest.environment.js

@ -11,7 +11,7 @@ class FineUiEnvironment extends JsdomEnvironment {
document.createElement('body'); document.createElement('body');
[ [
'../node_modules/@fui/core/dist/fineui.js', '../node_modules/fineui/dist/fineui.js',
'../node_modules/@fui/materials/docs/materials.js', '../node_modules/@fui/materials/docs/materials.js',
'../config/fineui.prepare.js', '../config/fineui.prepare.js',
'./fineui.setup.js', './fineui.setup.js',

21
i18n/zh_cn.properties

@ -62,11 +62,6 @@ Dec-Dcm_Connection_Form_UserName= 用户名
Dec-Dcm_Connection_Form_Password= 密码 Dec-Dcm_Connection_Form_Password= 密码
Dec-Dcm_Connection_Form_Principal= 客户端principal Dec-Dcm_Connection_Form_Principal= 客户端principal
Dec-Dcm_Connection_Form_KeyPath= keytab密钥路径 Dec-Dcm_Connection_Form_KeyPath= keytab密钥路径
Dec-Dcm_Connection_Form_Krb5File= krb5.conf文件
Dec-Dcm_Connection_File_Upload_Success= 已成功上传并校验成功
Dec-Dcm_Connection_File_Upload_Error= 检测异常
Dec-Dcm_Connection_File_Upload_ErrorCode= 错误代码
Dec-Dcm_Connection_File_Upload_ErrorMsg= 错误详情
Dec-Dcm_Connection_Form_Pool_Properties= 连接池属性 Dec-Dcm_Connection_Form_Pool_Properties= 连接池属性
Dec-Dcm_Connection_Form_SQL_Validation_Query= SQL验证查询 Dec-Dcm_Connection_Form_SQL_Validation_Query= SQL验证查询
Dec-Dcm_Connection_Form_Connection-Check= 获取连接前校验 Dec-Dcm_Connection_Form_Connection-Check= 获取连接前校验
@ -85,10 +80,10 @@ Dec-Dcm_Connection_Form_Database_Max_Wait= 最大等待时间
Dec-Dcm_Connection_Form_Database_Validation_Query= SQL验证查询 Dec-Dcm_Connection_Form_Database_Validation_Query= SQL验证查询
Dec-Dcm_Connection_Form_Database_Test_On_Borrow= 获取连接前检验 Dec-Dcm_Connection_Form_Database_Test_On_Borrow= 获取连接前检验
Dec-Dcm_Connection_Form_Database_Test_On_Return= 归还连接前检验 Dec-Dcm_Connection_Form_Database_Test_On_Return= 归还连接前检验
Dec-Dcm_Connection_Form_Database_Test_While_Idle= 获取连接时空闲连接可用性校 Dec-Dcm_Connection_Form_Database_Test_While_Idle= 开启空闲回收器检
Dec-Dcm_Connection_Form_Database_Test_Between_Eviction_Millis= 空闲连接回收器工作间隔 Dec-Dcm_Connection_Form_Database_Test_Between_Eviction_Millis= 空闲连接回收器休眠时间
Dec-Dcm_Connection_Form_Database_Tests_PerEviction_Run_Num= 空闲连接回收检查数 Dec-Dcm_Connection_Form_Database_Tests_PerEviction_Run_Num= 空闲连接回收检查数
Dec-Dcm_Connection_Form_Database_Min_Evictable_Idle_Time_Millis= 空闲连接回收时间阈 Dec-Dcm_Connection_Form_Database_Min_Evictable_Idle_Time_Millis= 保持空闲最小时间
Dec-Dcm_Connection_Make_Sure_Delete= 确定删除该数据连接? Dec-Dcm_Connection_Make_Sure_Delete= 确定删除该数据连接?
Dec-Dcm_Connection_ReConnect= 重新连接 Dec-Dcm_Connection_ReConnect= 重新连接
Dec-Dcm_Connection_JNDI_Form_ConnectionName= JNDI的名字 Dec-Dcm_Connection_JNDI_Form_ConnectionName= JNDI的名字
@ -101,7 +96,7 @@ Dec-Dcm_Connection_JNDI= JNDI数据连接
Dec-Dcm_Connection_JNDI_Warning= 注意:需要把包含INTIAL_CONTEXT_FACTORY类的.jar文件复制到软件安装目录下的/lib目录下 Dec-Dcm_Connection_JNDI_Warning= 注意:需要把包含INTIAL_CONTEXT_FACTORY类的.jar文件复制到软件安装目录下的/lib目录下
Dec-Dcm_Connection_Error= 接口访问错误 Dec-Dcm_Connection_Error= 接口访问错误
Dec-Dcm_Connection_Is_Using= 该连接正在被{R1}编辑,请稍后再试 Dec-Dcm_Connection_Is_Using= 该连接正在被{R1}编辑,请稍后再试
Dec-Dcm_Connection_Check_Integer= 请输入不小于{}的整数 Dec-Dcm_Connection_Check_Integer= 请输入不小于0的整数
Dec-Dcm_Connection_Check_Number= 只允许为整数 Dec-Dcm_Connection_Check_Number= 只允许为整数
Dec-Dcm_Connection_JDBC_Other=其他JDBC Dec-Dcm_Connection_JDBC_Other=其他JDBC
Dec-Dcm_Connection_JDBC_Warning= 请确认已经将krb5.Conf文件添加到/webapps/webroot/WEB_INF/resources目录 Dec-Dcm_Connection_JDBC_Warning= 请确认已经将krb5.Conf文件添加到/webapps/webroot/WEB_INF/resources目录
@ -307,10 +302,4 @@ BI-Basic_Quarter= 季度
BI-Basic_No_Select= 不选 BI-Basic_No_Select= 不选
BI-Basic_Now= 此刻 BI-Basic_Now= 此刻
Dec-Dcm_Connection_Analytic_DB=阿里云AnalyticDB Dec-Dcm_Connection_Analytic_DB=阿里云AnalyticDB
Dec-Dcm_Connection_Value_Out_Range=数值超出范围 Dec-Dcm_Connection_Value_Out_Range=数值超出范围
Dec-Dcm_Socket_Unable_Connect_Tip=可能出现编辑冲突
Dec-Dcm_Connection_File_Upload_ErrorTip1= 参考
Dec-Dcm_Connection_File_Upload_ErrorTip2= kerberos配置
Dec-Dcm_Connection_File_Upload_ErrorTip3= 获取帮助或联系技术支持
Dec-Dcm_Connection_Timeout_Detection=数据连接超时检测
Dec-Dcm_Connection_Timeout_Millisecond=毫秒(ms)

8
index.html

@ -5,15 +5,15 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>Fine Report</title> <title>Fine Report</title>
<!--核心css文件--> <!--核心css文件-->
<link rel="preload" href="./node_modules/@fui/core/dist/font/iconfont.woff" as="font" type="font/woff" crossorigin="" /> <link rel="preload" href="./node_modules/fineui/dist/font/iconfont.woff" as="font" type="font/woff" crossorigin="" />
<link rel="stylesheet" type="text/css" href="./node_modules/@fui/core/dist/fineui.css" /> <link rel="stylesheet" type="text/css" href="./node_modules/fineui/dist/fineui.css" />
<link rel="stylesheet" type="text/css" href="./node_modules/@fui/materials/docs/materials.css" /> <link rel="stylesheet" type="text/css" href="./node_modules/@fui/materials/docs/materials.css" />
</head> </head>
<body id="body"> <body id="body">
<div id="wrapper"></div> <div id="wrapper"></div>
<script src="./node_modules/@fui/core/dist/fineui.js"></script> <script src="./node_modules/fineui/dist/fineui.js"></script>
<script src="./node_modules/@fui/core/dist/utils.js"></script> <script src="./node_modules/fineui/dist/utils.js"></script>
<script src="./node_modules/@fui/materials/docs/materials.js"></script> <script src="./node_modules/@fui/materials/docs/materials.js"></script>
<script src="./assets/scripts/dec.js"></script> <script src="./assets/scripts/dec.js"></script>
<script src="./redis.js"></script> <script src="./redis.js"></script>

24
package.json

@ -7,7 +7,6 @@
"author": "decision", "author": "decision",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/plugin-proposal-logical-assignment-operators": "^7.20.7",
"@types/jss": "9.5.8", "@types/jss": "9.5.8",
"autoprefixer": "^9.6.1", "autoprefixer": "^9.6.1",
"es6-promise": "4.2.6", "es6-promise": "4.2.6",
@ -17,11 +16,10 @@
"nprogress": "0.2.0" "nprogress": "0.2.0"
}, },
"devDependencies": { "devDependencies": {
"@fui/babel-preset-fineui": "^1.0.0",
"@types/jest": "24.0.11", "@types/jest": "24.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/eslint-plugin": "1.7.0",
"@typescript-eslint/parser": "^5.0.0", "@typescript-eslint/parser": "1.7.0",
"axios": "^0.24.0", "axios": "0.18.0",
"babel-loader": "8.0.6", "babel-loader": "8.0.6",
"body-parser": "1.18.3", "body-parser": "1.18.3",
"chokidar": "2.1.5", "chokidar": "2.1.5",
@ -30,7 +28,6 @@
"eslint": "5.16.0", "eslint": "5.16.0",
"eslint-plugin-jest": "22.4.1", "eslint-plugin-jest": "22.4.1",
"express": "4.16.4", "express": "4.16.4",
"fork-ts-checker-webpack-plugin": "1.4.3",
"html-webpack-plugin": "3.2.0", "html-webpack-plugin": "3.2.0",
"http-proxy": "1.17.0", "http-proxy": "1.17.0",
"husky": "1.3.1", "husky": "1.3.1",
@ -49,14 +46,16 @@
"source-map-loader": "0.2.4", "source-map-loader": "0.2.4",
"style-loader": "0.23.1", "style-loader": "0.23.1",
"ts-jest": "24.0.2", "ts-jest": "24.0.2",
"typescript": "^4.3.5", "typescript": "3.5.1",
"webpack": "4.35.2", "webpack": "4.35.2",
"webpack-cli": "3.3.5", "webpack-cli": "3.3.5",
"webpack-dev-server": "3.7.2", "webpack-dev-server": "3.7.2",
"webpack-merge": "4.2.1" "webpack-merge": "4.2.1",
"@fui/babel-preset-fineui": "^1.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@fui/core": "^2.0.20210721103227" "fineui": "^2.0.0",
"@fui/materials": "10.0.0-release - 10.0.0-release.99999999999999"
}, },
"scripts": { "scripts": {
"dev": "cross-env NODE_ENV=mock webpack-dev-server -p --progress --config=webpack/webpack.dev.js --mode development --open", "dev": "cross-env NODE_ENV=mock webpack-dev-server -p --progress --config=webpack/webpack.dev.js --mode development --open",
@ -67,5 +66,10 @@
"i18n": "node ./lib/transform-i18n/transform-i18n.js", "i18n": "node ./lib/transform-i18n/transform-i18n.js",
"test": "jest --passWithNoTests", "test": "jest --passWithNoTests",
"upgrade": "node lib/upgrade" "upgrade": "node lib/upgrade"
},
"husky": {
"hooks": {
"pre-push": "npm run eslint && npm run test"
}
} }
} }

22
private/i18n.ts

@ -54,18 +54,13 @@ export default {
'Dec-Dcm_Connection_Form_Database_URL': '数据连接URL', 'Dec-Dcm_Connection_Form_Database_URL': '数据连接URL',
'Dec-Dcm_Connection_Form_Place_Input': '请输入', 'Dec-Dcm_Connection_Form_Place_Input': '请输入',
'Dec-Dcm_Connection_Form_OriginalCharsetName': '编码', 'Dec-Dcm_Connection_Form_OriginalCharsetName': '编码',
'Dec-Dcm_Connection_Form_Default': '默认', 'Dec-Dcm_Connection_Form_Auto': '自动',
'Dec-Dcm_Connection_Form_Host': '主机', 'Dec-Dcm_Connection_Form_Host': '主机',
'Dec-Dcm_Connection_Form_AuthType': '认证方式', 'Dec-Dcm_Connection_Form_AuthType': '认证方式',
'Dec-Dcm_Connection_Form_UserName': '用户名', 'Dec-Dcm_Connection_Form_UserName': '用户名',
'Dec-Dcm_Connection_Form_Password': '密码', 'Dec-Dcm_Connection_Form_Password': '密码',
'Dec-Dcm_Connection_Form_Principal': '客户端principal', 'Dec-Dcm_Connection_Form_Principal': '客户端principal',
'Dec-Dcm_Connection_Form_KeyPath': 'keytab密钥路径', 'Dec-Dcm_Connection_Form_KeyPath': 'keytab密钥路径',
'Dec-Dcm_Connection_Form_Krb5File': 'krb5.conf文件',
'Dec-Dcm_Connection_File_Upload_Success': ' 已成功上传并校验成功',
'Dec-Dcm_Connection_File_Upload_Error': '检测异常',
'Dec-Dcm_Connection_File_Upload_ErrorCode': '错误代码',
'Dec-Dcm_Connection_File_Upload_ErrorMsg': '错误详情',
'Dec-Dcm_Connection_Form_Pool_Properties': '连接池属性', 'Dec-Dcm_Connection_Form_Pool_Properties': '连接池属性',
'Dec-Dcm_Connection_Form_SQL_Validation_Query': 'SQL验证查询', 'Dec-Dcm_Connection_Form_SQL_Validation_Query': 'SQL验证查询',
'Dec-Dcm_Connection_Form_Connection-Check': '获取连接前校验', 'Dec-Dcm_Connection_Form_Connection-Check': '获取连接前校验',
@ -84,10 +79,10 @@ export default {
'Dec-Dcm_Connection_Form_Database_Validation_Query': 'SQL验证查询', 'Dec-Dcm_Connection_Form_Database_Validation_Query': 'SQL验证查询',
'Dec-Dcm_Connection_Form_Database_Test_On_Borrow': '获取连接前检验', 'Dec-Dcm_Connection_Form_Database_Test_On_Borrow': '获取连接前检验',
'Dec-Dcm_Connection_Form_Database_Test_On_Return': '归还连接前检验', 'Dec-Dcm_Connection_Form_Database_Test_On_Return': '归还连接前检验',
'Dec-Dcm_Connection_Form_Database_Test_While_Idle': '获取连接时空闲连接可用性校验', 'Dec-Dcm_Connection_Form_Database_Test_While_Idle': '开启空闲回收器检验',
'Dec-Dcm_Connection_Form_Database_Test_Between_Eviction_Millis': '空闲连接回收器工作间隔', 'Dec-Dcm_Connection_Form_Database_Test_Between_Eviction_Millis': '空闲连接回收器休眠时间',
'Dec-Dcm_Connection_Form_Database_Tests_PerEviction_Run_Num': '空闲连接回收检查数', 'Dec-Dcm_Connection_Form_Database_Tests_PerEviction_Run_Num': '空闲连接回收检查数',
'Dec-Dcm_Connection_Form_Database_Min_Evictable_Idle_Time_Millis': '空闲连接回收时间阈值', 'Dec-Dcm_Connection_Form_Database_Min_Evictable_Idle_Time_Millis': '保持空闲最小时间值',
'Dec-Dcm_Connection_Make_Sure_Delete': '确定删除该数据连接?', 'Dec-Dcm_Connection_Make_Sure_Delete': '确定删除该数据连接?',
'Dec-Dcm_Connection_ReConnect': '重新连接', 'Dec-Dcm_Connection_ReConnect': '重新连接',
'Dec-Dcm_Connection_JNDI_Form_ConnectionName': 'JNDI的名字', 'Dec-Dcm_Connection_JNDI_Form_ConnectionName': 'JNDI的名字',
@ -100,7 +95,7 @@ export default {
'Dec-Dcm_Connection_JNDI_Warning': '注意:需要把包含INTIAL_CONTEXT_FACTORY类的.jar文件复制到软件安装目录下的/lib目录下', 'Dec-Dcm_Connection_JNDI_Warning': '注意:需要把包含INTIAL_CONTEXT_FACTORY类的.jar文件复制到软件安装目录下的/lib目录下',
'Dec-Dcm_Connection_Error': '接口访问错误', 'Dec-Dcm_Connection_Error': '接口访问错误',
'Dec-Dcm_Connection_Is_Using': '该连接正在被{R1}编辑,请稍后再试', 'Dec-Dcm_Connection_Is_Using': '该连接正在被{R1}编辑,请稍后再试',
'Dec-Dcm_Connection_Check_Integer': '请输入不小于{}的整数', 'Dec-Dcm_Connection_Check_Integer': '请输入不小于0的整数',
'Dec-Dcm_Connection_Check_Number': '只允许为整数', 'Dec-Dcm_Connection_Check_Number': '只允许为整数',
'Dec-Dcm_Connection_JDBC_Other': '其他JDBC', 'Dec-Dcm_Connection_JDBC_Other': '其他JDBC',
'Dec-Dcm_Connection_JDBC_Warning': '请确认已经将krb5.Conf文件添加到/webapps/webroot/WEB_INF/resources目录', 'Dec-Dcm_Connection_JDBC_Warning': '请确认已经将krb5.Conf文件添加到/webapps/webroot/WEB_INF/resources目录',
@ -307,11 +302,4 @@ export default {
'BI-Basic_Now': '此刻', 'BI-Basic_Now': '此刻',
'Dec-Dcm_Connection_Analytic_DB': '阿里云AnalyticDB', 'Dec-Dcm_Connection_Analytic_DB': '阿里云AnalyticDB',
'Dec-Dcm_Connection_Value_Out_Range': '数值超出范围', 'Dec-Dcm_Connection_Value_Out_Range': '数值超出范围',
'Dec-Dcm_Socket_Unable_Connect_Tip': '可能出现编辑冲突',
'Dec-Connection_Lic_Limit_Approach_Tip': '当前数据连接数量超过注册lic限制({}个),所有数据连接都不可用,请删除多余的数据连接',
'Dec-Connection_Lic_Limit_Approach_Prevent_Tip': '当前数据连接数量已经达到注册lic限制({}个),无法新增',
'Dec-Dcm_Connection_Check_Fetch_Size_Range': '请输入0-1000000之间的值',
'Dec-Dcm_Connection_File_Upload_ErrorTip1':'参考',
'Dec-Dcm_Connection_File_Upload_ErrorTip2': 'kerberos配置',
'Dec-Dcm_Connection_File_Upload_ErrorTip3': '取帮助或联系技术支持',
}; };

4
src/index.ts

@ -1,5 +1,5 @@
import { App } from './modules/app'; import { AppXtype } from './modules/app';
BI.createWidget({ BI.createWidget({
type: App.xtype, type: AppXtype,
element: '#wrapper', element: '#wrapper',
}); });

2
src/less/background.less

@ -1,4 +1,4 @@
@import "../../node_modules/@fui/core/src/less/image.less"; @import "../../node_modules/fineui/src/less/image.less";
@import "./lib/background.less"; @import "./lib/background.less";
@import "var"; @import "var";

2
src/less/font.less

@ -1,4 +1,4 @@
@import "../../node_modules/@fui/core/src/less/image.less"; @import "../../node_modules/fineui/src/less/image.less";
@import "./lib/font.less"; @import "./lib/font.less";
.addFontRes(); .addFontRes();
.font(dcm-link-font, @font-link); .font(dcm-link-font, @font-link);

4
src/less/index.less

@ -1,5 +1,5 @@
@import "../../node_modules/@fui/core/src/less/lib/colors.less"; @import "../../node_modules/fineui/src/less/lib/colors.less";
@import '../../node_modules/@fui/core/src/less/visual.less'; @import '../../node_modules/fineui/src/less/visual.less';
@import "background.less"; @import "background.less";
@import "font.less"; @import "font.less";
@import "var.less"; @import "var.less";

2
src/less/lib/font.less

@ -1,4 +1,4 @@
@import '../../../node_modules/@fui/core/src/less/lib/font.less'; @import '../../../node_modules/fineui/src/less/lib/font.less';
@font-link: "e759"; @font-link: "e759";
@font-link-test: "e763"; @font-link-test: "e763";

3
src/modules/__test__/app.test.ts

@ -1,6 +1,4 @@
import { connectionCanEdit, resolveUrlInfo, splitUrl, getJdbcDatabaseType } from '../app.service'; import { connectionCanEdit, resolveUrlInfo, splitUrl, getJdbcDatabaseType } from '../app.service';
import '../app.provider';
const connection = { const connection = {
connectionId: '', connectionId: '',
connectionType: '', connectionType: '',
@ -19,7 +17,6 @@ test('DEC-11030 拼接url', () => {
*/ */
test('BI-56355 如果数据库类型和驱动都为空,则为其他jdbc', () => { test('BI-56355 如果数据库类型和驱动都为空,则为其他jdbc', () => {
expect(getJdbcDatabaseType('', '').databaseType).toEqual('otherJDBC'); expect(getJdbcDatabaseType('', '').databaseType).toEqual('otherJDBC');
expect(getJdbcDatabaseType('otherJDBC', 'org.h2.Driver').databaseType).toEqual('otherJDBC');
expect(getJdbcDatabaseType('mysql', '').databaseType).toEqual('mysql'); expect(getJdbcDatabaseType('mysql', '').databaseType).toEqual('mysql');
expect(getJdbcDatabaseType('', 'com.mysql.jdbc.Driver').databaseType).toEqual('mysql'); expect(getJdbcDatabaseType('', 'com.mysql.jdbc.Driver').databaseType).toEqual('mysql');
}); });

18
src/modules/app.model.ts

@ -2,12 +2,11 @@ import { PAGE_INDEX, DATEBASE_FILTER_TYPE } from './constants/constant';
import { Model, model } from '@core/core'; import { Model, model } from '@core/core';
import { Connection } from 'src/modules/crud/crud.typings'; import { Connection } from 'src/modules/crud/crud.typings';
import { getAllDatabaseTypes } from './app.service'; import { getAllDatabaseTypes } from './app.service';
export const AppModelXtype = 'dec.dcm.model.main';
@model() @model(AppModelXtype)
export class AppModel extends Model { export class AppModel extends Model {
static xtype = 'dec.dcm.model.main'; childContext = ['pageIndex', 'datebaseTypeSelected', 'datebaseTypeSelectedOne', 'filter', 'connections', 'connectionSelected', 'connectionSelectedOne', 'saveEvent', 'testEvent', 'isCopy'];
childContext = <const>['pageIndex', 'datebaseTypeSelected', 'datebaseTypeSelectedOne', 'filter', 'connections', 'connectionSelected', 'connectionSelectedOne', 'saveEvent', 'testEvent', 'isCopy', 'connectionLicInfo', 'noTestConnection'];
state() { state() {
return { return {
@ -19,28 +18,23 @@ export class AppModel extends Model {
saveEvent: '', saveEvent: '',
testEvent: '', testEvent: '',
isCopy: false, isCopy: false,
connectionLicInfo: {
currentConnectionNum: 0,
maxConnectionNum: 0,
},
noTestConnection: false,
}; };
} }
computed = { computed = {
connectionSelectedOne: () => this.model.connections.find(item => item.connectionName === this.model.connectionSelected), connectionSelectedOne: () => this.model.connections.find(item => item.connectionName === this.model.connectionSelected),
datebaseTypeSelectedOne: () => getAllDatabaseTypes().find(item => item.databaseType === this.model.datebaseTypeSelected), datebaseTypeSelectedOne: () => getAllDatabaseTypes().find(item => item.databaseType === this.model.datebaseTypeSelected),
}; }
actions = { actions = {
setPageIndex: (index: string) => { setPageIndex: (index: string) => {
this.model.pageIndex = index; this.model.pageIndex = index;
}, },
setFilter: (filter: string) => { setFilter:(filter: string) => {
this.model.filter = filter; this.model.filter = filter;
}, },
setDatebaseTypeSelected: (datebaseTypeSelected: string) => { setDatebaseTypeSelected: (datebaseTypeSelected: string) => {
this.model.datebaseTypeSelected = datebaseTypeSelected; this.model.datebaseTypeSelected = datebaseTypeSelected;
}, },
}; }
} }

170
src/modules/app.provider.ts

@ -1,177 +1,9 @@
import { CONSTANT_PLUGIN_TYPES } from './app.constant'; import { CONSTANT_PLUGIN_TYPES } from './app.constant';
import { DATA_BASE_TYPES } from '@constants/constant';
BI.provider('dec.connection.provider.datebase', function () {
this.resolves = {};
function starRocksResolve(url: string) {
// 处理starRocks数据连接常规模式
let result = url.match(/^jdbc:mysql:\/\/([0-9a-zA-Z_\\.-]+):([0-9a-zA-Z_\\.-]+)\/([0-9a-zA-Z_\\.-]+)\.([^]+)(.*)/i);
if (result) {
return {
host: result[1],
port: result[2] === 'port' ? '' : result[2],
catalog: result[3],
databaseName: result[4],
urlInfo: result[0],
};
} else {
// 兼容老数据库里面没有catalog的情况
result = url.match(/^jdbc:mysql:\/\/([0-9a-zA-Z_\\.-]+):([0-9a-zA-Z_\\.-]+)\/([^]+)(.*)/i);
if (result) {
return {
host: result[1],
port: result[2] === 'port' ? '' : result[2],
catalog: '',
databaseName: result[3],
urlInfo: result[0],
};
}
}
// 处理starRocks数据连接负载均衡模式
let loadBalance = url.match(/^jdbc:mysql:loadbalance:\/\/[^/]+\/([^/]+)\.([^/]+)/i);
if (loadBalance) {
return {
host: '',
port: '',
catalog: loadBalance[1],
databaseName: loadBalance[2],
urlInfo: loadBalance[0],
}
} else {
// 兼容老数据库里面没有catalog的情况
loadBalance = url.match(/^jdbc:mysql:loadbalance:\/\/[^/]+\/([^/]+)([^/]+)/i);
if (loadBalance) {
return {
host: '',
port: '',
catalog: '',
databaseName: loadBalance[1],
urlInfo: loadBalance[0],
}
}
}
return {
host: '',
port: '',
databaseName: '',
urlInfo: '',
};
}
// 原service中resolveUrlInfo方法
function jdbcResolve(url: string) {
if (BI.isNull(url)) return {};
const oracleUlr = url.match(/^jdbc:(oracle):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(:|\/)([^]+)(.*)/i);
if (oracleUlr) {
return {
host: oracleUlr[5],
port: oracleUlr[7] === 'port' ? '' : oracleUlr[7],
databaseName: oracleUlr[9],
urlInfo: oracleUlr[10],
};
}
const greenplumUrl = url.match(/^jdbc:(pivotal:greenplum):(thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(\/|;DatabaseName=)?([^]+)(.*)/i);
if (greenplumUrl) {
return {
host: greenplumUrl[4],
port: greenplumUrl[6] === 'port' ? '' : greenplumUrl[6],
databaseName: greenplumUrl[8],
urlInfo: greenplumUrl[9],
};
}
const result = url.match(/^jdbc:(mysql|sqlserver|db2|dm|impala|kylin|phoenix|derby|gbase|gbasedbt-sqli|informix-sqli|h2|postgresql|hive2|vertica|kingbase|presto|redshift|postgresql|clickhouse|trino|sybase:Tds):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(\/|;DatabaseName=)?([^]+)?(.*)/i);
if (result) {
return {
host: result[5],
port: result[7] === 'port' ? '' : result[7],
databaseName: result[9] || '',
urlInfo: result[10],
};
}
// 处理SAP HANA数据连接url
const sapHanaUrl = url.match(/^jdbc:(sap):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(\?databaseName=)?([^&]+)([^]+)?(.*)/i);
if (sapHanaUrl) {
return {
host: sapHanaUrl[5],
port: sapHanaUrl[7] === 'port' ? '' : sapHanaUrl[7],
databaseName: sapHanaUrl[9] || '',
urlInfo: sapHanaUrl[10],
};
}
// 处理oracle的RAC方式
if (/^jdbc:oracle:thin:([0-9a-zA-Z/]*)?@\(DESCRIPTION/i.test(url)) {
const host = url.match(/\(HOST\s*=\s*([0-9a-zA-Z_\\.-]+)\)/i);
const port = url.match(/\(PORT\s*=\s*([0-9]+)\)/i);
const databaseName = url.match(/\(SERVICE_NAME\s*=\s*([\s0-9a-zA-Z_\\.]+)\)/i);
return {
host: host ? host[1] : '',
port: port && port[1] !== 'port' ? port[1] : '',
databaseName: databaseName ? databaseName[1] : '',
urlInfo: '',
};
}
return {
host: '',
port: '',
databaseName: '',
urlInfo: '',
};
}
function coverBaseDatabase(config) {
const baseDataBase = DATA_BASE_TYPES.find(item => item.text === config.text);
if (BI.isNotNull(baseDataBase)) {
// 覆盖基础配置
Object.assign(baseDataBase, config);
return true;
}
return false;
}
function filterPluginDataTypeByPriority() {
const originTypes = [...BI.Constants.getConstant(CONSTANT_PLUGIN_TYPES)];
const sortDataTypes = BI.sortBy(originTypes, (index, value: any) => {
return value.priority || 0;
})
return BI.uniqWith(sortDataTypes, (current, other) => {
return current.text == other.text;
});
}
BI.provider('dec.connection.provider.datebase', function() {
this.registerDatabaseType = (config: any) => { this.registerDatabaseType = (config: any) => {
if (coverBaseDatabase(config)) return;
BI.config(CONSTANT_PLUGIN_TYPES, connections => BI.concat(connections, config)); BI.config(CONSTANT_PLUGIN_TYPES, connections => BI.concat(connections, config));
}; };
this.registerJdbcDatabase = (config: any, resolve?: Function) => {
config = {
...config,
type: 'jdbc',
};
BI.isFunction(resolve) && (this.resolves[config.databaseType] = resolve);
if (coverBaseDatabase(config)) return;
BI.config(CONSTANT_PLUGIN_TYPES, connections => BI.concat(connections, config));
};
this.$get = () => BI.inherit(BI.OB, { this.$get = () => BI.inherit(BI.OB, {
getJdbcResolveByType: (type: string) => {
// starRocks特殊处理
// todo: 后面有专门的迭代系统处理,这里先临时解决下bug
if (type === "starrocks"){
return starRocksResolve
}
return this.resolves[type] || jdbcResolve
},
customDatabaseType: BI.Constants.getConstant(CONSTANT_PLUGIN_TYPES),
}); });
}); });

112
src/modules/app.service.ts

@ -1,16 +1,11 @@
import { import { DATA_BASE_TYPES, DATA_BASE_TYPES_OTHER, DESIGN_DRIVER_TYPE } from '@constants/constant';
DATA_BASE_TYPES, import { CONSTANT_PLUGIN_TYPES } from './app.constant';
DATA_BASE_TYPES_OTHER,
DESIGN_DRIVER_TYPE,
OTHER_JDBC,
DATABASE_TYPE,
} from '@constants/constant';
import { DatabaseType } from './app.typings'; import { DatabaseType } from './app.typings';
import { Connection } from './crud/crud.typings'; import { Connection } from './crud/crud.typings';
export function getAllDatabaseTypes(): DatabaseType[] { export function getAllDatabaseTypes():DatabaseType[] {
return [ return [
...DATA_BASE_TYPES, ...DATA_BASE_TYPES,
...BI.Providers.getProvider('dec.connection.provider.datebase').customDatabaseType.map(item => { ...BI.Constants.getConstant(CONSTANT_PLUGIN_TYPES).map(item => {
return { return {
...item, ...item,
internal: false, internal: false,
@ -20,7 +15,7 @@ export function getAllDatabaseTypes(): DatabaseType[] {
]; ];
} }
function getPlugin(type: string) { function getPlugin(type: string) {
return BI.Providers.getProvider('dec.connection.provider.datebase').customDatabaseType.find(item => item.databaseType === type); return BI.Constants.getConstant(CONSTANT_PLUGIN_TYPES).find(item => item.databaseType === type);
} }
export function getPluginWidgetShow(plugin: string) { export function getPluginWidgetShow(plugin: string) {
return BI.get(getPlugin(plugin), 'show'); return BI.get(getPlugin(plugin), 'show');
@ -36,29 +31,68 @@ export function getJdbcDatabaseType(database: string, driver: string): DatabaseT
return DATA_BASE_TYPES_OTHER; return DATA_BASE_TYPES_OTHER;
} }
let databaseType = null; let databaseType = null;
// 从全部数据库类型中获取jdbc类型的 // KERNEL-1655 兼容旧版 由于旧版设计器创建的数据连接database都为other,所以要根据driber来判断数据类型
// 兼容之前的逻辑,otherJdbc要单独处理一下 if (database && database !== 'other' && DATA_BASE_TYPES.some(item => item.databaseType === database)) {
const jdbcDatabases = getAllDatabaseTypes().filter(v => v.type === 'jdbc' || v.type === OTHER_JDBC); databaseType = DATA_BASE_TYPES.find(item => item.databaseType === database);
// KERNEL-1655 兼容旧版 由于旧版设计器创建的数据连接database都为other,所以要根据driver来判断数据类型
if (database && database !== 'other' && jdbcDatabases.some(item => item.databaseType === database)) {
databaseType = jdbcDatabases.find(item => item.databaseType === database);
} else { } else {
const designDatabase = DESIGN_DRIVER_TYPE.find(item => item.driver === driver); const designDatabase = DESIGN_DRIVER_TYPE.find(item => item.driver === driver);
const decisionDatabase = jdbcDatabases.find(item => item.driver === driver); const decisionDatabase = DATA_BASE_TYPES.find(item => item.driver === driver);
const type = designDatabase ? BI.get(designDatabase, 'type') : BI.get(decisionDatabase, 'databaseType'); const type = designDatabase ? BI.get(designDatabase, 'type') : BI.get(decisionDatabase, 'databaseType');
databaseType = jdbcDatabases.find(item => item.databaseType === type); databaseType = DATA_BASE_TYPES.find(item => item.databaseType === type);
} }
if (!databaseType) { if (!databaseType) {
return DATA_BASE_TYPES_OTHER; return DATA_BASE_TYPES_OTHER;
} }
return databaseType; return databaseType;
} }
export function resolveUrlInfo(url: string, database?: string) { export function resolveUrlInfo (url: string) {
if (BI.isNull(url)) return {}; if (BI.isNull(url)) return {};
const oracleUlr = url.match(/^jdbc:(oracle):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(:|\/)([^]+)(.*)/i);
if (oracleUlr) {
return {
host: oracleUlr[5],
port: oracleUlr[7] === 'port' ? '' : oracleUlr[7],
databaseName: oracleUlr[9],
urlInfo: oracleUlr[10],
};
}
const greenplumUrl = url.match(/^jdbc:(pivotal:greenplum):(thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(\/|;)([^]+)(.*)/i);
if (greenplumUrl) {
return {
host: greenplumUrl[4],
port: greenplumUrl[6] === 'port' ? '' : greenplumUrl[6],
databaseName: greenplumUrl[8],
urlInfo: greenplumUrl[9],
};
}
const result = url.match(/^jdbc:(mysql|sqlserver|db2|impala|kylin|phoenix|derby|gbase|gbasedbt-sqli|informix-sqli|h2|postgresql|hive2|vertica|kingbase|presto|redshift|postgresql):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(\/|;DatabaseName=)?([^]+)?(.*)/i);
if (result) {
return {
host: result[5],
port: result[7] === 'port' ? '' : result[7],
databaseName: result[9] || '',
urlInfo: result[10],
};
}
return BI.Providers.getProvider('dec.connection.provider.datebase').getJdbcResolveByType(database)(url) || { // 处理oracle的RAC方式
if (/^jdbc:oracle:thin:([0-9a-zA-Z/]*)?@\(DESCRIPTION/i.test(url)) {
const host = url.match(/\(HOST\s*=\s*([0-9a-zA-Z_\\.-]+)\)/i);
const port = url.match(/\(PORT\s*=\s*([0-9]+)\)/i);
const databaseName = url.match(/\(SERVICE_NAME\s*=\s*([\s0-9a-zA-Z_\\.]+)\)/i);
return {
host: host ? host[1] : '',
port: port && port[1] !== 'port' ? port[1] : '',
databaseName: databaseName ? databaseName[1] : '',
urlInfo: '',
};
}
return {
host: '', host: '',
port: '', port: '',
databaseName: '', databaseName: '',
@ -67,40 +101,14 @@ export function resolveUrlInfo(url: string, database?: string) {
} }
// 拼接url // 拼接url
export function splitUrl(host: string, port: string, catalog: string, database: string, baseUrl: string, databaseType: string) { export function splitUrl(host: string, port: string, database: string, baseUrl: string) {
if (baseUrl.startsWith('jdbc:sqlserver')) { if (baseUrl.startsWith('jdbc:sqlserver')) {
return baseUrl.replace('hostname', host).replace(':port', port ? `:${port}` : '') return baseUrl.replace('hostname', host).replace(':port', port ? `:${port}` : '')
.replace('=database', `=${database}`); .replace('=database', `=${database}`);
} }
// https://work.fineres.com/browse/REPORT-72078
if (baseUrl.startsWith('jdbc:informix-sqli')) {
return baseUrl.replace('hostname', host)
.replace(':port', port ? `:${port}` : '')
.replace('database', database)
.replace(':INFORMIXSERVER={server}', '');
}
if (databaseType === DATABASE_TYPE.STAR_ROCKS) {
let databaseStr = '';
if (!catalog || !database) {
databaseStr = catalog + database;
} else {
databaseStr = catalog + '.' + database;
}
return baseUrl.replace('hostname', host).replace(':port', port ? `:${port}` : '')
.replace('default_catalog.database', databaseStr);
}
if (databaseType === DATABASE_TYPE.SAP_HANA) {
return baseUrl.replace('hostname', host)
.replace('port', port || '')
.replace('=database', `=${database}`);
}
return baseUrl.replace('hostname', host).replace(':port', port ? `:${port}` : '') return baseUrl.replace('hostname', host).replace(':port', port ? `:${port}` : '')
.replace('/database', `/${database}`) .replace('database', database)
.replace(':database', `:${database}`)
.replace('dbname', database); .replace('dbname', database);
} }
@ -109,13 +117,13 @@ export function connectionCanEdit(connection: Connection) {
// privilegeType === 4 代表编辑权限,privilegeValue === 2 代表有权限 // privilegeType === 4 代表编辑权限,privilegeValue === 2 代表有权限
return connection.privilegeDetailBeanList.some(item => item.privilegeType === 4 && item.privilegeValue === 2); return connection.privilegeDetailBeanList.some(item => item.privilegeType === 4 && item.privilegeValue === 2);
} }
return true; return true;
} }
export function getTextByDatabaseType(databaseType: string) { export function getTextByDatabaseType(databaseType: string) {
const database = getAllDatabaseTypes().find(item => item.databaseType === databaseType); const database = getAllDatabaseTypes().find(item => item.databaseType === databaseType);
return database ? database.text : ''; return database ? database.text : '';
} }

78
src/modules/app.ts

@ -1,27 +1,17 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { Title } from './title/title'; import { Tab, Vtape, Absolute } from 'ui';
import { TitleXtype } from './title/title';
import { PAGE_INDEX } from './constants/constant'; import { PAGE_INDEX } from './constants/constant';
import { Connection } from './pages/connection/connection'; import { ConnectionXtype, DatebaseXtype, MaintainXtype, ConnectionPoolXtype } from './pages';
import { AppModel } from './app.model'; import { AppModel, AppModelXtype } from './app.model';
import { Tab } from '@fui/core';
import { Datebase } from './pages/database/database';
import { Maintain } from './pages/maintain/maintain';
import { ConnectionPool } from './pages/connection_pool/connection_pool';
import { TimeOutSetting } from './pages/setting/setting';
import './app.provider'; import './app.provider';
import '../less/index.less'; import '../less/index.less';
import "./pages/__point__/connect.point";
@shortcut() export const AppXtype = 'dec.dcm.main';
@store(AppModel) @store(AppModelXtype)
@shortcut(AppXtype)
export class App extends BI.Widget { export class App extends BI.Widget {
static xtype = 'dec.dcm.main'; tab: any;
props = {
baseCls: 'dec-dcm',
};
tab: Tab;
store: AppModel['store']; store: AppModel['store'];
model: AppModel['model']; model: AppModel['model'];
@ -30,82 +20,60 @@ export class App extends BI.Widget {
pageIndex: (index: string) => { pageIndex: (index: string) => {
this.tab.setSelect(index); this.tab.setSelect(index);
}, },
}; }
render() { render() {
return { return {
type: BI.VTapeLayout.xtype, type: Vtape,
items: [ items: [
{ {
el: { el: {
type: Title.xtype, type: TitleXtype,
listeners: [{ cls: 'bi-border-bottom',
eventName: 'EVENT_CLICK_SETTING',
action:() => {
this._setting();
},
}]
}, },
height: 40, height: 40,
}, },
{ {
type: BI.AbsoluteLayout.xtype, type: Absolute,
cls: 'bi-background', cls: 'bi-background',
items: [{ items: [{
el: { el: {
type: BI.Tab.xtype, type: Tab,
cls: 'bi-card', cls: 'bi-card',
single: true, single: true,
tgap: 10, tgap: 10,
showIndex: this.model.pageIndex, showIndex: this.model.pageIndex,
ref: (_ref: Tab) => { ref: (_ref: any) => {
this.tab = _ref; this.tab = _ref;
}, },
cardCreator: (index: string) => { cardCreator: (index: string) => {
switch (index) { switch (index) {
case PAGE_INDEX.CONNECTION: case PAGE_INDEX.CONNECTION:
return { return {
type: Connection.xtype, type: ConnectionXtype,
}; };
case PAGE_INDEX.DATEBASE: case PAGE_INDEX.DATEBASE:
return { return {
type: Datebase.xtype, type: DatebaseXtype,
}; };
case PAGE_INDEX.MAINTAIN: case PAGE_INDEX.MAINTAIN:
return { return {
type: Maintain.xtype, type: MaintainXtype,
}; };
default: default:
return { return {
type: ConnectionPool.xtype, type: ConnectionPoolXtype,
}; };
} }
}, },
}, },
left: 0, left: 10,
top: 0, top: 10,
right: 0, right: 10,
bottom: 0, bottom: 10,
}], }],
}, },
], ],
}; };
} }
private _setting() {
const settingLayerId = BI.UUID();
BI.Layers.create(settingLayerId, null, {
container: this,
render: {
type: TimeOutSetting.xtype,
listeners: [{
eventName: "EVENT_CHANGE",
action: function () {
BI.Layers.remove(settingLayerId);
},
}],
},
}, this);
BI.Layers.show(settingLayerId);
}
} }

11
src/modules/app.typings.d.ts vendored

@ -8,18 +8,9 @@ export interface DatabaseType {
internal: boolean; internal: boolean;
type: string; type: string;
hasSchema?: boolean; hasSchema?: boolean;
hasSchemas?: {
[key: string]: boolean;
};
fetchSize: number;
versionConfig?: {
[key: string]: DatabaseType;
},
kerberos?: boolean; kerberos?: boolean;
iconUrl?: string; iconUrl?: string;
versions?: string[];
urls?: { urls?: {
[key: string]: string; [key: string]: string;
}; }
marker?: string;
} }

5
src/modules/components/collapse/collapse.model.ts

@ -1,9 +1,8 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
@model() export const CollapseModelXtype = 'dec.dcm.model.components.collapse';
@model(CollapseModelXtype)
export class CollapseModel extends Model { export class CollapseModel extends Model {
static xtype = 'dec.dcm.model.components.collapse';
state() { state() {
return { return {
isCollapse: true, isCollapse: true,

33
src/modules/components/collapse/collapse.ts

@ -1,22 +1,20 @@
import { IconLabel, Left, Label } from 'ui';
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { CollapseModel } from './collapse.model'; import { CollapseModel, CollapseModelXtype } from './collapse.model';
import { IconLabel } from '@fui/core';
export const EVENT_CHANGE = 'EVENT_CHANGE'; export const EVENT_CHANGE = 'EVENT_CHANGE';
@shortcut() export const CollapseXtype = 'dec.dcm.components.collapse';
@store(CollapseModel) @shortcut(CollapseXtype)
@store(CollapseModelXtype)
export class Collapse extends BI.BasicButton { export class Collapse extends BI.BasicButton {
static xtype = 'dec.dcm.components.collapse';
props = { props = {
name: '', name: '',
isCollapse: true, isCollapse: true,
$testId: 'dec-dcm-components-collapse', $testId: 'dec-dcm-components-collapse',
el: {},
} }
rightFont: IconLabel; rightFont: any;
downFont: IconLabel; downFont: any;
model: CollapseModel['model']; model: CollapseModel['model'];
store: CollapseModel['store']; store: CollapseModel['store'];
@ -33,32 +31,31 @@ export class Collapse extends BI.BasicButton {
this.store.setCollapse(this.options.isCollapse); this.store.setCollapse(this.options.isCollapse);
return { return {
type: BI.FloatLeftLayout.xtype, type: Left,
items: [ items: [
{ {
type: BI.IconLabel.xtype, type: IconLabel,
height: 17, height: 17,
cls: 'dcm-triangle-collapse-font icon-size-16', cls: 'dcm-triangle-collapse-font icon-size-16',
ref: (_ref: IconLabel) => { ref: (_ref: any) => {
this.rightFont = _ref; this.rightFont = _ref;
}, },
invisible: !this.model.isCollapse, invisible: !this.model.isCollapse,
}, },
{ {
type: BI.IconLabel.xtype, type: IconLabel,
height: 17, height: 17,
cls: 'dcm-triangle-expand-font icon-size-16', cls: 'dcm-triangle-expand-font icon-size-16',
ref: (_ref: IconLabel) => { ref: (_ref: any) => {
this.downFont = _ref; this.downFont = _ref;
}, },
invisible: this.model.isCollapse, invisible: this.model.isCollapse,
}, },
{ {
type: BI.Label.xtype, type: Label,
lgap: 2, lgap: 2,
text: this.options.name, text: this.options.name,
}, },
this.options.el,
], ],
}; };
} }
@ -66,8 +63,4 @@ export class Collapse extends BI.BasicButton {
doClick() { doClick() {
this.store.setCollapse(!this.model.isCollapse); this.store.setCollapse(!this.model.isCollapse);
} }
setCollapse(v: boolean) {
this.store.setCollapse(v);
}
} }

68
src/modules/components/file_chooser/file_chooser.model.ts

@ -1,68 +0,0 @@
import { model, Model } from '@core/core';
type RootInfo = {
url: string; // api url
prefix: string; // 路径前缀
root: string; // 根文件夹名称
};
export const ROOT_INFO_MAP: Record<string, RootInfo> = {
// 证书 resources/certificates/
certificates: {
url: '/v10/certificates/all',
prefix: 'resources/',
root: 'certificates',
},
};
@model()
export class FileChooserModel extends Model {
static xtype = 'dec.dcm.model.components.file_chooser';
private options: {
root: string;
};
state() {
return {
keyword: '', // 搜索关键字
items: [], // 文件项
};
}
actions = {
/**
* items
* @param callback
*/
requestGetItems: (callback?: Function) => {
const { keyword } = this.model;
const { url, prefix, root } = ROOT_INFO_MAP[this.options.root];
const requestUrl = `${url}?keyword=${encodeURIComponent(keyword)}`;
Dec.reqGetHandle(requestUrl, '', (data) => {
this.model.items = data
.concat({
id: root,
text: prefix + root,
value: prefix + root,
isParent: true,
})
.map((item) => ({
...item,
value: prefix + item.path,
open: item.id === root || BI.isKey(keyword),
}));
BI.isFunction(callback) && callback();
});
},
/**
* keyword
* @param value
*/
setKeyword: (value: string) => {
this.model.keyword = value;
this.requestGetItems();
},
};
}

183
src/modules/components/file_chooser/file_chooser.ts

@ -1,183 +0,0 @@
import { EVENT_CHANGE } from './../collapse/collapse';
import { shortcut, store } from '@core/core';
import { SignEditor, MultiLayerSingleLevelTree, SearchEditor, Button, Editor } from '@fui/core';
import { FileChooserModel } from './file_chooser.model';
@shortcut()
@store(FileChooserModel, {
props(this: FileChooser) {
return this.options;
},
})
export class FileChooser extends BI.Widget {
static xtype = 'dec.dcm.components.file_chooser';
props = {
width: 300,
root: '', // 含义见model中的RootInfo
watermark: '',
value: '',
};
model: FileChooserModel['model'];
store: FileChooserModel['store'];
watch = {
items: (value) => {
this.fileTree.populate(value);
},
};
textEditor: SignEditor;
keywordEditor: SearchEditor;
fileTree: MultiLayerSingleLevelTree;
sureButton: Button;
render() {
const { width, watermark, value } = this.options;
return {
type: BI.VerticalAdaptLayout.xtype,
height: 24,
items: [
{
type: BI.SignEditor.xtype,
cls: 'bi-border-bottom bi-focus-shadow',
width,
height: 22,
watermark,
title: value,
value,
ref: (_ref: SignEditor) => {
this.textEditor = _ref;
},
listeners: [
{
eventName: BI.SignEditor.EVENT_CHANGE,
action: () => {
const value = this.textEditor.getValue();
this.setValue(value);
},
},
],
},
{
el: {
type: BI.Button.xtype,
text: BI.i18nText('Dec-Basic_Choose_File'),
clear: true,
handler: () => {
this.openFileChoosePopover();
},
},
lgap: 10,
},
],
};
}
getValue(): string {
return this.textEditor.getValue();
}
setValue(value: string) {
this.options.value = value;
this.textEditor.text.setTitle(value);
this.textEditor.setValue(value);
}
/**
*
*/
private openFileChoosePopover() {
// 重置搜索关键词
this.store.setKeyword('');
// 创建并显示窗口
const popoverName = BI.UUID();
BI.Popovers.create(
popoverName,
{
header: BI.i18nText('Dec-Data_Set_File_Select_Server_File'),
body: {
type: BI.VTapeLayout.xtype,
items: [
{
type: BI.SearchEditor.xtype,
ref: (ref: SearchEditor) => {
this.keywordEditor = ref;
},
height: 24,
value: this.model.keyword,
listeners: [
{
eventName: BI.SearchEditor.EVENT_CHANGE,
action: () => {
const value = this.keywordEditor.getValue();
this.store.setKeyword(value);
},
},
{
eventName: BI.SearchEditor.EVENT_CLEAR,
action: () => {
this.store.setKeyword('');
},
},
],
},
{
el: {
type: BI.MultiLayerSingleLevelTree.xtype,
ref: (ref: MultiLayerSingleLevelTree) => {
this.fileTree = ref;
},
keywordGetter: () => this.model.keyword,
items: this.model.items,
listeners: [
{
eventName: BI.MultiLayerSingleLevelTree.EVENT_CHANGE,
action: () => {
this.sureButton.setEnable(true);
},
},
],
},
tgap: 15,
},
{
type: BI.RightVerticalAdaptLayout.xtype,
height: 24,
vgap: 10,
items: [
{
type: BI.Button.xtype,
text: BI.i18nText('BI-Basic_Cancel'),
level: 'ignore',
handler: () => {
BI.Popovers.remove(popoverName);
},
},
{
el: {
type: BI.Button.xtype,
ref: (ref: Button) => {
this.sureButton = ref;
},
text: BI.i18nText('BI-Basic_OK'),
disabled: true,
handler: () => {
const value = this.fileTree.getValue()[0];
this.setValue(value);
BI.Popovers.remove(popoverName);
},
},
lgap: 10,
},
],
},
],
},
},
this
).show(popoverName);
}
}

13
src/modules/components/file_upload/file_upload.less

@ -1,13 +0,0 @@
.data-conf-file {
.x-icon{
width: 48px;
height: 48px;
}
}
.data-keytab-file {
.x-icon{
width: 48px;
height: 48px;
}
}

35
src/modules/components/file_upload/file_upload.model.ts

@ -1,35 +0,0 @@
import { model, Model } from '@core/core';
type UploadParam = {
keytabPath: string;
krb5ConfPath: string;
principal: string;
}
@model()
export class FileUploadModel extends Model {
static xtype = 'dec.dcm.model.components.file_upload';
private options: {
inter: string;
}
state() {
return {
uploadUrl: '',
fileName: '',
};
}
actions = {
setFileInfo: (params: UploadParam) => {
const inter = this.options.inter;
this.model.uploadUrl = Dec.Utils.getEncodeURL(Dec.fineServletURL + inter, "", params);
},
setFileName:(v: string) => {
this.model.fileName = v;
}
}
}

327
src/modules/components/file_upload/file_upload.ts

@ -1,327 +0,0 @@
import { shortcut, store } from '@core/core';
import { SignEditor, MultiLayerSingleLevelTree, SearchEditor, Button, Editor, Label } from '@fui/core';
import { FileUploadModel } from './file_upload.model';
import { ApiFactory } from 'src/modules/crud/apiFactory';
import './file_upload.less';
const api = new ApiFactory().create();
@shortcut()
@store(FileUploadModel, {
props(this: FileUpload) {
return this.options;
},
})
export class FileUpload extends BI.Widget {
public static xtype = "dec.dcm.components.file_upload";
public static EVENT_CHECK_SUCCESS = 'EVENT_CHECK_SUCCESS';
public static EVENT_CLEAR_FILE = 'EVENT_CLEAR_FILE';
public props = {
watermark: '',
value: '',
processId: '',
disabled: false,
inter: '',
access: '',
iconCls: ''
};
model: FileUploadModel['model'];
store: FileUploadModel['store'];
watch = {
uploadUrl: function () {
this.uploader.setUrl(this.model.uploadUrl);
},
};
public textEditor: SignEditor;
public keywordEditor: SearchEditor;
public fileTree: MultiLayerSingleLevelTree;
public sureButton: Button;
public infoLabel: Label;
public render() {
const { width, watermark, value, processId, inter } = this.options;
let self = this;
const processName = BI.concat("process-", processId);
const processClass = BI.concat(".process-", processId);
this.setFileInfo({
keytabPath: '',
principal:'',
krb5ConfPath: '',
});
return {
type: BI.VerticalLayout.xtype,
items:[{
type: BI.FloatLeftLayout.xtype,
items: [
{
type: BI.SignEditor.xtype,
cls: 'bi-border-bottom bi-focus-shadow',
width: 300,
height: 22,
watermark,
disabled: true,
value,
ref: (_ref: SignEditor) => {
this.textEditor = _ref;
},
listeners: [
{
eventName: BI.SignEditor.EVENT_CHANGE,
action: () => {
const value = this.textEditor.getValue();
this.setValue(value);
},
},
],
}, {
type: BI.Button.xtype,
width: 100,
_lgap: 10,
iconCls: "upload-font",
level: "ignore",
ghost: true,
ref: (_ref: Button) => {
this.uploadButton = _ref;
},
text: BI.i18nText('Dec-Basic_Choose_File'),
handler: () => {
this.uploader.select();
},
},
],
}, {
type: BI.FloatLeftLayout.xtype,
tgap: 8,
invisible: true,
ref: (_ref) => {
this.fileInfo = _ref;
},
items: [
{
type: BI.VerticalLayout.xtype,
cls: "bi-border",
items: [{
type: BI.HTapeLayout.xtype,
height: 68,
width: 300,
items: [{
el: {
type: BI.IconLabel.xtype,
cls: this.options.iconCls,
},
width: 48,
lgap: 8,
}, {
el: {
type: BI.VerticalLayout.xtype,
items : [{
type: BI.Label.xtype,
width: 200,
height: 20,
textAlign: "left",
ref: (_ref: Label) => {
this.fileName = _ref;
},
},{
type: BI.VerticalAdaptLayout.xtype,
items: [{
type: BI.Label.xtype,
cls: "bi-tips",
height: 20,
rgap: 3,
ref: (_ref: Label) => {
this.fileSize = _ref;
},
}, {
type: BI.Label.xtype,
cls: "bi-tips",
height: 20,
ref: (_ref: Label) => {
this.fileModified = _ref;
},
}]
}],
},
tgap: 14,
lgap: 4,
}, {
el: {
type: BI.IconButton.xtype,
cls: "default-delete-font",
handler: function () {
NProgress.set(0.0);
self.xhr.abort();
self.store.setFileName('');
self.clearInfo();
self.fireEvent(FileUpload.EVENT_CLEAR_FILE);
},
},
rgap: 10,
}]
}, {
type: BI.VerticalLayout.xtype,
cls: processName,
width: 300,
height: 1,
}]
}, {
el :{
type: BI.VerticalLayout.xtype,
cls: "bi-error",
ref: (_ref: any) => {
this.errorInfo = _ref;
},
invisible: true,
items : [{
type: BI.Label.xtype,
height: 20,
textAlign: "left",
ref: (_ref: Label) => {
this.errorCode = _ref;
},
},{
type: BI.Label.xtype,
height: 20,
textAlign: "left",
ref: (_ref: Label) => {
this.errorMsg = _ref;
},
}, {
type: BI.VerticalAdaptLayout.xtype,
rgap: 5,
items: [
{
type: BI.Label.xtype,
text: BI.i18nText('Dec-Dcm_Connection_File_Upload_ErrorTip1'),
},{
type: BI.TextButton.xtype,
cls: "bi-high-light bi-high-light-border-bottom",
text: BI.i18nText('Dec-Dcm_Connection_File_Upload_ErrorTip2'),
handler: function () {
window.open(Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][DecCst.Hyperlink.KERBEROS_CONF_HELP]);
},
},{
type: BI.Label.xtype,
text: BI.i18nText('Dec-Dcm_Connection_File_Upload_ErrorTip3'),
}
],
},],
},
vgap: 4,
lgap: 8,
}
],
}, {
type: BI.MultifileEditor.xtype,
ref: (ref:any) => {
self.uploader = ref;
},
url: this.model.uploadUrl,
accept: this.options.accept,
listeners: [
{
// 选择文件
eventName: BI.MultifileEditor.EVENT_CHANGE,
action: function (files) {
self.options.attachId = '';
const fileInfo = files.files[0];
self.setInfo(fileInfo);
self.store.setFileName(fileInfo.fileName);
this.upload();
NProgress.configure({ parent: processClass, minimum: 0.0 });
},
},
{
// 上传进度刷新
eventName: BI.MultifileEditor.EVENT_PROGRESS,
action: function (progress) {
let rate = progress.loaded/progress.total;
NProgress.set(rate);
},
},
{
// 开始上传文件
eventName: BI.MultifileEditor.EVENT_UPLOADSTART,
action: function (progressEvent, xhr) {
self.xhr = xhr;
},
},
{
// 上传文件完毕
eventName: BI.MultifileEditor.EVENT_UPLOADED,
action: function () {
const uploadedInfo = this.getValue();
const failed = BI.some(uploadedInfo, function (index, file) {
if (file.data.errorCode) {
BI.Msg.toast(uploadedInfo[0].filename + BI.i18nText('Dec-Dcm_Connection_File_Upload_Error'), {
level: "error",
});
self.setErrorInfo(file.data)
return true;
}
});
const key = self.options.processId +'Path';
!failed && self.setValue(uploadedInfo[0].data.kerberosInfo[key]);
!failed && self.fireEvent(FileUpload.EVENT_CHECK_SUCCESS, uploadedInfo[0].data);
!failed && BI.Msg.toast(uploadedInfo[0].filename + BI.i18nText('Dec-Dcm_Connection_File_Upload_Success'),{
level: "success"
});
NProgress.configure({ parent: 'body'});
},
},
],
}]
};
}
public getValue(): string {
return this.options.value;
}
public setValue(value: string) {
this.options.value = value;
this.textEditor.text.setTitle(value);
this.textEditor.setValue(value);
}
public setInfo(info: any) {
this.uploadButton.setEnable(false);
this.fileInfo.setVisible(true);
this.textEditor.setValue(info.fileName);
this.fileName.setText(info.fileName);
this.fileSize.setText(Dec.Utils.getByteWidthUnit(info.size));
this.fileModified.setText(BI.getDate().print("%Y-%X-%d %H:%M:%S"))
}
public clearInfo() {
this.uploadButton.setEnable(true);
this.fileInfo.setVisible(false);
this.errorInfo.setVisible(false);
this.textEditor.setValue('');
this.options.attachId = '';
}
public setErrorInfo(errorInfo: any) {
this.errorInfo.setVisible(true);
this.errorCode.setText(BI.i18nText("Dec-Dcm_Connection_File_Upload_ErrorCode") + ":"+ errorInfo.errorCode);
this.errorMsg.setText(BI.i18nText("Dec-Dcm_Connection_File_Upload_ErrorMsg") + ":" + errorInfo.errorMessage);
}
public setEnable(v) {
this.uploadButton._setEnable(v);
}
public setFileInfo(params) {
this.store.setFileInfo(params);
}
}

52
src/modules/components/link_button/link.ts

@ -1,52 +0,0 @@
import { shortcut } from '@core/core';
import { Label } from '@fui/core';
const DEFAULT_LINK = '/';
@shortcut()
export class LinkButton extends BI.BasicButton {
static xtype = 'dec.dcm.components.link.button';
props: {
text: string;
cls: string;
$testId: string;
link?: Function | string;
} = {
text: '',
cls: 'cursor-pointer',
$testId: 'dec-dcm-link-button',
}
private text: Label;
render() {
return {
type: BI.CenterAdaptLayout.xtype,
cls: 'bi-high-light',
items: [
{
type: BI.Label.xtype,
cls: 'bi-high-light-border-bottom',
text: this.options.text,
ref: (_ref: Label) => {
this.text = _ref;
},
},
],
};
}
getLink() {
const link = this.options.link;
return (BI.isFunction(link) ? link() : link) || DEFAULT_LINK;
}
setText(v: string) {
this.text.setText(v);
}
doClick() {
window.open(this.getLink());
}
}

5
src/modules/components/test_status/test_status.model.ts

@ -1,9 +1,8 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { TEST_STATUS } from '@constants/constant'; import { TEST_STATUS } from '@constants/constant';
export const TestStatusModelXtype = 'dec.dcm.model.components.test_status';
@model() @model(TestStatusModelXtype)
export class TestStatusModel extends Model { export class TestStatusModel extends Model {
static xtype = 'dec.dcm.model.components.test_status';
state() { state() {
return { return {
status: TEST_STATUS.LOADING, status: TEST_STATUS.LOADING,

108
src/modules/components/test_status/test_status.ts

@ -1,16 +1,17 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { TestStatusModel } from './test_status.model'; import { TestStatusModelXtype, TestStatusModel } from './test_status.model';
import { CenterAdapt, Tab, Vertical, Label, TextButton, Left } from 'ui';
import { TEST_STATUS } from '@constants/constant'; import { TEST_STATUS } from '@constants/constant';
import { TipIcon } from './tip_icon/tip_icon'; import { TipIconXtype } from './tip_icon/tip_icon';
import { TipFail } from './tip_icon/tip_fail'; import { TipFailXtype, EVENT_CLOSE, EVENT_RELOAD, EVENT_DETAIL } from './tip_icon/tip_fail';
import { FloatLeftLayout, Label, Tab, VerticalLayout } from '@fui/core'; export const TestStatusXtype = 'dec.dcm.components.test_status';
@shortcut() export {
@store(TestStatusModel) EVENT_CLOSE,
EVENT_RELOAD,
};
@shortcut(TestStatusXtype)
@store(TestStatusModelXtype)
export class TestStatus extends BI.Widget { export class TestStatus extends BI.Widget {
static xtype = 'dec.dcm.components.test_status';
static EVENT_CLOSE = 'EVENT_CLOSE';
static EVENT_RELOAD = 'EVENT_RELOAD';
props = { props = {
loadingCls: '', loadingCls: '',
loadingText: '', loadingText: '',
@ -24,14 +25,11 @@ export class TestStatus extends BI.Widget {
model: TestStatusModel['model']; model: TestStatusModel['model'];
store: TestStatusModel['store']; store: TestStatusModel['store'];
tab: Tab; tab: any;
failMessage: Label; failMessage: any;
failDriverMessage: Label; failDriverMessage: any;
driverLink: FloatLeftLayout; driverLink: any;
detail: VerticalLayout; detail: any;
failMaskers: any;
extraContainer: VerticalLayout;
watch = { watch = {
status: (status: string) => { status: (status: string) => {
@ -40,62 +38,55 @@ export class TestStatus extends BI.Widget {
} }
render() { render() {
const LAYOUT_WIDTH = 400;
const { loadingCls, loadingText, successCls, successText, failCls, failText, retryText } = this.options; const { loadingCls, loadingText, successCls, successText, failCls, failText, retryText } = this.options;
return { return {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
cls: 'bi-z-index-mask', cls: 'bi-z-index-mask',
items: [ items: [
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
items: [ items: [
{ {
type: BI.Tab.xtype, type: Tab,
cls: 'bi-card', cls: 'bi-card',
width: 450, width: 450,
height: 250, height: 250,
// single: true, single: true,
showIndex: this.model.status, showIndex: this.model.status,
ref: (_ref: Tab) => { ref: (_ref: any) => {
this.tab = _ref; this.tab = _ref;
}, },
cardCreator: (index: string) => { cardCreator: (index: string) => {
switch (index) { switch (index) {
case TEST_STATUS.SUCCESS: case TEST_STATUS.SUCCESS:
return { return {
type: TipIcon.xtype, type: TipIconXtype,
tipCls: successCls, tipCls: successCls,
tipText: successText, tipText: successText,
}; };
case TEST_STATUS.FAIL: case TEST_STATUS.FAIL:
return { return {
type: TipFail.xtype, type: TipFailXtype,
tipCls: failCls, tipCls: failCls,
tipText: failText, tipText: failText,
retryText, retryText,
ref: (_ref: TipFail) => {
this.failMaskers = _ref;
if (BI.isEmptyString(this.failMessage.getText())) {
this.failMaskers.populateFail(BI.i18nText('Dec-Conn-ect-Failed'), false);
}
},
listeners: [ listeners: [
{ {
eventName: TipFail.EVENT_RELOAD, eventName: EVENT_RELOAD,
action: () => { action: () => {
this.fireEvent(TestStatus.EVENT_RELOAD); this.fireEvent(EVENT_RELOAD);
this.detail.setVisible(false); this.detail.setVisible(false);
}, },
}, },
{ {
eventName: TipFail.EVENT_CLOSE, eventName: EVENT_CLOSE,
action: () => { action: () => {
this.fireEvent(TestStatus.EVENT_CLOSE); this.fireEvent(EVENT_CLOSE);
}, },
}, },
{ {
eventName: TipFail.EVENT_DETAIL, eventName: EVENT_DETAIL,
action: (isCollapse: boolean) => { action: (isCollapse: boolean) => {
this.tab.setHeight(isCollapse ? 250 : 200); this.tab.setHeight(isCollapse ? 250 : 200);
this.detail.setVisible(!isCollapse); this.detail.setVisible(!isCollapse);
@ -105,7 +96,7 @@ export class TestStatus extends BI.Widget {
}; };
default: default:
return { return {
type: TipIcon.xtype, type: TipIconXtype,
tipCls: loadingCls, tipCls: loadingCls,
tipText: loadingText, tipText: loadingText,
}; };
@ -113,13 +104,13 @@ export class TestStatus extends BI.Widget {
}, },
}, },
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
cls: 'bi-card', cls: 'bi-card',
invisible: true, invisible: true,
bgap: 10, bgap: 10,
items: [ items: [
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
cls: 'bi-header-background', cls: 'bi-header-background',
vgap: 5, vgap: 5,
hgap: 10, hgap: 10,
@ -127,36 +118,29 @@ export class TestStatus extends BI.Widget {
height: 75, height: 75,
items: [ items: [
{ {
type: BI.VerticalLayout.xtype, type: Label,
width: LAYOUT_WIDTH,
ref: (_ref: VerticalLayout) => {
this.extraContainer = _ref;
}
},
{
type: BI.Label.xtype,
whiteSpace: 'normal', whiteSpace: 'normal',
width: LAYOUT_WIDTH, width: 400,
textAlign: 'left', textAlign: 'left',
text: '', text: '',
ref: (_ref: Label) => { ref: (_ref: any) => {
this.failMessage = _ref; this.failMessage = _ref;
}, },
}, },
{ {
type: BI.Label.xtype, type: Label,
textAlign: 'left', textAlign: 'left',
invisible: true, invisible: true,
ref: (_ref: Label) => { ref: (_ref: any) => {
this.failDriverMessage = _ref; this.failDriverMessage = _ref;
}, },
}, },
{ {
type: BI.FloatLeftLayout.xtype, type: Left,
invisible: true, invisible: true,
items: [ items: [
{ {
type: BI.TextButton.xtype, type: TextButton,
cls: 'bi-high-light bi-high-light-border-bottom', cls: 'bi-high-light bi-high-light-border-bottom',
text: BI.i18nText('Dec-Dcm_Connection_Download_Driver'), text: BI.i18nText('Dec-Dcm_Connection_Download_Driver'),
handler: () => { handler: () => {
@ -164,14 +148,14 @@ export class TestStatus extends BI.Widget {
}, },
}, },
], ],
ref: (_ref: FloatLeftLayout) => { ref: (_ref: any) => {
this.driverLink = _ref; this.driverLink = _ref;
}, },
}, },
], ],
}, },
], ],
ref: (_ref: VerticalLayout) => { ref: (_ref: any) => {
this.detail = _ref; this.detail = _ref;
}, },
}, },
@ -185,7 +169,7 @@ export class TestStatus extends BI.Widget {
this.store.setStatus(TEST_STATUS.SUCCESS); this.store.setStatus(TEST_STATUS.SUCCESS);
} }
setFail(message: string = '', driver = '', link = '') { setFail(message: string, driver = '', link = '') {
this.store.setStatus(TEST_STATUS.FAIL); this.store.setStatus(TEST_STATUS.FAIL);
this.failMessage.setText(message); this.failMessage.setText(message);
this.failDriverMessage.setVisible(!!driver); this.failDriverMessage.setVisible(!!driver);
@ -199,14 +183,4 @@ export class TestStatus extends BI.Widget {
setLoading() { setLoading() {
this.store.setStatus(TEST_STATUS.LOADING); this.store.setStatus(TEST_STATUS.LOADING);
} }
/**
*
*/
setExtraContainer(container: Obj) {
BI.createWidget({
...container,
element: this.extraContainer,
});
}
} }

6
src/modules/components/test_status/tip_icon/tip_fail.model.ts

@ -1,9 +1,7 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
export const TipFailModelXtype = 'dec.dcm.model.components.test_status.tip_fail';
@model() @model(TipFailModelXtype)
export class TipFailModel extends Model { export class TipFailModel extends Model {
static xtype = 'dec.dcm.model.components.test_status.tip_fail';
context: ['isCollapse']; context: ['isCollapse'];
state() { state() {

64
src/modules/components/test_status/tip_icon/tip_fail.ts

@ -1,16 +1,13 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { Button, Label } from '@fui/core'; import { Vertical, HorizotalAuto, CenterAdapt, Label, VerticalAdapt, Button } from 'ui';
import { TipFailModel } from './tip_fail.model'; import { TipFailModel, TipFailModelXtype } from './tip_fail.model';
export const TipFailXtype = 'dec.dcm.components.test_status.tip_fail';
@shortcut() export const EVENT_CLOSE = 'EVENT_CLOSE';
@store(TipFailModel) export const EVENT_RELOAD = 'EVENT_RELOAD';
export const EVENT_DETAIL = 'EVENT_DETAIL';
@shortcut(TipFailXtype)
@store(TipFailModelXtype)
export class TipFail extends BI.Widget { export class TipFail extends BI.Widget {
static xtype = 'dec.dcm.components.test_status.tip_fail';
static EVENT_CLOSE = 'EVENT_CLOSE';
static EVENT_RELOAD = 'EVENT_RELOAD';
static EVENT_DETAIL = 'EVENT_DETAIL';
props = { props = {
tipCls: '', tipCls: '',
tipText: '', tipText: '',
@ -20,8 +17,8 @@ export class TipFail extends BI.Widget {
model: TipFailModel['model']; model: TipFailModel['model'];
store: TipFailModel['store']; store: TipFailModel['store'];
detailButton: Button; detailButton: any;
failText:Label;
watch = { watch = {
isCollapse: (isCollapse: boolean) => { isCollapse: (isCollapse: boolean) => {
this.detailButton.setText(isCollapse ? this.detailButton.setText(isCollapse ?
@ -29,22 +26,18 @@ export class TipFail extends BI.Widget {
BI.i18nText('Dec-Dcm_Connection_Detailed_Information')); BI.i18nText('Dec-Dcm_Connection_Detailed_Information'));
}, },
} }
populateFail(text:string,isVisible:boolean){
this.failText.setText(text);
this.detailButton.setVisible(isVisible);
}
render() { render() {
const { tipCls, tipText, retryText } = this.options; const { tipCls, tipText, retryText } = this.options;
return { return {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
items: [ items: [
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
items: [ items: [
{ {
type: BI.HorizontalAutoLayout.xtype, type: HorizotalAuto,
cls: tipCls, cls: tipCls,
bgap: 20, bgap: 20,
items: [{ items: [{
@ -53,43 +46,40 @@ export class TipFail extends BI.Widget {
height: 60, height: 60,
}], }],
}, { }, {
type: BI.Label.xtype, type: Label,
_bgap: 10, height: 14,
bgap: 10,
text: tipText, text: tipText,
ref:(_ref:Label)=>{
this.failText=_ref;
}
}, },
{ {
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
hgap: 12, hgap: 5,
items: [ items: [
{ {
type: BI.Button.xtype, type: Button,
text: BI.i18nText('Dec-Dcm_Connection_Detailed_Information'), text: BI.i18nText('Dec-Dcm_Connection_Detailed_Information'),
clear: true, level: 'ignore',
ref: (_ref: Button) => { ref: (_ref: any) => {
this.detailButton = _ref; this.detailButton = _ref;
}, },
handler: () => { handler: () => {
this.store.setIsCollapse(!this.model.isCollapse); this.store.setIsCollapse(!this.model.isCollapse);
this.fireEvent(TipFail.EVENT_DETAIL, !this.model.isCollapse); this.fireEvent(EVENT_DETAIL, !this.model.isCollapse);
}, },
}, },
{ {
type: BI.Button.xtype, type: Button,
light: true,
text: BI.i18nText('Dec-Dcm_Back'), text: BI.i18nText('Dec-Dcm_Back'),
level: 'ignore',
handler: () => { handler: () => {
this.fireEvent(TipFail.EVENT_CLOSE); this.fireEvent(EVENT_CLOSE);
}, },
}, },
{ {
type: BI.Button.xtype, type: Button,
text: retryText, text: retryText,
handler: () => { handler: () => {
this.store.setIsCollapse(false); this.fireEvent(EVENT_RELOAD);
this.fireEvent(TipFail.EVENT_RELOAD);
}, },
}, },
], ],

14
src/modules/components/test_status/tip_icon/tip_icon.ts

@ -1,8 +1,8 @@
import { shortcut } from '@core/core'; import { shortcut } from '@core/core';
@shortcut() import { Vertical, HorizotalAuto, CenterAdapt, Label } from 'ui';
export const TipIconXtype = 'dec.dcm.components.test_status.tip_icon';
@shortcut(TipIconXtype)
export class TipIcon extends BI.Widget { export class TipIcon extends BI.Widget {
static xtype = 'dec.dcm.components.test_status.tip_icon';
props = { props = {
tipCls: '', tipCls: '',
tipText: '', tipText: '',
@ -11,13 +11,13 @@ export class TipIcon extends BI.Widget {
const { tipCls, tipText } = this.options; const { tipCls, tipText } = this.options;
return { return {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
items: [ items: [
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
items: [ items: [
{ {
type: BI.HorizontalAutoLayout.xtype, type: HorizotalAuto,
cls: tipCls, cls: tipCls,
bgap: 20, bgap: 20,
items: [{ items: [{
@ -26,7 +26,7 @@ export class TipIcon extends BI.Widget {
height: 60, height: 60,
}], }],
}, { }, {
type: BI.Label.xtype, type: Label,
height: 14, height: 14,
text: tipText, text: tipText,
}, },

131
src/modules/components/text_checker/text_checker.ts

@ -1,99 +1,86 @@
import { shortcut } from '@core/core'; import { shortcut } from '@core/core';
import { Label, TextEditor } from '@fui/core'; import { TextEditor, Absolute, Label } from 'ui';
export const TextCheckerXtype = 'dec.dcm.components.text_checker';
@shortcut() @shortcut(TextCheckerXtype)
export class TextChecker extends BI.Widget { export class TextChecker extends BI.Widget {
public static xtype = 'dec.dcm.components.text_checker'; props = {
public props = {
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: '', value: '',
watermark: '', watermark: '',
inputType: 'text',
autocomplete: '',
validationChecker: [] as { validationChecker: [] as {
errorText: string; errorText: string;
checker: (value: string) => boolean; checker: (value: string) => boolean;
autoFix?: boolean; autoFix?: boolean;
}[], }[],
$value: '', }
};
public textEditor: TextEditor; textEditor: any;
public errorLabel: Label; errorLabel: any;
private isError: boolean; private isError;
private value: string; private value: string;
private errorChecker: { private errorChecker: {
errorText: string; errorText: string;
checker: (value: string) => boolean; checker: (value: string) => boolean;
autoFix?: boolean; autoFix?: boolean;
}; }
public render() { render() {
const { width, allowBlank, value, watermark, inputType, autocomplete, validationChecker, $value } = this.options; const { width, allowBlank, value, watermark, validationChecker, $value } = this.options;
this.value = value; this.value = value;
return { return {
type: BI.AbsoluteLayout.xtype, type: Absolute,
width, width,
height: 20, height: 20,
items: [ items: [{
{ el: {
el: { type: TextEditor,
type: BI.TextEditor.xtype, $value,
$value, width,
width, allowBlank,
allowBlank, value,
value, watermark,
watermark, ref: (_ref: any) => {
inputType, this.textEditor = _ref;
autocomplete,
ref: (_ref: TextEditor) => {
this.textEditor = _ref;
},
listeners: [
{
eventName: BI.Editor.EVENT_CHANGE,
action: () => {
const value = this.getValue();
if (value) {
this.errorChecker = validationChecker.find((item) => item.checker && !item.checker(value));
this.errorLabel.setText(BI.get(this.errorChecker, 'errorText'));
this.isError = !!BI.get(this.errorChecker, 'errorText');
} else {
this.errorLabel.setText('');
this.isError = false;
}
if (!this.isError) {
this.value = value;
}
this.fireEvent(BI.Editor.EVENT_CHANGE);
},
},
{
eventName: BI.TextEditor.EVENT_BLUR,
action: () => {
if (BI.get(this.errorChecker, 'autoFix')) {
this.setValue(this.value);
this.errorLabel.setText('');
}
},
},
],
}, },
}, listeners: [{
{ eventName: BI.Editor.EVENT_CHANGE,
el: { action: () => {
type: BI.Label.xtype, const value = this.getValue();
cls: 'bi-error', if (value) {
ref: (_ref: Label) => { this.errorChecker = validationChecker.find(item => item.checker && !item.checker(value));
this.errorLabel = _ref; this.errorLabel.setText(BI.get(this.errorChecker, 'errorText'));
this.isError = !!BI.get(this.errorChecker, 'errorText');
} else {
this.errorLabel.setText('');
this.isError = false;
}
if (!this.isError) {
this.value = value;
}
this.fireEvent(BI.Editor.EVENT_CHANGE);
},
}, {
eventName: BI.TextEditor.EVENT_BLUR,
action: () => {
if (BI.get(this.errorChecker, 'autoFix')) {
this.setValue(this.value);
this.errorLabel.setText('');
}
}, },
}],
},
}, {
el: {
type: Label,
cls: 'bi-error',
ref: (_ref: any) => {
this.errorLabel = _ref;
}, },
top: -15,
}, },
], top: -15,
}],
}; };
} }
@ -108,8 +95,4 @@ export class TextChecker extends BI.Widget {
public setError(value: string) { public setError(value: string) {
this.errorLabel.setText(value); this.errorLabel.setText(value);
} }
public setWatermark(value: string) {
this.textEditor.setWaterMark(value);
}
} }

41
src/modules/components/tips_combo/tips_combo.ts

@ -1,41 +0,0 @@
import { shortcut } from '@core/core';
import { BubbleCombo, BubblePopupView, IconButton } from '@fui/core';
@shortcut()
export class TipsCombo extends BI.Widget {
public static xtype = 'dec.dcm.tips.combo';
public props: BubblePopupView['props'] & IconButton['props'] = {
trigger: 'hover',
direction: 'top'
};
private bubbleCombo: BubbleCombo;
private bubbleComboPopup: BubblePopupView;
public render() {
const { direction, trigger, el } = this.options;
return {
type: BI.BubbleCombo.xtype,
trigger,
direction,
el: {
type: BI.IconButton.xtype,
cls: "detail-font",
},
popup: {
type: BI.BubblePopupView.xtype,
ref: (_ref: BubblePopupView) => {
this.bubbleComboPopup = _ref;
},
el,
},
listeners: [],
ref: (_ref: BubbleCombo) => {
this.bubbleCombo = _ref;
}
}
}
}

237
src/modules/constants/constant.ts

@ -1,3 +1,5 @@
import { CONSTANT_PLUGIN_TYPES } from '../app.constant';
export const PAGE_INDEX = { export const PAGE_INDEX = {
CONNECTION: 'connection', CONNECTION: 'connection',
DATEBASE: 'datebase', DATEBASE: 'datebase',
@ -5,15 +7,8 @@ export const PAGE_INDEX = {
POOL: 'pool', POOL: 'pool',
}; };
export const DATABASE_TYPE = {
SAP_HANA: "sap-hana",
STAR_ROCKS :'starrocks',
};
export const OTHER_JDBC = 'otherJDBC'; export const OTHER_JDBC = 'otherJDBC';
export const DEFAULT_HELP_LINK = 'databaseHelpLink';
export const JDBC_ODBC_DRIVER = 'sun.jdbc.odbc.JdbcOdbcDriver'; export const JDBC_ODBC_DRIVER = 'sun.jdbc.odbc.JdbcOdbcDriver';
export const JDBC_ODBC_DRIVER_HELP_LINK = DecCst && DecCst.Hyperlink ? DecCst.Hyperlink.Database.OTHER_ODBC : ''; export const JDBC_ODBC_DRIVER_HELP_LINK = DecCst && DecCst.Hyperlink ? DecCst.Hyperlink.Database.OTHER_ODBC : '';
@ -24,17 +19,17 @@ export const DATEBASE_FILTER_TYPE = {
}; };
export const DATA_BASE_TYPES_OTHER = export const DATA_BASE_TYPES_OTHER =
{ {
text: OTHER_JDBC, text: OTHER_JDBC,
databaseType: OTHER_JDBC, databaseType: OTHER_JDBC,
driver: '', driver: '',
url: '', url: '',
commonly: false, commonly: false,
internal: false, internal: false,
type: 'jdbc', type: 'jdbc',
hasSchema: true, hasSchema: true,
kerberos: false, kerberos: false,
}; };
export const DATA_BASE_DRIVER_LINK = DecCst && DecCst.Hyperlink ? [ export const DATA_BASE_DRIVER_LINK = DecCst && DecCst.Hyperlink ? [
{ {
databaseType: 'ads', databaseType: 'ads',
@ -50,7 +45,7 @@ export const DATA_BASE_DRIVER_LINK = DecCst && DecCst.Hyperlink ? [
}, },
{ {
databaseType: 'apache-kylin', databaseType: 'apache-kylin',
link: DecCst.Hyperlink.Database.KYLIN, link: DecCst.Hyperlink.Database.PHOENIX,
}, },
{ {
databaseType: 'apache-phoenix', databaseType: 'apache-phoenix',
@ -60,10 +55,6 @@ export const DATA_BASE_DRIVER_LINK = DecCst && DecCst.Hyperlink ? [
databaseType: 'derby', databaseType: 'derby',
link: DecCst.Hyperlink.Database.DERBY, link: DecCst.Hyperlink.Database.DERBY,
}, },
{
databaseType: 'clickhouse',
link: DecCst.Hyperlink.Database.CLICKHOUSE,
},
{ {
databaseType: 'gbase-8a', databaseType: 'gbase-8a',
link: DecCst.Hyperlink.Database.GBASE8A, link: DecCst.Hyperlink.Database.GBASE8A,
@ -104,10 +95,6 @@ export const DATA_BASE_DRIVER_LINK = DecCst && DecCst.Hyperlink ? [
databaseType: 'hbase', databaseType: 'hbase',
link: DecCst.Hyperlink.Database.HBASE, link: DecCst.Hyperlink.Database.HBASE,
}, },
{
databaseType: 'hologres',
link: DecCst.Hyperlink.Database.HOLOGRES,
},
{ {
databaseType: 'hp-vertica', databaseType: 'hp-vertica',
link: DecCst.Hyperlink.Database.VERTICA, link: DecCst.Hyperlink.Database.VERTICA,
@ -128,10 +115,6 @@ export const DATA_BASE_DRIVER_LINK = DecCst && DecCst.Hyperlink ? [
databaseType: 'kingbase', databaseType: 'kingbase',
link: DecCst.Hyperlink.Database.KINGBASE, link: DecCst.Hyperlink.Database.KINGBASE,
}, },
{
databaseType: 'kyligence',
link: DecCst.Hyperlink.Database.KYLIGENCE,
},
{ {
databaseType: 'sql-server', databaseType: 'sql-server',
link: DecCst.Hyperlink.Database.SQLSERVER, link: DecCst.Hyperlink.Database.SQLSERVER,
@ -140,10 +123,6 @@ export const DATA_BASE_DRIVER_LINK = DecCst && DecCst.Hyperlink ? [
databaseType: 'mysql', databaseType: 'mysql',
link: DecCst.Hyperlink.Database.MYSQL, link: DecCst.Hyperlink.Database.MYSQL,
}, },
{
databaseType: 'odps',
link: DecCst.Hyperlink.Database.ODPS,
},
{ {
databaseType: 'oracle', databaseType: 'oracle',
link: DecCst.Hyperlink.Database.ORACLE, link: DecCst.Hyperlink.Database.ORACLE,
@ -234,7 +213,7 @@ export const DATA_BASE_TYPES = [
{ {
text: 'Amazon Redshift', text: 'Amazon Redshift',
databaseType: 'amazon-redshift', databaseType: 'amazon-redshift',
driver: 'com.amazon.redshift.jdbc41.Driver', driver: 'com.amazon.redshift.jdbc4.Driver',
drivers: ['com.amazon.redshift.jdbc4.Driver', 'com.amazon.redshift.jdbc41.Driver'], drivers: ['com.amazon.redshift.jdbc4.Driver', 'com.amazon.redshift.jdbc41.Driver'],
url: 'jdbc:redshift://endpoint:port/database', url: 'jdbc:redshift://endpoint:port/database',
commonly: false, commonly: false,
@ -280,17 +259,6 @@ export const DATA_BASE_TYPES = [
hasSchema: true, hasSchema: true,
kerberos: true, kerberos: true,
}, },
{
text: 'ClickHouse',
databaseType: 'clickhouse',
driver: 'ru.yandex.clickhouse.ClickHouseDriver',
url: 'jdbc:clickhouse://hostname:port/database',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: true,
kerberos: false,
},
{ {
text: 'DERBY', text: 'DERBY',
databaseType: 'derby', databaseType: 'derby',
@ -372,7 +340,7 @@ export const DATA_BASE_TYPES = [
text: 'FusionInsight HD', text: 'FusionInsight HD',
databaseType: 'hw-fusioninsight-hd', databaseType: 'hw-fusioninsight-hd',
driver: 'org.apache.hive.jdbc.HiveDriver', driver: 'org.apache.hive.jdbc.HiveDriver',
url: 'jdbc:hive2://hostname1:port,hostname2:port,hostname3:port/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2;sasl.qop=auth-conf;auth=KERBEROS;zk.principal=zookeeper/hadoop;principal=hive/hadoop.hadoop.com@HADOOP.COM;', 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;',
commonly: false, commonly: false,
internal: true, internal: true,
type: 'jdbc', type: 'jdbc',
@ -409,16 +377,6 @@ export const DATA_BASE_TYPES = [
type: 'jdbc', type: 'jdbc',
hasSchema: true, hasSchema: true,
kerberos: true, kerberos: true,
}, {
text: 'Hologres',
databaseType: 'hologres',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/database',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: true,
kerberos: false,
}, { }, {
text: 'HP Vertica', text: 'HP Vertica',
databaseType: 'hp-vertica', databaseType: 'hp-vertica',
@ -449,7 +407,6 @@ export const DATA_BASE_TYPES = [
type: 'jdbc', type: 'jdbc',
hasSchema: true, hasSchema: true,
kerberos: false, kerberos: false,
fetchSize: 50,
}, { }, {
text: 'INFORMIX', text: 'INFORMIX',
databaseType: 'informix', databaseType: 'informix',
@ -464,23 +421,12 @@ export const DATA_BASE_TYPES = [
text: 'KINGBASE', text: 'KINGBASE',
databaseType: 'kingbase', databaseType: 'kingbase',
driver: 'com.kingbase.Driver', driver: 'com.kingbase.Driver',
versions: ['KingbaseES 7.0'],
url: 'jdbc:kingbase://hostname:port/database', url: 'jdbc:kingbase://hostname:port/database',
commonly: false, commonly: false,
internal: true, internal: true,
type: 'jdbc', type: 'jdbc',
hasSchema: true, hasSchema: true,
kerberos: false, kerberos: false,
}, {
text: 'Kyligence',
databaseType: 'kyligence',
driver: 'org.apache.kylin.jdbc.Driver',
url: 'jdbc:kylin://hostname:port/database',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: true,
kerberos: false,
}, { }, {
text: 'Microsoft SQL Server', text: 'Microsoft SQL Server',
databaseType: 'sql-server', databaseType: 'sql-server',
@ -507,17 +453,6 @@ export const DATA_BASE_TYPES = [
'org.gjt.mm.mysql.Driver': 'jdbc:mysql://hostname:port/database', 'org.gjt.mm.mysql.Driver': 'jdbc:mysql://hostname:port/database',
}, },
}, },
{
text: 'MaxCompute',
databaseType: 'odps',
driver: 'com.aliyun.odps.jdbc.OdpsDriver',
url: 'jdbc:odps:<maxcompute_endpoint>?project=<maxcompute_project_name>',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: true,
kerberos: false,
},
{ {
text: 'Oracle', text: 'Oracle',
databaseType: 'oracle', databaseType: 'oracle',
@ -528,7 +463,6 @@ export const DATA_BASE_TYPES = [
type: 'jdbc', type: 'jdbc',
hasSchema: true, hasSchema: true,
kerberos: false, kerberos: false,
fetchSize: 128,
}, },
{ {
text: 'Pivotal Greenplum Database', text: 'Pivotal Greenplum Database',
@ -543,7 +477,7 @@ export const DATA_BASE_TYPES = [
kerberos: false, kerberos: false,
urls: { urls: {
'org.postgresql.Driver': 'jdbc:postgresql://hostname:port/dbname', 'org.postgresql.Driver': 'jdbc:postgresql://hostname:port/dbname',
'com.pivotal.jdbc.GreenplumDriver': 'jdbc:pivotal:greenplum://hostname:port;DatabaseName=dbname', 'com.pivotal.jdbc.GreenplumDriver': 'jdbc:pivotal:greenplum://hostname:port;dbname',
}, },
}, { }, {
text: 'Postgresql', text: 'Postgresql',
@ -555,51 +489,6 @@ export const DATA_BASE_TYPES = [
type: 'jdbc', type: 'jdbc',
hasSchema: true, hasSchema: true,
kerberos: false, kerberos: false,
fetchSize: 10000,
}, {
text: 'Tidb',
databaseType: 'tidb',
driver: 'com.mysql.jdbc.Driver',
drivers: ['com.mysql.jdbc.Driver'],
url: 'jdbc:mysql://hostname:port/database',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: false,
kerberos: false,
}, {
text: 'Doris',
databaseType: 'doris',
driver: 'com.mysql.jdbc.Driver',
drivers: ['com.mysql.jdbc.Driver'],
url: 'jdbc:mysql://hostname:port/database',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: false,
kerberos: false,
}, {
text: BI.i18nText('Dec-Dcm_Connection_Database_DM'),
databaseType: 'dm',
driver: 'dm.jdbc.driver.DmDriver',
drivers: ['dm.jdbc.driver.DmDriver'],
url: 'jdbc:dm://hostname:port',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: true,
kerberos: true,
}, {
text: 'dremio',
databaseType: 'dremio',
driver: 'com.dremio.jdbc.Driver',
drivers: ['com.dremio.jdbc.Driver'],
url: 'jdbc:dremio:direct=hostname:31010',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: true,
kerberos: false,
}, { }, {
text: 'Presto', text: 'Presto',
databaseType: 'presto', databaseType: 'presto',
@ -614,7 +503,7 @@ export const DATA_BASE_TYPES = [
text: 'SAP HANA', text: 'SAP HANA',
databaseType: 'sap-hana', databaseType: 'sap-hana',
driver: 'com.sap.db.jdbc.Driver', driver: 'com.sap.db.jdbc.Driver',
url: 'jdbc:sap://hostname:port?databaseName=database&reconnect=true', url: 'jdbc:sap://hostname:port?reconnect=true',
commonly: false, commonly: false,
internal: true, internal: true,
type: 'jdbc', type: 'jdbc',
@ -698,48 +587,20 @@ export const DATA_BASE_TYPES = [
'org.sqlite.JDBC': 'jdbc:sqlite:[PATH_TO_DB_FILES]', 'org.sqlite.JDBC': 'jdbc:sqlite:[PATH_TO_DB_FILES]',
}, },
}, },
{ ...BI.Constants.getConstant(CONSTANT_PLUGIN_TYPES).map(item => {
text: 'trino', return {
databaseType: 'trino', ...item,
driver: 'io.trino.jdbc.TrinoDriver', internal: false,
url: 'jdbc:trino://hostname:port/database', commonly: false,
commonly: false, };
internal: true, }),
type: 'jdbc',
hasSchema: true,
kerberos: false,
},
{
text: 'TDSQL',
databaseType: 'tdsql',
driver: 'org.postgresql.Driver',
url: 'jdbc:postgresql://hostname:port/database',
versions: ['pgsql'],
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: true,
kerberos: false,
fetchSize: 10000,
},
{
text: BI.i18nText('StarRocks'),
databaseType: 'starrocks',
driver: 'com.mysql.jdbc.Driver',
drivers: ['com.mysql.jdbc.Driver'],
url: 'jdbc:mysql://hostname:port/default_catalog.database',
commonly: false,
internal: true,
type: 'jdbc',
hasSchema: false,
kerberos: false,
}
]; ];
export const CONNECT_CHARSET = [ export const CONNECT_CHARSET = [
{ {
text: BI.i18nText('Dec-Dcm_Connection_Form_Default'), text: BI.i18nText('Dec-Dcm_Connection_Form_Auto'),
value: '', value: '',
}, },
{ {
@ -776,28 +637,6 @@ export const CONNECT_CHARSET = [
}, },
]; ];
export const CONNECT_SSH_TYPE = [
{
text: BI.i18nText('Dec-Dcm_Connection_Form_Password'),
value: 'NORMAL',
privateKeyPathFormVisible: false,
secretFormName: BI.i18nText('Dec-Dcm_Connection_Form_Password'),
},
{
text: BI.i18nText('Dec-Dcm_Connection_Form_PublicKey'),
value: 'KEY',
privateKeyPathFormVisible: true,
secretFormName: BI.i18nText('Dec-Dcm_Connection_Form_Passphrase'),
},
];
export const CONNECT_SSL_TYPE = [
{
text: BI.i18nText('Dec-Dcm_Connection_Form_Password'),
value: 'NORMAL',
},
];
export const TEST_STATUS = { export const TEST_STATUS = {
LOADING: 'loading', LOADING: 'loading',
SUCCESS: 'success', SUCCESS: 'success',
@ -834,18 +673,15 @@ export const DEFAULT_JDBC_POOL = {
minIdle: 0, minIdle: 0,
maxWait: 10000, maxWait: 10000,
testOnBorrow: true, testOnBorrow: true,
keepAlive: true,
testOnReturn: false, testOnReturn: false,
testWhileIdle: false, testWhileIdle: false,
timeBetweenEvictionRunsMillis: 60000, timeBetweenEvictionRunsMillis: -1,
numTestsPerEvictionRun: 3, numTestsPerEvictionRun: 3,
minEvictableIdleTimeMillis: 1800, minEvictableIdleTimeMillis: 1800,
maxEvictableIdleTimeMillis: 25200,
keepAliveBetweenTimeMillis: 120000,
}; };
export const CONNECTION_LAYOUT = { export const CONNECTION_LAYOUT = {
hgap: 10, hgap: 5,
vgap: 15, vgap: 15,
labelHeight: 24, labelHeight: 24,
}; };
@ -853,10 +689,10 @@ export const CONNECTION_LAYOUT = {
export const JNDI_FACTORYS = [ export const JNDI_FACTORYS = [
{ {
factory: '', factory:'',
url: '', url: '',
}, { }, {
factory: 'weblogic.jndi.WLInitialContextFactory', factory:'weblogic.jndi.WLInitialContextFactory',
url: 't3://localhost:7001', url: 't3://localhost:7001',
}, { }, {
factory: 'com.ibm.websphere.naming.WsnInitialContextFactory', factory: 'com.ibm.websphere.naming.WsnInitialContextFactory',
@ -876,14 +712,3 @@ export const JNDI_FACTORYS = [
export const PAGE_SIZE = 50; export const PAGE_SIZE = 50;
export const INT_MAX_VALUE = 2147483647; export const INT_MAX_VALUE = 2147483647;
export const INT_MIN_VALUE = -2147483648; export const INT_MIN_VALUE = -2147483648;
export const YES_OR_NO = [
{
text: BI.i18nText('Dec-Basic_Yes'),
value: 1,
},
{
text: BI.i18nText('Dec-Basic_No'),
value: 0,
}
]

52
src/modules/core/checkIllegalStrings/checkIllegalStrings.ts

@ -1,52 +0,0 @@
/*
https://work.fineres.com/browse/REPORT-91724 用于参数统一校验
*/
import { ILLEGAL_STRINGS } from "./constant";
export type CheckResult = {
legal: boolean,
errorMsg: string,
}
export const CHECK_CORRECT: CheckResult = {
legal: true,
errorMsg: "",
};
/**
*
* @param value
*/
export function checkIllegalStrings(value: string): CheckResult {
// 后端传入的校验开关,如果没传,那也默认开启
const enabled = Dec.system.enableParameterVerify ?? true;
let result = CHECK_CORRECT;
if (enabled) {
// 关键字不区分大小写
ILLEGAL_STRINGS.every(s => {
const sIndex = value.toLowerCase().indexOf(s);
if (sIndex !== -1) {
result = {
legal: false,
errorMsg: `${BI.i18nText("Dec-Basic_Check_Illegal_Strings")}${value.substr(sIndex, s.length)}`,
};
return false;
}
return true;
});
return result;
}
return result;
}
export function checkIllegalStringsInWidgetAndShowError(widget: any) {
const value = widget.getValue();
const result = checkIllegalStrings(value);
if (!result.legal) {
widget.showError(result.errorMsg);
}
return result.legal;
}

15
src/modules/core/checkIllegalStrings/constant.ts

@ -1,15 +0,0 @@
/**
*
*/
export const ILLEGAL_STRINGS = [
"\"",
"<",
">",
"&",
"/script",
"javascript:",
"onblur",
"getruntime",
"processbuilder",
"java.lang.processimpl",
];

42
src/modules/core/core.ts

@ -1,3 +1,43 @@
type Constructor<T> = new(...args: any[]) => T; type Constructor<T> = new(...args: any[]) => T;
export const { shortcut, model, store, Model, provider } = BI.Decorators; export function shortcut(className: string) {
return function decorator<U>(Base: Constructor<U>): void {
BI.shortcut(className, Base);
};
}
export function store(modelName: string) {
return function decorator<U>(Base: Constructor<U>): void {
Base.prototype._store = () => BI.Models.getModel(modelName);
};
}
export function model(className: string) {
return function decorator<U>(Base: Constructor<U>): void {
BI.model(className, Base);
};
}
export class Model<U extends {context?: {[key: string]: any}} = {}> extends Fix.Model {
model: {[key in keyof U['context']]: U['context'][key]} & {[key in keyof ReturnType<this['state']>]: ReturnType<this['state']>[key]} & {[key in keyof this['computed']]: ReturnType<this['computed'][key]>} & {[key: string]: undefined};
store: this['actions'];
state(): {[key: string]: any} {
return {};
}
// context: Partial<keyof U['context']>;
context: string[];
actions:{[key: string]: (...args: any[]) => any};
// childContext: (keyof this['$$childContext'])[];
childContext: string[];
$$childContext: {[key in keyof this['computed']]: ReturnType<this['computed'][key]>} & {[key in keyof ReturnType<this['state']>]: ReturnType<this['state']>[key]};
computed: {[key: string]: () => any};
}

1
src/modules/core/index.ts

@ -1 +0,0 @@
export { checkIllegalStringsInWidgetAndShowError, checkIllegalStrings } from "./checkIllegalStrings/checkIllegalStrings"

50
src/modules/crud/api.ts

@ -1,12 +1,4 @@
import { import { Connection, TestRequest, ConnectionPoolType, SocketResult, ResultType } from './crud.typings';
Connection,
ConnectionLicInfo,
TestRequest,
ConnectionPoolType,
SocketResult,
ResultType,
checkDriverStatusParams,
} from './crud.typings';
export interface Api { export interface Api {
/** /**
@ -17,12 +9,7 @@ export interface Api {
/** /**
* *
*/ */
getConnectionList(): Promise<{ data?: Connection[] }>; getConnectionlist(): Promise<{data?: Connection[]}>;
/**
* lic限制信息
*/
getConnectionLicInfo(): Promise<{ data?: ConnectionLicInfo }>;
/** /**
* *
@ -47,27 +34,11 @@ export interface Api {
*/ */
testConnection(data: Connection): Promise<TestRequest>; testConnection(data: Connection): Promise<TestRequest>;
/**
*
*/
getDriverLoadPath(data: Connection): Promise<ResultType<string>>;
/**
*
* @param data
*/
checkDriverStatus(data: checkDriverStatusParams): Promise<ResultType<boolean>>;
/** /**
* *
* @param name * @param name
*/ */
getConnectionPool(name: string): Promise<{ data?: ConnectionPoolType }>; getConnectionPool(name: string): Promise<{data?: ConnectionPoolType}>;
/**
*
*/
getSimpleDriverList(): Promise<{ data?: any[] }>;
/** /**
* *
@ -95,19 +66,4 @@ export interface Api {
* *
*/ */
getCipher(password: string): string; getCipher(password: string): string;
/**
*
*/
getPlain(cipher: string): string;
/**
*
*/
getHyperlink(name: string): string;
/**
* JNDI数据库类型可用状态
*/
getJNDIDatabaseStatus(): Promise<{ data?: boolean }>;
} }

6
src/modules/crud/crud.service.ts

@ -15,7 +15,7 @@ export function requestGet(url: string, data?: any): Promise<ResultType> {
export function requestPost(url: string, data = {}): Promise<ResultType> { export function requestPost(url: string, data = {}): Promise<ResultType> {
return new Promise(resolve => { return new Promise(resolve => {
Dec.reqByEncrypt("POST", getFullUrl(url), data, re => { Dec.reqPost(getFullUrl(url), data, re => {
resolve(re); resolve(re);
}); });
}); });
@ -23,7 +23,7 @@ export function requestPost(url: string, data = {}): Promise<ResultType> {
export function requestDelete(url: string, data = {}) { export function requestDelete(url: string, data = {}) {
return new Promise(resolve => { return new Promise(resolve => {
Dec.reqByEncrypt("DELETE", getFullUrl(url), data, re => { Dec.reqDelete(getFullUrl(url), data, re => {
resolve(re); resolve(re);
}); });
}); });
@ -31,7 +31,7 @@ export function requestDelete(url: string, data = {}) {
export function requestPut(url: string, data = {}) { export function requestPut(url: string, data = {}) {
return new Promise(resolve => { return new Promise(resolve => {
Dec.reqByEncrypt("PUT", getFullUrl(url), data, re => { Dec.reqPut(getFullUrl(url), data, re => {
resolve(re); resolve(re);
}); });
}); });

243
src/modules/crud/crud.typings.d.ts vendored

@ -1,6 +1,3 @@
export interface CrudParams {
[key: string]: string | number | { [key: string]: any };
}
export interface CrudReqOpts { export interface CrudReqOpts {
url?: string; url?: string;
@ -13,116 +10,23 @@ export interface CrudReqOpts {
params?: CrudParams; params?: CrudParams;
} }
export interface ConnectionLicInfo { export interface CrudParams {
currentConnectionNum: number; [key: string]: string | number | { [key: string]: any };
maxConnectionNum: number;
}
export interface ConnectionPoolType {
maxActive: number;
maxIdle: number;
numActive: number;
numIdle: number;
} }
type ConnectionDataOfSSH = { export interface Connection {
usingSsh: boolean; // 使用SSH通道 connectionId: string;
sshIp: string; // 主机 connectionType: string;
sshPort: number; // 端口 connectionName: string;
sshUser: string; // 用户名 creator?: string;
redirectPort: number; connectionData: ConnectionJDBC | ConnectionJNDI | ConnectionPlugin | string;
redirectIp: string; privilegeDetailBeanList?: {
sshTimeOut: number; privilegeType: number;
sshKeepAlive: number; privilegeValue: number;
} & ( }[]
| {
sshType: 'NORMAL'; // 验证方法:密码
sshPrivateKeyPath: ''; // 没啥意义,该验证方法下为空字符串
sshSecret: string; // 密码
}
| {
sshType: 'KEY'; // 验证方法:公钥
sshPrivateKeyPath: string; // 私钥
sshSecret: string; // 密码短语
}
);
type ConnectionDataOfSSL = {
usingSsl: boolean; // 使用SSL通道
sslType: 'NORMAL'; // SSL类型,只有NORMAL一种
caCertificate: string; // CA证书
verifyCa: boolean; // 验证针对CA的服务器证书
sslClientPrivateKey: string; // 客户端密钥
sslClientCertificate: string; // 客户端证书
};
export interface ConnectionPoolJDBC {
/**
*
*/
initialSize?: number;
/**
*
*/
maxActive?: number;
/**
*
*/
maxIdle?: number;
/**
*
*/
minIdle?: number;
/**
*
*/
maxWait?: number;
/**
* sql查询
*/
validationQuery?: string;
/**
*
*/
testOnBorrow?: boolean;
/**
*
*/
keepAlive?: boolean;
/**
*
*/
testOnReturn?: boolean;
/**
*
*/
testWhileIdle?: boolean;
/**
* 线
*/
timeBetweenEvictionRunsMillis?: number;
/**
*
*/
numTestsPerEvictionRun?: number;
/**
*
*/
minEvictableIdleTimeMillis?: number;
/**
*
*/
maxEvictableIdleTimeMillis?: number;
/**
*
*/
keepAliveBetweenTimeMillis?: number;
} }
export type ConnectionJDBC = { export interface ConnectionJDBC {
/** /**
* *
*/ */
@ -136,10 +40,6 @@ export type ConnectionJDBC = {
* *
*/ */
driver: string; driver: string;
/**
*
*/
driverSource: 'default' | 'custom';
/** /**
* url * url
*/ */
@ -183,7 +83,7 @@ export type ConnectionJDBC = {
/** /**
* *
*/ */
port?: number | ''; port?: number|'';
/** /**
* *
*/ */
@ -204,59 +104,73 @@ export type ConnectionJDBC = {
* *
*/ */
keyPath?: string; keyPath?: string;
connectionPoolAttr: ConnectionPoolJDBC;
}
export interface ConnectionPoolJDBC {
/** /**
* krb5.conf文件 *
*/ */
krb5Path?: string; initialSize?: number;
/** /**
* fetchSize *
*/ */
fetchSize?: number; maxActive?: number;
/**
*
*/
maxIdle?: number;
/** /**
* id *
*/
minIdle?: number;
/**
*
*/ */
identity?: string; maxWait?: number;
/**
* sql查询
*/
validationQuery?: string;
connectionPoolAttr: ConnectionPoolJDBC;
/** /**
* *
*/ */
parallelLoad?: IParallelLoad; testOnBorrow?: boolean;
/** /**
* HDFS *
*/ */
hdfs?: { testOnReturn?: boolean;
/**
* HDFS地址
*/
hdfsAddress?: string;
};
} & ConnectionDataOfSSH & ConnectionDataOfSSL;
/**
*
*/
export interface IParallelLoad {
/** /**
* *
*/ */
serverAddress?: string; testWhileIdle?: boolean;
/** /**
* * 线
*/ */
serverAddressItems?: string[]; timeBetweenEvictionRunsMillis?: number;
/** /**
* *
*/ */
reuseTemporaryTable?: string; numTestsPerEvictionRun?: number;
/** /**
* *
*/ */
filePiecesLimit?: string; minEvictableIdleTimeMillis?: number;
}
export interface ConnectionJNDI {
jndiName: string;
/** /**
* *
*/ */
fileSizeLimit?: string originalCharsetName: string;
newCharsetName: string;
creator?: string;
contextHashtable: ContextHashtable;
} }
export interface ContextHashtable { export interface ContextHashtable {
@ -277,54 +191,33 @@ export interface ContextHashtable {
'java.naming.applet': string; 'java.naming.applet': string;
} }
export interface ConnectionJNDI {
jndiName: string;
/**
*
*/
originalCharsetName: string;
newCharsetName: string;
creator?: string;
contextHashtable: ContextHashtable;
}
export interface ConnectionPlugin { export interface ConnectionPlugin {
pluginType: 'json'; pluginType: 'json';
creator: ''; creator: '';
pluginData: any; pluginData: any;
} }
export interface Connection {
connectionId: string;
connectionType: string;
connectionName: string;
creator?: string;
connectionData: ConnectionJDBC | ConnectionJNDI | ConnectionPlugin | string;
privilegeDetailBeanList?: {
privilegeType: number;
privilegeValue: number;
}[];
}
export interface TestRequest { export interface TestRequest {
data?: string[]; data?: string[];
errorCode?: string; errorCode?: string;
errorMsg?: string; errorMsg?: string;
} }
export interface ConnectionPoolType {
maxActive: number;
maxIdle: number;
numActive: number;
numIdle: number;
}
export interface SocketResult { export interface SocketResult {
data?: string; data?: string;
errorCode?: string; errorCode?: string;
errorMsg?: string; errorMsg?: string;
} }
export interface ResultType<T = any> { export interface ResultType {
data?: T; data?: any;
errorCode?: string; errorCode?: string;
errorMsg?: string; errorMsg?: string;
} }
export type checkDriverStatusParams = {
path: string;
driver: ConnectionJDBC['driver'];
}

131
src/modules/crud/decision.api.ts

@ -1,19 +1,15 @@
import { Api } from './api'; import { Api } from './api';
import { Connection, TestRequest, ConnectionPoolType, SocketResult, ConnectionLicInfo, ResultType, checkDriverStatusParams } from './crud.typings'; import { Connection, TestRequest, ConnectionPoolType, SocketResult } from './crud.typings';
import { requestGet, requestDelete, requestPost, requestPut } from './crud.service'; import { requestGet, requestDelete, requestPost, requestPut } from './crud.service';
import { editStatusEvent, errorCode } from '@constants/env'; import { editStatusEvent, errorCode } from '@constants/env';
export class DecisionApi implements Api { export class DecisionApi implements Api {
isDec = true; isDec = true;
getConnectionList(): Promise<{ data?: Connection[] }> { getConnectionlist(): Promise<{data?: Connection[]}> {
return requestGet('list', {}); return requestGet('list', {});
} }
getConnectionLicInfo(): Promise<{ data?: ConnectionLicInfo }> {
return requestGet('lic/info', {});
}
deleteConnection(connectionName: string) { deleteConnection(connectionName: string) {
return requestDelete('', { return requestDelete('', {
connectionName, connectionName,
@ -24,87 +20,57 @@ export class DecisionApi implements Api {
const form = { const form = {
...data, ...data,
connectionId: data.connectionId || data.connectionName, connectionId: data.connectionId || data.connectionName,
connectionData: JSON.stringify(data.connectionData), connectionData : JSON.stringify(data.connectionData),
}; };
return requestPost('', form); return requestPost('', form);
} }
updateConnection(data: Connection) { updateConnection(data: Connection) {
const form = { const form = {
...data, ...data,
connectionData: JSON.stringify(data.connectionData), connectionData : JSON.stringify(data.connectionData),
}; };
return requestPut('', form); return requestPut('', form);
} }
testConnection(data: Connection): Promise<TestRequest> { testConnection(data: Connection): Promise<TestRequest> {
const form = { const form = {
...data, ...data,
connectionData: JSON.stringify(data.connectionData), connectionData : JSON.stringify(data.connectionData),
}; };
return requestPost('test', form); return requestPost('test', form);
} }
/** getConnectionPool(name: string): Promise<{data?: ConnectionPoolType}> {
*
* @returns
*/
getDriverLoadPath(data: Connection): Promise<ResultType<string>> {
const form = {
...data,
connectionData: JSON.stringify(data.connectionData),
};
return requestPost('driver/path', form);
}
/**
*
* @param data
*/
checkDriverStatus(data: checkDriverStatusParams): Promise<ResultType<boolean>> {
return requestGet(Dec.Utils.getEncodeURL('test/driver/conflict', '', data));
}
getConnectionPool(name: string): Promise<{ data?: ConnectionPoolType }> {
return requestGet(`pool/info?connectionName=${encodeURIComponent(name)}`, {}); return requestGet(`pool/info?connectionName=${encodeURIComponent(name)}`, {});
} }
getSimpleDriverList(): Promise<{ data: any[] }> {
return new Promise(resolve => {
Dec.reqGet('/v10/drivers/simple/list', '', re => {
resolve(re);
});
});
}
getConnectionStatus(name: string): Promise<SocketResult> { getConnectionStatus(name: string): Promise<SocketResult> {
return this.sendEditStatusEvent(name, editStatusEvent.OPEN) return this.sendEditStatusEvent(name, editStatusEvent.OPEN).then(re => {
.then(re => { if (re.errorCode) {
if (re.errorCode) { let errorMessage = '';
let errorMessage = ''; switch (re.errorCode) {
switch (re.errorCode) { case errorCode.CONNECTION_DELETED:
case errorCode.CONNECTION_DELETED: errorMessage = 'Dec-Dcm_Connection_Deleted';
errorMessage = 'Dec-Dcm_Connection_Deleted'; break;
break; case errorCode.CONNECTION_UNDER_EDIT:
case errorCode.CONNECTION_UNDER_EDIT: errorMessage = 'Dec-Dcm_Connection_Is_Using';
errorMessage = 'Dec-Dcm_Connection_Is_Using'; break;
break; default:
default: errorMessage = re.errorMsg;
errorMessage = re.errorMsg; break;
break;
}
BI.Msg.toast(BI.i18nText(errorMessage, re.errorMsg), {
level: 'error',
});
throw re;
} else {
return re;
} }
}); BI.Msg.toast(BI.i18nText(errorMessage, re.errorMsg), {
level: 'error',
});
throw re;
} else {
return re;
}
});
} }
shutdownConnectionStatus(name: string): Promise<SocketResult> { shutdownConnectionStatus(name: string): Promise<SocketResult> {
@ -115,7 +81,7 @@ export class DecisionApi implements Api {
if (Dec) { if (Dec) {
return Dec.socket.connected; return Dec.socket.connected;
} }
return false; return false;
} }
@ -123,43 +89,12 @@ export class DecisionApi implements Api {
if (Dec) { if (Dec) {
return DecCst.ErrorCode.LACK_DRIVER === errorCode; return DecCst.ErrorCode.LACK_DRIVER === errorCode;
} }
return false; return false;
} }
getCipher(password: string) { getCipher(password: string) {
return BI.Providers.getProvider('dec.provider.cipher') return BI.Providers.getProvider('dec.provider.cipher').getCipher(password);
.getCompleteCipher(password);
}
getPlain(cipher: string) {
return BI.Providers.getProvider('dec.provider.cipher')
.getCompletePlain(cipher);
}
getHyperlink(name: string) {
return Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][name];
}
changePrincipal(value: any) {
return requestPost(`switch/principal`, value);
}
getPrincipals(keytab: string) {
return requestGet(`/principals?keytabPath=${keytab}`, {});
}
getTimeOut(): Promise<{ data?: any }> {
return requestGet('kdc/timeout', {});
}
putTimeOut(value: number) {
return requestPut(`kdc/timeout?timeout=${value}`, {})
}
// 获取当前lic是否可以使用JNDI数据库类型
getJNDIDatabaseStatus(): Promise<{ data?: boolean }> {
return requestGet('databasetype/limit', {});
} }
private sendEditStatusEvent(name: string, type: string): Promise<SocketResult> { private sendEditStatusEvent(name: string, type: string): Promise<SocketResult> {

68
src/modules/crud/design.api.ts

@ -1,34 +1,29 @@
import { Api } from './api'; import { Api } from './api';
import { Connection, TestRequest, ConnectionPoolType, SocketResult, ConnectionLicInfo, ResultType, ConnectionJDBC, checkDriverStatusParams } from './crud.typings'; import { Connection, TestRequest, ConnectionPoolType, SocketResult } from './crud.typings';
import { requestGet } from './crud.service';
// TODO: 此页面的接口等待设计器提供相应的方法 // TODO: 此页面的接口等待设计器提供相应的方法
export class DesignApi implements Api { export class DesignApi implements Api {
isDec = false; isDec = false;
getConnectionList(): Promise<{ data: Connection[] }> { getConnectionlist(): Promise<{data: Connection[]}> {
return new Promise(resolve => { return new Promise(resolve => {
resolve({ data: [] }); resolve({ data: [] });
}); });
} }
getConnectionLicInfo(): Promise<{ data?: ConnectionLicInfo }> { deleteConnection(connectionName: string): Promise<{data: string}> {
return requestGet('lic/info', {});
}
deleteConnection(connectionName: string): Promise<{ data: string }> {
return new Promise(resolve => { return new Promise(resolve => {
resolve({ data: 'success' }); resolve({ data: 'success' });
}); });
} }
addConnection(data: Connection): Promise<{ data: string }> { addConnection(data: Connection): Promise<{data: string}> {
return new Promise(resolve => { return new Promise(resolve => {
resolve({ data: 'success' }); resolve({ data: 'success' });
}); });
} }
updateConnection(data: Connection): Promise<{ data: string }> { updateConnection(data: Connection): Promise<{data: string}> {
return new Promise(resolve => { return new Promise(resolve => {
resolve({ data: 'success' }); resolve({ data: 'success' });
}); });
@ -39,37 +34,14 @@ export class DesignApi implements Api {
}); });
} }
/** getConnectionPool(name: string): Promise<{data: ConnectionPoolType}> {
*
* @param name
* @returns
*/
getDriverLoadPath(data: Connection): Promise<ResultType<string>> {
return new Promise(resolve => { return new Promise(resolve => {
resolve({ data: '' }); resolve({ data: {
}); maxActive: 1,
} maxIdle: 1,
numActive: 1,
/** numIdle: 1,
* } });
* @param data
*/
checkDriverStatus(data: checkDriverStatusParams): Promise<ResultType<boolean>> {
return new Promise(resolve => {
resolve({ data: false });
});
}
getConnectionPool(name: string): Promise<{ data: ConnectionPoolType }> {
return new Promise(resolve => {
resolve({
data: {
maxActive: 1,
maxIdle: 1,
numActive: 1,
numIdle: 1,
}
});
}); });
} }
@ -99,18 +71,4 @@ export class DesignApi implements Api {
// 设计器加密方法 // 设计器加密方法
return password; return password;
} }
getPlain(cipher: string) {
// 设计器解密方法
return cipher;
}
getHyperlink(name: string) {
// 设计器获取超链
return '';
}
getJNDIDatabaseStatus() {
return Promise.resolve({ data: true });
}
} }

24
src/modules/pages/__point__/connect.point.ts

@ -1,24 +0,0 @@
BI.point("dec.dcm.model.connection", "createNewConnection", () => {
Dec.Utils.saveFocusPoint({
id: "E73325",
title: "新建数据连接",
});
});
BI.point("dec.dcm.model.title_maintain", "setTestEvent", () => {
Dec.Utils.saveFocusPoint({
id: "E73328",
title: "测试数据连接",
});
});
BI.point("dec.dcm.model.maintain_form", "addConnection", function () {
Dec.Utils.saveFocusPoint({
id: "E8827",
title: "保存数据连接",
body: {
datebaseType: this.model.datebaseTypeSelected,
databaseName: this.model.connectionSelected,
},
});
});

14
src/modules/pages/connection/components/form_item/form_item.ts

@ -1,8 +1,8 @@
import { shortcut } from '@core/core'; import { shortcut } from '@core/core';
import { Label, Htape, Vertical } from 'ui';
@shortcut() export const FormItemXtype = 'dec.dcm.connection_form_item';
@shortcut(FormItemXtype)
export class FormItem extends BI.Widget { export class FormItem extends BI.Widget {
static xtype = 'dec.dcm.connection_form_item';
props = { props = {
name: '', name: '',
value: '', value: '',
@ -16,12 +16,12 @@ export class FormItem extends BI.Widget {
const { nameWidth, unit, value } = this.options; const { nameWidth, unit, value } = this.options;
return { return {
type: BI.HTapeLayout.xtype, type: Htape,
height: 17, height: 17,
items: [ items: [
{ {
el: { el: {
type: BI.Label.xtype, type: Label,
cls: this.options.isBold ? 'bi-font-bold' : '', cls: this.options.isBold ? 'bi-font-bold' : '',
textAlign: 'left', textAlign: 'left',
text: this.options.name, text: this.options.name,
@ -29,10 +29,10 @@ export class FormItem extends BI.Widget {
width: nameWidth, width: nameWidth,
}, },
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
text: unit ? `${value} ${unit}` : value, text: unit ? `${value} ${unit}` : value,
textAlign: 'left', textAlign: 'left',
title: value, title: value,

61
src/modules/pages/connection/connection.model.ts

@ -1,50 +1,22 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { AppModel } from '../../app.model'; import { AppModel } from '../../app.model';
import { ApiFactory } from 'src/modules/crud/apiFactory'; import { ApiFactory } from 'src/modules/crud/apiFactory';
import { PAGE_INDEX } from '@constants/constant';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
export const ConnectionModelXtype = 'dec.dcm.model.connection';
@model() @model(ConnectionModelXtype)
export class ConnectionModel extends Model<{ export class ConnectionModel extends Model<{
types: { context : {
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
connections: AppModel['TYPE']['connections']; connections: AppModel['$$childContext']['connections'];
connectionSelected: AppModel['TYPE']['connectionSelected']; connectionSelected: AppModel['$$childContext']['connectionSelected'];
connectionSelectedOne: AppModel['TYPE']['connectionSelectedOne']; connectionSelectedOne: AppModel['$$childContext']['connectionSelectedOne'];
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
noTestConnection: AppModel['TYPE']['noTestConnection']; }
},
childContext: ConnectionModel['childContext'];
context: ConnectionModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection'; context = ['pageIndex', 'connectionSelected', 'connectionSelectedOne', 'datebaseTypeSelected'];
context = <const>['pageIndex', 'connectionSelected', 'connectionSelectedOne', 'datebaseTypeSelected', 'connectionLicInfo', 'noTestConnection'];
actions = { actions = {
initConnectionLicInfo: (cb: Function) => { setPageIndex:(index: string) => {
return api.getConnectionLicInfo()
.then(res => {
this.model.connectionLicInfo = res.data;
if (res.data.currentConnectionNum > res.data.maxConnectionNum) {
BI.Services.getService('dec.service.component.icon_text.msg').alert({
text: BI.i18nText('Dec-Connection_Lic_Limit_Approach_Tip', res.data.maxConnectionNum),
});
}
cb();
});
},
createNewConnection: () => {
if (this.model.connectionLicInfo.currentConnectionNum < this.model.connectionLicInfo.maxConnectionNum) {
this.setPageIndex(PAGE_INDEX.DATEBASE);
} else {
BI.Services.getService('dec.service.component.icon_text.msg').alert({
text: BI.i18nText('Dec-Connection_Lic_Limit_Approach_Prevent_Tip', this.model.connectionLicInfo.maxConnectionNum),
});
}
},
setPageIndex: (index: string) => {
this.model.pageIndex = index; this.model.pageIndex = index;
}, },
setDatebaseTypeSelected(name: string) { setDatebaseTypeSelected(name: string) {
@ -54,16 +26,7 @@ export class ConnectionModel extends Model<{
this.model.connectionSelected = name; this.model.connectionSelected = name;
}, },
getConnectionStatus() { getConnectionStatus() {
if (this.model.connectionSelectedOne.pluginConnection) {
return Promise.resolve();
}
return api.getConnectionStatus(this.model.connectionSelected); return api.getConnectionStatus(this.model.connectionSelected);
}, },
setNoTestConnection(value: boolean) { }
this.model.noTestConnection = value;
},
checkConnectionLic() {
return this.model.connectionLicInfo.currentConnectionNum > this.model.connectionLicInfo.maxConnectionNum;
},
};
} }

196
src/modules/pages/connection/connection.ts

@ -1,96 +1,78 @@
import { Button, Htape, Vtape, Label, VerticalAdapt, ListView, CenterAdapt, Layout } from 'ui';
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { ConnectionModel } from './connection.model'; import { ConnectionModel, ConnectionModelXtype } from './connection.model';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { ConnectionList } from './list/list'; import { ConnectionListXtype } from './list/list';
import { ConnectionJdbc } from './connection_jdbc/connection_jdbc'; import { ConnectionJdbcXtype } from './connection_jdbc/connection_jdbc';
import { ConnectionJndi } from './connection_jndi/connection_jndi'; import { ConnectionJndiXtype } from './connection_jndi/connection_jndi';
import { ConnectionPlugin } from './connection_plugin/connection_plugin'; import { ConnectionPluginXtype } from './connection_plugin/connection_plugin';
import { connectionType } from '@constants/env'; import { connectionType } from '@constants/env';
import { getAllDatabaseTypes, connectionCanEdit, getJdbcDatabaseType, getTextByDatabaseType } from '../../app.service'; import { getAllDatabaseTypes, connectionCanEdit, getJdbcDatabaseType, getTextByDatabaseType } from '../../app.service';
import { ConnectionJDBC } from '../../crud/crud.typings'; import { ConnectionJDBC } from '../../crud/crud.typings';
import { Button, HTapeLayout, Label, ListView } from '@fui/core';
@shortcut() export const ConnectionXtype = 'dec.dcm.connection';
@store(ConnectionModel) @shortcut(ConnectionXtype)
@store(ConnectionModelXtype)
export class Connection extends BI.Widget { export class Connection extends BI.Widget {
static xtype = 'dec.dcm.connection';
store: ConnectionModel['store']; store: ConnectionModel['store'];
model: ConnectionModel['model']; model: ConnectionModel['model'];
connectionTitleWidget: Label; connectionTitleWidget: any;
connectionEditWidget: Button; connectionEditWidget: any;
listView: ListView; listView: any;
title: HTapeLayout; title: any;
watch = { watch = {
connectionSelectedOne: { connectionSelected:(name: string) => {
immediate: true, if (name) {
handler: (v: Connection) => { const canEdit = connectionCanEdit(this.model.connectionSelectedOne);
BI.nextTick(() => { const type = this.getSelectConnectionType();
const connectionName = v.connectionName; this.connectionTitleWidget.setText(`${name}${getTextByDatabaseType(type)}`);
this.connectionEditWidget.setVisible(canEdit);
connectionName const hasRegistered = this.hasRegistered();
? this.renderConnectionListView(connectionName) this.title.setVisible(hasRegistered);
: this.renderEmptyListView(); if (!hasRegistered) {
}); this.listView.populate(BI.createItems(this.renderNoRegistered()));
}, } else {
this.listView.populate(BI.createItems(this.renderItems()));
}
} else {
this.listView.populate(BI.createItems(this.renderEmpty()));
this.connectionTitleWidget.setText('');
this.connectionEditWidget.setVisible(false);
}
}, },
};
beforeRender(cb: Function) {
this.store.initConnectionLicInfo(cb);
} }
render() { render() {
this.store.setConnectionSelected('');
return { return {
type: BI.HTapeLayout.xtype, type: Htape,
hgap: 10, hgap: 10,
items: [ items: [
{ {
el: { el: {
type: BI.VTapeLayout.xtype, type: Vtape,
cls: 'bi-border-right', cls: 'bi-border-right',
rgap: 10, rgap: 10,
items: [ items: [
{ {
el: { el: {
type: BI.LeftRightVerticalAdaptLayout.xtype, type: VerticalAdapt,
cls: 'bi-border-bottom', cls: 'bi-border-bottom',
items: { items: [{
left: [ type: Button,
{ text: BI.i18nText('Dec-Dcm_Connection_New'),
type: BI.Button.xtype, handler: () => {
text: BI.i18nText('Dec-Dcm_Connection_New'), this.store.setPageIndex(PAGE_INDEX.DATEBASE);
title: BI.i18nText('Dec-Dcm_Connection_New'), },
minWidth: 0, }],
width: 98,
handler: () => {
this.store.createNewConnection();
},
},
],
right: [
{
type: 'dec.connection.driver.entry',
invisible: !BI.Services.getService('dec.service.global').isAdmin(),
from: '.dec-dcm',
listeners: [
{
eventName: 'EVENT_CLOSE',
action: () => {
this.reset();
},
},
],
},
],
},
}, },
height: 40, height: 40,
}, },
{ {
type: ConnectionList.xtype, type: ConnectionListXtype,
tgap: 10, tgap: 10,
}, },
], ],
@ -98,55 +80,52 @@ export class Connection extends BI.Widget {
width: 275, width: 275,
}, },
{ {
type: BI.VTapeLayout.xtype, type: Vtape,
items: [ items: [
{ {
el: { el: {
type: BI.HTapeLayout.xtype, type: Htape,
ref: (_ref: HTapeLayout) => { ref: (_ref: any) => {
this.title = _ref; this.title = _ref;
}, },
cls: 'bi-border-bottom', cls: 'bi-border-bottom',
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
textAlign: 'left', textAlign: 'left',
ref: (_ref: Label) => { ref: (_ref: any) => {
this.connectionTitleWidget = _ref; this.connectionTitleWidget = _ref;
}, },
}, },
{ {
el: { el: {
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
items: [{ items: [{
type: BI.Button.xtype, type: Button,
$value: 'connection-edit', $value: 'connection-edit',
invisible: true, invisible: true,
text: BI.i18nText('Dec-Dcm_Edit'), text: BI.i18nText('Dec-Dcm_Edit'),
ref: (_ref: Button) => { ref: (_ref: any) => {
this.connectionEditWidget = _ref; this.connectionEditWidget = _ref;
}, },
handler: () => { handler: () => {
this.store.getConnectionStatus() this.store.getConnectionStatus().then(re => {
.then(() => { this.store.setPageIndex(PAGE_INDEX.MAINTAIN);
const databaseType = this.model.connectionSelectedOne.connectionType; this.store.setDatebaseTypeSelected('');
const database = BI.find(getAllDatabaseTypes(), (_index, value) => value.databaseType === databaseType); })
this.setMaintainPage(); .catch(() => {});
this.store.setNoTestConnection(database.isHideConnection);
})
.catch(() => {
});
}, },
}], }],
}, },
width: 90,
}, },
], ],
}, },
height: 40, height: 40,
}, },
{ {
type: BI.ListView.xtype, type: ListView,
ref: (_ref: ListView) => { ref: (_ref: any) => {
this.listView = _ref; this.listView = _ref;
}, },
}, },
@ -164,38 +143,38 @@ export class Connection extends BI.Widget {
switch (this.model.connectionSelectedOne.connectionType) { switch (this.model.connectionSelectedOne.connectionType) {
case connectionType.JDBC: case connectionType.JDBC:
return [{ return [{
type: ConnectionJdbc.xtype, type: ConnectionJdbcXtype,
}]; }];
case connectionType.JNDI: case connectionType.JNDI:
return [{ return [{
type: ConnectionJndi.xtype, type: ConnectionJndiXtype,
}]; }];
default: default:
return [{ return [{
type: ConnectionPlugin.xtype, type: ConnectionPluginXtype,
}]; }];
} }
} }
private renderNoRegistered() { private renderNoRegistered() {
return [{ return [{
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
height: 500, height: 500,
items: [ items: [
{ {
type: BI.VTapeLayout.xtype, type: Vtape,
width: 300, width: 300,
height: 150, height: 150,
items: [ items: [
{ {
el: { el: {
type: BI.Layout.xtype, type: Layout,
cls: 'error-page-background', cls: 'error-page-background',
}, },
height: 130, height: 130,
}, },
{ {
type: BI.Label.xtype, type: Label,
cls: 'bi-tips', cls: 'bi-tips',
text: BI.i18nText('Dec-Dcm_Connection_Np_Registered'), text: BI.i18nText('Dec-Dcm_Connection_Np_Registered'),
}, },
@ -205,6 +184,12 @@ export class Connection extends BI.Widget {
}]; }];
} }
private renderEmpty() {
return [{
type: Layout,
}];
}
private hasRegistered() { private hasRegistered() {
const allDatabaseTypes = getAllDatabaseTypes(); const allDatabaseTypes = getAllDatabaseTypes();
switch (this.model.connectionSelectedOne.connectionType) { switch (this.model.connectionSelectedOne.connectionType) {
@ -223,40 +208,7 @@ export class Connection extends BI.Widget {
const connectionJDBC = this.model.connectionSelectedOne.connectionData as ConnectionJDBC; const connectionJDBC = this.model.connectionSelectedOne.connectionData as ConnectionJDBC;
databaseType = getJdbcDatabaseType(connectionJDBC.database, connectionJDBC.driver).databaseType; databaseType = getJdbcDatabaseType(connectionJDBC.database, connectionJDBC.driver).databaseType;
} }
return databaseType; return databaseType;
} }
private setMaintainPage() {
this.store.setPageIndex(PAGE_INDEX.MAINTAIN);
this.store.setDatebaseTypeSelected('');
}
private renderConnectionListView(name: string) {
const canEdit = connectionCanEdit(this.model.connectionSelectedOne),
type = this.getSelectConnectionType(),
hasRegistered = this.hasRegistered();
this.connectionTitleWidget.setText(`${name}${getTextByDatabaseType(type)}`);
this.connectionEditWidget.setVisible(canEdit);
this.title.setVisible(hasRegistered);
hasRegistered
? this.listView.populate(BI.createItems(this.renderItems()))
: this.listView.populate(BI.createItems(this.renderNoRegistered()));
}
private renderEmptyListView() {
this.listView.populate(
BI.createItems([
{
type: BI.Layout.xtype,
}
])
);
this.connectionTitleWidget.setText('');
this.connectionEditWidget.setVisible(false);
}
} }

16
src/modules/pages/connection/connection_jdbc/connection_jdbc.model.ts

@ -1,13 +1,11 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { AppModel } from '../../../app.model'; import { ConnectionModel } from '../connection.model';
export const ConnectionJdbcModelXtype = 'dec.dcm.model.connection_jdbc';
@model() @model(ConnectionJdbcModelXtype)
export class ConnectionJdecModel extends Model<{ export class ConnectionJdecModel extends Model<{
types : { context : {
connectionSelectedOne: AppModel['TYPE']['connectionSelectedOne']; connectionSelectedOne: ConnectionModel['$$childContext']['connectionSelectedOne'];
}, }
context: ConnectionJdecModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection_jdbc'; context = ['connectionSelectedOne'];
context = <const>['connectionSelectedOne'];
} }

579
src/modules/pages/connection/connection_jdbc/connection_jdbc.ts

@ -1,405 +1,174 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { FormItem } from '../components/form_item/form_item'; import { Vertical, Layout } from 'ui';
import { Collapse, EVENT_CHANGE } from 'src/modules/components/collapse/collapse'; import { FormItemXtype } from '../components/form_item/form_item';
import { ConnectionJdecModel } from './connection_jdbc.model'; import { CollapseXtype, EVENT_CHANGE } from 'src/modules/components/collapse/collapse';
import { ConnectionJDBC } from 'src/modules/crud/crud.typings'; import { ConnectionJdbcModelXtype, ConnectionJdecModel } from './connection_jdbc.model';
import { getAllDatabaseTypes, getJdbcDatabaseType, resolveUrlInfo } from '../../../app.service'; import { ConnectionJDBC } from 'src/modules/crud/crud.typings';
import { CONNECTION_LAYOUT, CONNECT_SSH_TYPE } from '@constants/constant'; import { getAllDatabaseTypes, getJdbcDatabaseType, resolveUrlInfo } from '../../../app.service';
import { VerticalLayout } from '@fui/core'; import { CONNECTION_LAYOUT } from '@constants/constant';
import { ApiFactory } from '../../../crud/apiFactory'; export const ConnectionJdbcXtype = 'dec.dcm.connection_jdbc';
@shortcut(ConnectionJdbcXtype)
const api = new ApiFactory().create(); @store(ConnectionJdbcModelXtype)
export class ConnectionJdbc extends BI.Widget {
@shortcut() advancedSet: any;
@store(ConnectionJdecModel)
export class ConnectionJdbc extends BI.Widget { model: ConnectionJdecModel['model'];
static xtype = 'dec.dcm.connection_jdbc'; allDatabaseTypes = getAllDatabaseTypes();
model: ConnectionJdecModel['model']; render () {
allDatabaseTypes = getAllDatabaseTypes(); const connectionData = this.model.connectionSelectedOne.connectionData as ConnectionJDBC;
const { driver, database, user, originalCharsetName, schema, connectionPoolAttr, authType, principal, url } = connectionData;
sshSet: VerticalLayout; const databaseType = getJdbcDatabaseType(database, driver);
sslSet: VerticalLayout; const { host, port, databaseName } = resolveUrlInfo(url);
advancedSet: VerticalLayout; const { hgap, vgap } = CONNECTION_LAYOUT;
parallelLoadSet: VerticalLayout;
return {
render() { type: Vertical,
const connectionData = this.model.connectionSelectedOne.connectionData as ConnectionJDBC; hgap,
const { vgap,
driver, items: [
driverSource, {
database, type: FormItemXtype,
user, name: BI.i18nText('Dec-Dcm_Connection_Form_Driver'),
originalCharsetName, value: driver,
schema, },
connectionPoolAttr, {
authType, type: FormItemXtype,
principal, name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Name'),
url, value: databaseName,
fetchSize, },
// ssh {
usingSsh, type: FormItemXtype,
sshIp, name: BI.i18nText('Dec-Dcm_Connection_Form_Host'),
sshPort, value: host,
sshUser, },
sshType, {
sshSecret, type: FormItemXtype,
sshPrivateKeyPath, name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Port'),
// ssl value: port,
usingSsl, },
caCertificate, authType ?
verifyCa, {
sslClientPrivateKey, type: FormItemXtype,
sslClientCertificate, name: BI.i18nText('Dec-Dcm_Connection_Form_AuthType'),
// 并行装载 value: authType,
parallelLoad, } : {
// HDFS type: Layout,
hdfs, },
} = connectionData; {
const databaseType = getJdbcDatabaseType(database, driver); type: FormItemXtype,
const { host, port, catalog, databaseName, version } = resolveUrlInfo(url, database); name: authType ? BI.i18nText('Dec-Dcm_Connection_Form_Principal') : BI.i18nText('Dec-Dcm_Connection_Form_UserName'),
this.version = !BI.isUndefined(databaseType.versions) ? (version ?? databaseType.versions[0]) : version; value: authType ? principal : user,
const { hgap, vgap } = CONNECTION_LAYOUT; },
{
return { type: FormItemXtype,
type: BI.VerticalLayout.xtype, name: authType ? BI.i18nText('Dec-Dcm_Connection_Form_KeyPath') : BI.i18nText('Dec-Dcm_Connection_Form_Password'),
hgap, value: '******',
vgap, },
items: [ {
{ type: FormItemXtype,
type: FormItem.xtype, name: BI.i18nText('Dec-Dcm_Connection_Form_OriginalCharsetName'),
name: BI.i18nText('Dec-Basic_Version'), value: originalCharsetName ? originalCharsetName : BI.i18nText('Dec-Dcm_Connection_Form_Auto'),
invisible: BI.isUndefined(this.version), },
value: BI.i18nText('Dec-Migration_Database_Version', this.version), {
}, type: FormItemXtype,
{ name: BI.i18nText('Dec-Dcm_Connection_Form_Pattern'),
type: FormItem.xtype, value: schema,
_tgap: BI.isUndefined(this.version) ? vgap : 0, invisible: !databaseType.hasSchema,
name: BI.i18nText('Dec-Dcm_Connection_Form_Driver'), },
value: BI.isKey(driverSource) ? `${driver} (${driverSource})` : driver, {
}, type: FormItemXtype,
{ name: BI.i18nText('Dec-Dcm_Connection_Form_Database_URL'),
type: FormItem.xtype, value: url,
name: 'catalog', },
invisible: database !== 'starrocks', {
value: catalog, type: CollapseXtype,
}, width: 70,
{ name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Advanced_Setting'),
type: FormItem.xtype, listeners: [
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Name'), {
value: databaseName, eventName: EVENT_CHANGE,
}, action: (isCollapse: boolean) => {
{ this.advancedSet.setVisible(!isCollapse);
type: FormItem.xtype, },
name: BI.i18nText('Dec-Dcm_Connection_Form_Host'), },
value: host, ],
}, },
{ {
type: FormItem.xtype, type: Vertical,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Port'), tgap: -15,
value: port, vgap,
}, invisible: true,
authType ref: (_ref: any) => {
? { this.advancedSet = _ref;
type: FormItem.xtype, },
name: BI.i18nText('Dec-Dcm_Connection_Form_AuthType'), items: [
value: authType, {
} type: FormItemXtype,
: { name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Initial_Size'),
type: BI.Layout.xtype, value: connectionPoolAttr.initialSize,
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: authType ? BI.i18nText('Dec-Dcm_Connection_Form_Principal') : BI.i18nText('Dec-Dcm_Connection_Form_UserName'), name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Max_Active'),
value: authType ? principal : user, value: connectionPoolAttr.maxActive,
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: authType ? BI.i18nText('Dec-Dcm_Connection_Form_KeyPath') : BI.i18nText('Dec-Dcm_Connection_Form_Password'), name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Max_Idle'),
value: '******', value: connectionPoolAttr.maxIdle,
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_OriginalCharsetName'), name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Min_Idle'),
value: originalCharsetName ? originalCharsetName : BI.i18nText('Dec-Dcm_Connection_Form_Default'), value: connectionPoolAttr.minIdle,
}, },
// HDFS设置 {
{ type: FormItemXtype,
type: FormItem.xtype, name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Max_Wait'),
invisible: BI.isNull(hdfs), value: connectionPoolAttr.maxWait,
name: BI.i18nText('Dec-Dcm_Connection_Address', 'HDFS'), unit: BI.i18nText('Dec-Dcm_Millisecond'),
value: hdfs?.hdfsAddress, },
}, {
// 并行装载设置 type: FormItemXtype,
{ name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Validation_Query'),
type: Collapse.xtype, value: connectionPoolAttr.validationQuery,
invisible: BI.isNull(parallelLoad), },
name: BI.i18nText('Dec-Dcm_Connection_Setting', BI.i18nText('Dec-Dcm_Connection_Parallel_Load')), {
listeners: [ type: FormItemXtype,
{ name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_On_Borrow'),
eventName: EVENT_CHANGE, value: connectionPoolAttr.testOnBorrow ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
action: (isCollapse: boolean) => { },
this.parallelLoadSet.setVisible(!isCollapse); {
}, type: FormItemXtype,
}, name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_On_Return'),
], value: connectionPoolAttr.testOnReturn ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
}, },
{ {
type: BI.VerticalLayout.xtype, type: FormItemXtype,
invisible: true, name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_While_Idle'),
ref: (_ref: VerticalLayout) => { value: connectionPoolAttr.testWhileIdle ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
this.parallelLoadSet = _ref; },
}, {
items: [ type: FormItemXtype,
{ name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_Between_Eviction_Millis'),
type: FormItem.xtype, value: connectionPoolAttr.timeBetweenEvictionRunsMillis,
_bgap: vgap, unit: BI.i18nText('Dec-Dcm_Millisecond'),
name: `${BI.i18nText('Dec-Dcm_Connection_Server_Address')}-${BI.i18nText('Dec-Memory_Detection_Server_Cluster_Node', '1')}`, },
value: parallelLoad?.serverAddress, {
}, type: FormItemXtype,
{ name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Tests_PerEviction_Run_Num'),
type: FormItem.xtype, value: connectionPoolAttr.numTestsPerEvictionRun,
_bgap: vgap, },
name: BI.i18nText('Dec-Dcm_Connection_Reuse_Temporary_Table'), {
value: parallelLoad?.reuseTemporaryTable, type: FormItemXtype,
}, name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Min_Evictable_Idle_Time_Millis'),
{ value: connectionPoolAttr.minEvictableIdleTimeMillis,
type: FormItem.xtype, unit: BI.i18nText('BI-Basic_Seconds'),
_bgap: vgap, },
name: BI.i18nText('Dec-Dcm_Connection_Temporary_File_Pieces_Limit'), ],
value: parallelLoad?.filePiecesLimit, },
}, ],
{ };
type: FormItem.xtype, }
name: BI.i18nText('Dec-Dcm_Connection_Temporary_File_Size_Limit'), }
value: parallelLoad?.fileSizeLimit,
},
],
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Pattern'),
value: schema,
invisible: !databaseType.hasSchema,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_URL'),
value: url,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Max_Active'),
value: connectionPoolAttr.maxActive,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_On_Borrow'),
value: connectionPoolAttr.testOnBorrow ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Regular_Check_On_Borrow'),
value: connectionPoolAttr.keepAlive ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_SQL_Validation_Query'),
value: api.getPlain(connectionPoolAttr.validationQuery || ''),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Max_Wait'),
value: connectionPoolAttr.maxWait,
unit: BI.i18nText('Dec-Dcm_Millisecond'),
},
// ssh设置
{
type: Collapse.xtype,
width: 100,
invisible: !usingSsh,
name: BI.i18nText('Dec-Dcm_Connection_Setting', 'SSH'),
listeners: [
{
eventName: EVENT_CHANGE,
action: (isCollapse: boolean) => {
this.sshSet.setVisible(!isCollapse);
},
},
],
},
{
el: {
type: BI.VerticalLayout.xtype,
bgap: vgap,
invisible: true,
ref: (_ref: VerticalLayout) => {
this.sshSet = _ref;
},
items: [
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Host'),
value: sshIp,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Port'),
value: sshPort,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_UserName'),
value: sshUser,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_VerifyType'),
value: CONNECT_SSH_TYPE.find((SSH_TYPE) => sshType === SSH_TYPE.value).text,
},
{
type: FormItem.xtype,
invisible: sshType !== 'KEY',
name: BI.i18nText('Dec-Dcm_Connection_Form_PrivateKey'),
value: sshPrivateKeyPath,
},
{
type: FormItem.xtype,
name: CONNECT_SSH_TYPE.find((SSH_TYPE) => sshType === SSH_TYPE.value).secretFormName,
value: sshSecret,
},
],
},
},
// ssl设置
{
type: Collapse.xtype,
width: 100,
invisible: !usingSsl,
name: BI.i18nText('Dec-Dcm_Connection_Setting', 'SSL'),
listeners: [
{
eventName: EVENT_CHANGE,
action: (isCollapse: boolean) => {
this.sslSet.setVisible(!isCollapse);
},
},
],
},
{
el: {
type: BI.VerticalLayout.xtype,
bgap: vgap,
invisible: true,
ref: (_ref: VerticalLayout) => {
this.sslSet = _ref;
},
items: [
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_CA_Certificate'),
value: caCertificate,
},
{
type: FormItem.xtype,
invisible: !caCertificate,
name: BI.i18nText('Dec-Dcm_Connection_Form_Verify_CA_Certificate'),
value: verifyCa ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Client') + BI.i18nText('Dec-Dcm_Connection_Form_SecretKey'),
value: sslClientPrivateKey,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Client') + BI.i18nText('Dec-Dcm_Connection_Form_Certificate'),
value: sslClientCertificate,
},
],
},
},
// 更多设置
{
type: Collapse.xtype,
width: 100,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_More_Setting'),
listeners: [
{
eventName: EVENT_CHANGE,
action: (isCollapse: boolean) => {
this.advancedSet.setVisible(!isCollapse);
},
},
],
},
{
el: {
type: BI.VerticalLayout.xtype,
bgap: vgap,
invisible: true,
ref: (_ref: VerticalLayout) => {
this.advancedSet = _ref;
},
items: [
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Initial_Size'),
value: connectionPoolAttr.initialSize,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Min_Idle'),
value: connectionPoolAttr.minIdle,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_On_Return'),
value: connectionPoolAttr.testOnReturn ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_While_Idle'),
value: connectionPoolAttr.testWhileIdle ? BI.i18nText('Dec-Dcm_Yes') : BI.i18nText('Dec-Dcm_No'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Test_Between_Eviction_Millis'),
value: connectionPoolAttr.timeBetweenEvictionRunsMillis,
unit: BI.i18nText('Dec-Dcm_Millisecond'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Tests_PerEviction_Run_Num'),
value: connectionPoolAttr.numTestsPerEvictionRun,
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Min_Evictable_Idle_Time_Millis'),
value: connectionPoolAttr.minEvictableIdleTimeMillis,
unit: BI.i18nText('BI-Basic_Seconds'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Max_Evictable_Idle_Time_Millis'),
value: connectionPoolAttr.maxEvictableIdleTimeMillis,
unit: BI.i18nText('BI-Basic_Seconds'),
},
{
type: FormItem.xtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Regular_Check_On_Borrow_Threshold'),
value: connectionPoolAttr.keepAliveBetweenTimeMillis,
unit: BI.i18nText('Dec-Dcm_Millisecond'),
},
{
type: FormItem.xtype,
name: 'Fetchsize',
value: fetchSize,
},
],
},
},
],
};
}
}

15
src/modules/pages/connection/connection_jndi/connection_jndi.model.ts

@ -1,12 +1,11 @@
import { AppModel } from 'src/modules/app.model';
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
@model() import { ConnectionModel } from '../connection.model';
export const ConnectionJndiModelXtype = 'dec.dcm.model.connection_jndi';
@model(ConnectionJndiModelXtype)
export class ConnectionJndiModel extends Model<{ export class ConnectionJndiModel extends Model<{
types : { context : {
connectionSelectedOne: AppModel['TYPE']['connectionSelectedOne']; connectionSelectedOne: ConnectionModel['$$childContext']['connectionSelectedOne'];
}, }
context: ConnectionJndiModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection_jndi'; context = ['connectionSelectedOne'];
context = <const>['connectionSelectedOne'];
} }

73
src/modules/pages/connection/connection_jndi/connection_jndi.ts

@ -1,47 +1,46 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { FormItem } from '../components/form_item/form_item'; import { Vertical, Htape, Label, Left } from 'ui';
import { ConnectionJndiModel } from './connection_jndi.model'; import { FormItemXtype } from '../components/form_item/form_item';
import { ConnectionJndiModelXtype, ConnectionJndiModel } from './connection_jndi.model';
import { ConnectionJNDI } from 'src/modules/crud/crud.typings'; import { ConnectionJNDI } from 'src/modules/crud/crud.typings';
import { Collapse, EVENT_CHANGE } from 'src/modules/components/collapse/collapse'; import { CollapseXtype, EVENT_CHANGE } from 'src/modules/components/collapse/collapse';
import { CONNECTION_LAYOUT } from '@constants/constant'; import { CONNECTION_LAYOUT } from '@constants/constant';
import { VerticalLayout } from '@fui/core';
@shortcut()
@store(ConnectionJndiModel)
export class ConnectionJndi extends BI.Widget {
static xtype = 'dec.dcm.connection_jndi';
export const ConnectionJndiXtype = 'dec.dcm.connection_jndi';
@shortcut(ConnectionJndiXtype)
@store(ConnectionJndiModelXtype)
export class ConnectionJdbc extends BI.Widget {
model: ConnectionJndiModel['model']; model: ConnectionJndiModel['model'];
advancedSet: VerticalLayout; advancedSet: any;
render() { render() {
const connectionData = this.model.connectionSelectedOne.connectionData as ConnectionJNDI; const connectionData = this.model.connectionSelectedOne.connectionData as ConnectionJNDI;
const { jndiName, contextHashtable, originalCharsetName } = connectionData; const { jndiName, contextHashtable, originalCharsetName } = connectionData;
const { hgap, vgap } = CONNECTION_LAYOUT; const { hgap, vgap } = CONNECTION_LAYOUT;
return { return {
type: BI.VerticalLayout.xtype, type: Vertical,
$testId: 'dec-dcm-connection-jndi', $testId: 'dec-dcm-connection-jndi',
hgap, hgap,
vgap, vgap,
items: [ items: [
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_ConnectionName'), name: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_ConnectionName'),
value: jndiName, value: jndiName,
}, },
{ {
type: BI.HTapeLayout.xtype, type: Htape,
height: 115, height: 115,
items: [ items: [
{ {
el: { el: {
type: BI.FloatLeftLayout.xtype, type: Left,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
cls: 'bi-font-bold', cls: 'bi-font-bold',
textAlign: 'left', textAlign: 'left',
text: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_Connection'), text: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_Connection'),
@ -51,33 +50,33 @@ export class ConnectionJndi extends BI.Widget {
width: 200, width: 200,
}, },
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
bgap: 15, bgap: 15,
height: 115, height: 115,
items: [ items: [
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'INTIAL_CONTEXT_FACTORY', name: 'INTIAL_CONTEXT_FACTORY',
nameWidth: 200, nameWidth: 200,
isBold: false, isBold: false,
value: contextHashtable['java.naming.factory.initial'], value: contextHashtable['java.naming.factory.initial'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'PROVIDER_URL', name: 'PROVIDER_URL',
nameWidth: 200, nameWidth: 200,
isBold: false, isBold: false,
value: contextHashtable['java.naming.provider.url'], value: contextHashtable['java.naming.provider.url'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'SECURITY_PRINCIPAL', name: 'SECURITY_PRINCIPAL',
nameWidth: 200, nameWidth: 200,
isBold: false, isBold: false,
value: contextHashtable['java.naming.security.principal'], value: contextHashtable['java.naming.security.principal'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'SECURITY_CREDENTIALS', name: 'SECURITY_CREDENTIALS',
nameWidth: 200, nameWidth: 200,
isBold: false, isBold: false,
@ -89,13 +88,13 @@ export class ConnectionJndi extends BI.Widget {
], ],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: BI.i18nText('Dec-Dcm_Connection_Form_OriginalCharsetName'), name: BI.i18nText('Dec-Dcm_Connection_Form_OriginalCharsetName'),
value: originalCharsetName ? originalCharsetName : BI.i18nText('Dec-Dcm_Connection_Form_Default'), value: originalCharsetName ? originalCharsetName : BI.i18nText('Dec-Dcm_Connection_Form_Auto'),
}, },
{ {
type: Collapse.xtype, type: CollapseXtype,
width: 70, width: 70,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Advanced_Setting'), name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Advanced_Setting'),
listeners: [ listeners: [
@ -108,76 +107,76 @@ export class ConnectionJndi extends BI.Widget {
], ],
}, },
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
vgap, vgap,
tgap: -15, tgap: -15,
invisible: true, invisible: true,
ref: (_ref: VerticalLayout) => { ref: (_ref: any) => {
this.advancedSet = _ref; this.advancedSet = _ref;
}, },
items: [ items: [
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'OBJECT_FACTORIES', name: 'OBJECT_FACTORIES',
value: contextHashtable['java.naming.factory.object'], value: contextHashtable['java.naming.factory.object'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'STATE_FACTORIES', name: 'STATE_FACTORIES',
value: contextHashtable['java.naming.factory.state'], value: contextHashtable['java.naming.factory.state'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'URL_PKG_PREFIXES', name: 'URL_PKG_PREFIXES',
value: contextHashtable['java.naming.factory.url.pkgs'], value: contextHashtable['java.naming.factory.url.pkgs'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'DNS_URL', name: 'DNS_URL',
value: contextHashtable['java.naming.dns.url'], value: contextHashtable['java.naming.dns.url'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'AUTHORITATIVE', name: 'AUTHORITATIVE',
value: contextHashtable['java.naming.authoritative'], value: contextHashtable['java.naming.authoritative'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'BATCHSIZE', name: 'BATCHSIZE',
value: contextHashtable['java.naming.batchsize'], value: contextHashtable['java.naming.batchsize'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'REFERRAL', name: 'REFERRAL',
value: contextHashtable['java.naming.referral'], value: contextHashtable['java.naming.referral'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'SECURITY_PROTOCOL', name: 'SECURITY_PROTOCOL',
value: contextHashtable['java.naming.security.protocol'], value: contextHashtable['java.naming.security.protocol'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'SECURITY_AUTHENTICATION', name: 'SECURITY_AUTHENTICATION',
value: contextHashtable['java.naming.security.authentication'], value: contextHashtable['java.naming.security.authentication'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'LANGUAGE', name: 'LANGUAGE',
value: contextHashtable['java.naming.language'], value: contextHashtable['java.naming.language'],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
nameWidth: 200, nameWidth: 200,
name: 'APPLET', name: 'APPLET',
value: contextHashtable['java.naming.applet'], value: contextHashtable['java.naming.applet'],

17
src/modules/pages/connection/connection_plugin/connection_plugin.model.ts

@ -1,14 +1,11 @@
import { AppModel } from '../../../app.model';
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { ConnectionModel } from '../connection.model';
@model() export const ConnectionPluginModelXtype = 'dec.dcm.model.connection_plugin';
@model(ConnectionPluginModelXtype)
export class ConnectionPluginModel extends Model<{ export class ConnectionPluginModel extends Model<{
types : { context : {
connectionSelectedOne: AppModel['TYPE']['connectionSelectedOne']; connectionSelectedOne: ConnectionModel['$$childContext']['connectionSelectedOne'];
}, }
context: ConnectionPluginModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection_plugin'; context = ['connectionSelectedOne'];
context = <const>['connectionSelectedOne'];
} }

9
src/modules/pages/connection/connection_plugin/connection_plugin.ts

@ -1,11 +1,10 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { ConnectionPluginModel } from './connection_plugin.model'; import { ConnectionPluginModelXtype, ConnectionPluginModel } from './connection_plugin.model';
import { getPluginWidgetShow } from 'src/modules/app.service'; import { getPluginWidgetShow } from 'src/modules/app.service';
@shortcut() export const ConnectionPluginXtype = 'dec.dcm.connection_plugin';
@store(ConnectionPluginModel) @shortcut(ConnectionPluginXtype)
@store(ConnectionPluginModelXtype)
export class ConnectionPlugin extends BI.Widget { export class ConnectionPlugin extends BI.Widget {
static xtype = 'dec.dcm.connection_plugin';
model: ConnectionPluginModel['model']; model: ConnectionPluginModel['model'];
render () { render () {

1
src/modules/pages/connection/list/list.constant.ts

@ -1 +0,0 @@
BI.constant('dec.constant.connection.list', []);

50
src/modules/pages/connection/list/list.model.ts

@ -1,59 +1,37 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { ApiFactory } from '../../..//crud/apiFactory'; import { ApiFactory } from '../../..//crud/apiFactory';
import { AppModel } from '../../../app.model'; import { AppModel } from '../../../app.model';
import type { ConnectionJDBC } from '../../../crud/crud.typings';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
@model() export const ConnectionListModelXtype = 'dec.dcm.model.connection.list';
@model(ConnectionListModelXtype)
export class ConnectionListModel extends Model<{ export class ConnectionListModel extends Model<{
types: { context : {
connections: AppModel['TYPE']['connections']; connections: AppModel['$$childContext']['connections'];
connectionSelected: AppModel['TYPE']['connectionSelected']; connectionSelected: AppModel['$$childContext']['connectionSelected'];
}, }
context: ConnectionListModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection.list'; context = ['connections', 'connectionSelected'];
context = <const>['connections', 'connectionSelected'];
computed = { computed = {
shwoType: () => BI.size(this.model.connections) > 0 ? 'list' : 'none', shwoType: () => BI.size(this.model.connections) > 0 ? 'list' : 'none',
} }
actions = { actions = {
setConnections: (): Promise<void> => api.getConnectionList().then(data => { setConnections: ():Promise<void> => api.getConnectionlist().then(data => {
data.data.push(...BI.Constants.getConstant('dec.constant.connection.list'));
if (BI.size(data.data) > 0) { if (BI.size(data.data) > 0) {
this.model.connections = data.data; this.model.connections = data.data;
let defaultDatabaseName,
defaultDatabaseId = BI.Services.getService("dec.service.global")
.getHashSearchParams("databaseId");
this.model.connections.forEach(item => { this.model.connections.forEach(item => {
// REPORT-111534 有些环境存在脏数据,补下容错 // 后端传过来的是字符串,转为对象
if (BI.isNull(item.connectionData)) return; item.connectionData = JSON.parse(item.connectionData as string);
// 后端传过来的是字符串,转为对象
BI.isString(item.connectionData) && (item.connectionData = JSON.parse(item.connectionData as string));
// 目前只有jdbc存在identity,后期拓展
if ((item.connectionData as ConnectionJDBC).identity === defaultDatabaseId) {
defaultDatabaseName = item.connectionName;
}
}); });
this.model.connectionSelected = data.data[0].connectionName;
// 仅首次进入时从url中读取参数,其他情况保留选中状态 } else {
defaultDatabaseName ||= data.data[0].connectionName; this.model.connectionSelected = '';
this.setSelectedConnection(defaultDatabaseName);
} }
return new Promise(resolve => { return new Promise(resolve => {
resolve(); resolve();
}); });
}), }),
setSelectedConnection(name: string) {
this.model.connectionSelected = name;
}
} }
} }

40
src/modules/pages/connection/list/list.ts

@ -1,22 +1,19 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { ListItem } from './list_item/list_item'; import { CenterAdapt, Label, Layout, Vtape, Loader, Tab } from 'ui';
import { ConnectionListModel } from './list.model'; import { ListItemXtype } from './list_item/list_item';
import { ConnectionListModel, ConnectionListModelXtype } from './list.model';
import { getDatabaseType } from './list.service'; import { getDatabaseType } from './list.service';
import { Tab } from '@fui/core'; export const ConnectionListXtype = 'dec.dcm.connection.list';
import './list.constant' @shortcut(ConnectionListXtype)
@store(ConnectionListModelXtype)
@shortcut() export class ConnectionList extends BI.LoadingPane {
@store(ConnectionListModel)
export class ConnectionList extends BI.Pane {
static xtype = 'dec.dcm.connection.list';
store: ConnectionListModel['store']; store: ConnectionListModel['store'];
model: ConnectionListModel['model']; model: ConnectionListModel['model'];
groupWidget: any; groupWidget: any;
tab: Tab; tab: any;
beforeRender(cb: Function) { beforeInit(cb: Function) {
this.store.setConnections().then(() => { this.store.setConnections().then(() => {
cb(); cb();
}); });
@ -35,31 +32,31 @@ export class ConnectionList extends BI.Pane {
render() { render() {
return { return {
type: BI.Tab.xtype, type: Tab,
single: true, single: true,
showIndex: this.model.shwoType, showIndex: this.model.shwoType,
ref: (_ref: Tab) => { ref: (_ref: any) => {
this.tab = _ref; this.tab = _ref;
}, },
cardCreator: (index: 'list' | 'none') => { cardCreator: (index: 'list' | 'none') => {
if (index === 'none') { if (index === 'none') {
return { return {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
items: [ items: [
{ {
type: BI.VTapeLayout.xtype, type: Vtape,
width: 260, width: 260,
height: 150, height: 150,
items: [ items: [
{ {
el: { el: {
type: BI.Layout.xtype, type: Layout,
cls: 'data-connection-background', cls: 'data-connection-background',
}, },
height: 130, height: 130,
}, },
{ {
type: BI.Label.xtype, type: Label,
cls: 'bi-tips', cls: 'bi-tips',
text: BI.i18nText('Dec-Dcm_Connection_None'), text: BI.i18nText('Dec-Dcm_Connection_None'),
}, },
@ -68,9 +65,9 @@ export class ConnectionList extends BI.Pane {
], ],
}; };
} }
return { return {
type: BI.Loader.xtype, type: Loader,
itemsCreator: (options: {times: number}, populate) => { itemsCreator: (options: {times: number}, populate) => {
populate(this.renderList((options.times - 1) * 50, options.times * 50)); populate(this.renderList((options.times - 1) * 50, options.times * 50));
}, },
@ -86,13 +83,12 @@ export class ConnectionList extends BI.Pane {
private renderList(start = 0, end = 0) { private renderList(start = 0, end = 0) {
return this.model.connections.slice(start, end).map((item, index) => { return this.model.connections.slice(start, end).map((item, index) => {
return { return {
type: ListItem.xtype, type: ListItemXtype,
name: item.connectionName, name: item.connectionName,
value: item.connectionName, value: item.connectionName,
creator: item.creator, creator: item.creator,
databaseType: getDatabaseType(item), databaseType: getDatabaseType(item),
selected: this.model.connectionSelected ? this.model.connectionSelected === item.connectionName : index === 0, selected: this.model.connectionSelected ? this.model.connectionSelected === item.connectionName : index === 0,
pluginConnection: item.pluginConnection,
}; };
}); });
} }

101
src/modules/pages/connection/list/list_item/list_item.model.ts

@ -4,26 +4,22 @@ import { ApiFactory } from '../../../../crud/apiFactory';
import { ResultType } from '../../../../crud/crud.typings'; import { ResultType } from '../../../../crud/crud.typings';
import { getChartLength } from '../../../../app.service'; import { getChartLength } from '../../../../app.service';
import { NAME_MAX_LENGTH } from '../../../../app.constant'; import { NAME_MAX_LENGTH } from '../../../../app.constant';
import { PAGE_INDEX } from '@constants/constant';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
@model() export const ListItemModelXtype = 'dec.dcm.model.connection.list_item';
@model(ListItemModelXtype)
export class ListItemModel extends Model<{ export class ListItemModel extends Model<{
types: { context : {
connectionSelected: AppModel['TYPE']['connectionSelected']; connectionSelected: AppModel['$$childContext']['connectionSelected'];
connectionSelectedOne: AppModel['TYPE']['connectionSelectedOne']; connectionSelectedOne: AppModel['$$childContext']['connectionSelectedOne'];
datebaseTypeSelectedOne: AppModel['TYPE']['datebaseTypeSelectedOne']; datebaseTypeSelectedOne: AppModel['$$childContext']['datebaseTypeSelectedOne'];
connections: AppModel['TYPE']['connections']; connections: AppModel['$$childContext']['connections'];
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
isCopy: AppModel['TYPE']['isCopy'] isCopy: AppModel['$$childContext']['isCopy']
}, }
context: ListItemModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection.list_item'; context = ['connectionSelected', 'connections', 'pageIndex', 'datebaseTypeSelectedOne', 'connectionSelectedOne', 'datebaseTypeSelected', 'isCopy'];
context = <const>['connectionSelected', 'connections', 'pageIndex', 'datebaseTypeSelectedOne', 'connectionSelectedOne', 'datebaseTypeSelected', 'isCopy', 'connectionLicInfo'];
state() { state() {
return { return {
@ -54,12 +50,10 @@ export class ListItemModel extends Model<{
}, },
setIsEdit: (isEdit: boolean, name: string) => { setIsEdit: (isEdit: boolean, name: string) => {
if (isEdit) { if (isEdit) {
api.getConnectionStatus(name) api.getConnectionStatus(name).then(re => {
.then(re => { this.model.isEdit = true;
this.model.isEdit = true; })
}) .catch(() => {});
.catch(() => {
});
} else { } else {
api.shutdownConnectionStatus(name); api.shutdownConnectionStatus(name);
this.model.isEdit = false; this.model.isEdit = false;
@ -73,10 +67,7 @@ export class ListItemModel extends Model<{
} }
if (getChartLength(newName) > NAME_MAX_LENGTH) { if (getChartLength(newName) > NAME_MAX_LENGTH) {
return new Promise(resolve => { return new Promise(resolve => {
resolve({ resolve({ errorCode: '1', errorMsg: BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH) });
errorCode: '1',
errorMsg: BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH),
});
}); });
} }
const hasNamed = this.model.connections.some(item => item.connectionName === newName); const hasNamed = this.model.connections.some(item => item.connectionName === newName);
@ -89,59 +80,39 @@ export class ListItemModel extends Model<{
connection.connectionId = oldName; connection.connectionId = oldName;
connection.connectionName = newName; connection.connectionName = newName;
return api.updateConnection(connection) return api.updateConnection(connection).then(re => {
.then(re => { if (!re.errorCode) {
if (!re.errorCode) { this.model.connections = this.model.connections.map(item => {
this.model.connections = this.model.connections.map(item => { return {
return { ...item,
...item, connectionName: item.connectionName === oldName ? newName : item.connectionName,
connectionName: item.connectionName === oldName ? newName : item.connectionName, connectionId: item.connectionName === oldName ? newName : item.connectionName,
connectionId: item.connectionName === oldName ? newName : item.connectionName, };
}; });
}); if (this.model.connectionSelected === oldName) {
if (this.model.connectionSelected === oldName) { this.model.connectionSelected = newName;
this.model.connectionSelected = newName;
}
} }
}
return re;
}); return re;
}, });
copyConnection(connectionName) {
if (this.model.connectionLicInfo.currentConnectionNum >= this.model.connectionLicInfo.maxConnectionNum) {
BI.Services.getService('dec.service.component.icon_text.msg').alert({
text: BI.i18nText('Dec-Connection_Lic_Limit_Approach_Prevent_Tip', this.model.connectionLicInfo.maxConnectionNum),
});
return;
}
this.setConnectionSelected(connectionName);
this.setIsCopy(true);
this.setPageIndex(PAGE_INDEX.MAINTAIN);
}, },
setIsCopy: (isCopy: boolean) => { setIsCopy: (isCopy: boolean) => {
this.model.isCopy = isCopy; this.model.isCopy = isCopy;
}, },
isDriverError: (errorCode: string) => api.isDriverError(errorCode), isDriverError: (errorCode: string) => api.isDriverError(errorCode),
}; }
removeConnection(name: string) { removeConnection(name: string) {
api.deleteConnection(name) api.deleteConnection(name).then(re => api.getConnectionlist())
.then(re => {
this.model.connectionLicInfo.currentConnectionNum -= 1;
return api.getConnectionList();
})
.then(connections => { .then(connections => {
this.model.connections = connections.data; this.model.connections = connections.data;
this.model.connections.forEach(item => { this.model.connections.forEach(item => {
// 后端传过来的是字符串,转为对象 // 后端传过来的是字符串,转为对象
item.connectionData = JSON.parse(item.connectionData as string); item.connectionData = JSON.parse(item.connectionData as string);
}); });
if (name === this.model.connectionSelected) { if (name === this.model.connectionSelected) {
this.setConnectionSelected(this.model.connections?.[0]?.connectionName || ''); this.model.connectionSelected = BI.size(this.model.connections) > 0 ? this.model.connections[0].connectionName : '';
} }
api.shutdownConnectionStatus(name); api.shutdownConnectionStatus(name);
}); });

84
src/modules/pages/connection/list/list_item/list_item.ts

@ -1,37 +1,32 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { Label, IconLabel, IconButton, DownListCombo, SignEditor, Layout, Htape, Vertical } from 'ui';
import './list_item.less'; import './list_item.less';
import { ListItemModel } from './list_item.model'; import { ListItemModel, ListItemModelXtype } from './list_item.model';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { hasRegistered } from '../list.service'; import { hasRegistered } from '../list.service';
import { connectionCanEdit, getTextByDatabaseType, getChartLength } from '../../../../app.service'; import { connectionCanEdit, getTextByDatabaseType, getChartLength } from '../../../../app.service';
import { testConnection } from '../../../maintain/forms/form.server'; import { testConnection } from '../../../maintain/forms/form.server';
import { DownListCombo, Label, SignEditor } from '@fui/core';
import { ApiFactory } from '../../../../crud/apiFactory';
import { checkIllegalStrings } from "@core/index";
const api = new ApiFactory().create(); export const ListItemXtype = 'dec.dcm.connection.list_item';
@shortcut(ListItemXtype)
@shortcut() @store(ListItemModelXtype)
@store(ListItemModel)
export class ListItem extends BI.BasicButton { export class ListItem extends BI.BasicButton {
static xtype = 'dec.dcm.connection.list_item';
props = { props = {
name: '', name: '',
creator: '', creator: '',
databaseType: '', databaseType: '',
pluginConnection: false,
height: 25, height: 25,
baseCls: 'dec-dcm-connection-list-item bi-list-item-active2', baseCls: 'dec-dcm-connection-list-item bi-list-item-active2',
$testId: 'dec-dcm-connection-list-item', $testId: 'dec-dcm-connection-list-item',
}; }
store: ListItemModel['store']; store: ListItemModel['store'];
model: ListItemModel['model']; model: ListItemModel['model'];
nameLabel: Label; comboWidget: any;
nameEditor: SignEditor; nameLabel: any;
downListCombo: DownListCombo; nameEditor: any;
downListCombo: any;
watch = { watch = {
isEdit: (isEdit: boolean) => { isEdit: (isEdit: boolean) => {
@ -41,40 +36,40 @@ export class ListItem extends BI.BasicButton {
this.nameEditor.focus(); this.nameEditor.focus();
} }
}, },
}; }
render() { render() {
const { name, databaseType, pluginConnection } = this.options; const { name, databaseType } = this.options;
return { return {
type: BI.HTapeLayout.xtype, type: Htape,
$scope: name, $scope: name,
items: [{ items: [{
el: { el: {
type: BI.IconLabel.xtype, type: IconLabel,
cls: 'dcm-link-font icon-size-16', cls: 'dcm-link-font icon-size-16',
title: name, title: name,
}, },
width: 25, width: 25,
}, { }, {
type: BI.VerticalLayout.xtype, type: Vertical,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
text: name, text: name,
textAlign: 'left', textAlign: 'left',
height: 25, height: 25,
title: name, title: name,
ref: (_ref: Label) => { ref: (_ref: any) => {
this.nameLabel = _ref; this.nameLabel = _ref;
}, },
}, },
{ {
type: BI.SignEditor.xtype, type: SignEditor,
$value: 'connection-name', $value: 'connection-name',
value: name, value: name,
invisible: !this.model.isEdit, invisible: !this.model.isEdit,
ref: (_ref: SignEditor) => { ref: (_ref: any) => {
this.nameEditor = _ref; this.nameEditor = _ref;
}, },
listeners: [{ listeners: [{
@ -91,17 +86,6 @@ export class ListItem extends BI.BasicButton {
return; return;
} }
const result = checkIllegalStrings(newName);
if (!result.legal) {
BI.Msg.toast(result.errorMsg, {
level: 'error',
});
this.store.setIsEdit(false, name);
this.nameLabel.setText(name);
this.nameEditor.setValue(name);
return;
}
this.store.changeName(name, newName).then(re => { this.store.changeName(name, newName).then(re => {
this.store.setIsEdit(false, name); this.store.setIsEdit(false, name);
if (re.errorCode) { if (re.errorCode) {
@ -119,18 +103,18 @@ export class ListItem extends BI.BasicButton {
}, },
], ],
}, { }, {
el: databaseType && !pluginConnection ? { el: databaseType ? {
type: BI.DownListCombo.xtype, type: DownListCombo,
cls: 'link-item-icon', cls: 'link-item-icon',
stopPropagation: true, stopPropagation: true,
hgap: 8, hgap: 8,
el: { el: {
type: BI.IconButton.xtype, type: IconButton,
$value: 'other-edit', $value: 'other-edit',
cls: 'dcm-link-other-font icon-size-16', cls: 'dcm-link-other-font icon-size-16',
}, },
items: this.renderDownList(), items: this.renderDownList(),
ref: (_ref: DownListCombo) => { ref: (_ref: any) => {
this.downListCombo = _ref; this.downListCombo = _ref;
}, },
listeners: [{ listeners: [{
@ -146,7 +130,7 @@ export class ListItem extends BI.BasicButton {
}], }],
} : { } : {
type: BI.Layout.xtype, type: Layout,
}, },
width: 25, width: 25,
}], }],
@ -222,17 +206,8 @@ export class ListItem extends BI.BasicButton {
} }
private testConnectionAction() { private testConnectionAction() {
// 接口返回的内容是对称加密的,前端要先解密再用新加密传回去 const { name } = this.options;
const connection = BI.cloneDeep(this.model.connections testConnection(this.model.connections.find(item => item.connectionName === name));
.find(item => item.connectionName === this.options.name));
if (BI.isNull(connection)) return;
const validationQuery = connection?.connectionData?.connectionPoolAttr?.validationQuery || '';
BI.set(connection, 'connectionData.connectionPoolAttr.validationQuery', api.getCipher(api.getPlain(validationQuery)));
testConnection(connection);
} }
private itemActionCalculate() { private itemActionCalculate() {
@ -245,14 +220,15 @@ export class ListItem extends BI.BasicButton {
this.store.setPageIndex(PAGE_INDEX.MAINTAIN); this.store.setPageIndex(PAGE_INDEX.MAINTAIN);
this.store.setDatebaseTypeSelected(''); this.store.setDatebaseTypeSelected('');
}) })
.catch(() => { .catch(() => { });
});
}, },
changeName: () => { changeName: () => {
this.store.setIsEdit(true, name); this.store.setIsEdit(true, name);
}, },
copy: () => { copy: () => {
this.store.copyConnection(name); this.store.setConnectionSelected(name);
this.store.setIsCopy(true);
this.store.setPageIndex(PAGE_INDEX.MAINTAIN);
}, },
delete: () => { delete: () => {
this.store.deleteConnection(name); this.store.deleteConnection(name);

17
src/modules/pages/connection_pool/connection_pool.model.ts

@ -1,18 +1,15 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { AppModel } from '../../app.model'; import { AppModel } from '../../app.model';
import { connectionType } from '@constants/env'; import { connectionType } from '@constants/env';
export const ConnectionPoolModelXtype = 'dec.dcm.model.connection_pool';
@model() @model(ConnectionPoolModelXtype)
export class ConnectionPoolModel extends Model<{ export class ConnectionPoolModel extends Model<{
types : { context : {
connections: AppModel['TYPE']['connections']; connections: AppModel['$$childContext']['connections'];
}, }
context: ConnectionPoolModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection_pool'; childContext = ['selected'];
context = ['connections'];
childContext = <const>['selected'];
context = <const>['connections'];
state() { state() {
return { return {

76
src/modules/pages/connection_pool/connection_pool.ts

@ -1,16 +1,14 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { ConnectionPoolModel } from './connection_pool.model'; import { Htape, Vtape, Label, Layout, CenterAdapt, Loader } from 'ui';
import { ListItem } from './list_item/list_item'; import { ConnectionPoolModel, ConnectionPoolModelXtype } from './connection_pool.model';
import { Pool } from './pool/pool'; import { ListItemXtype } from './list_item/list_item';
import { PoolXtype } from './pool/pool';
import { PAGE_SIZE } from '@constants/constant'; import { PAGE_SIZE } from '@constants/constant';
import { Label } from '@fui/core'; export const ConnectionPoolXtype = 'dec.dcm.connection_pool';
@shortcut(ConnectionPoolXtype)
@shortcut() @store(ConnectionPoolModelXtype)
@store(ConnectionPoolModel)
export class ConnectionPool extends BI.Widget { export class ConnectionPool extends BI.Widget {
static xtype = 'dec.dcm.connection_pool'; title: any;
title: Label;
model: ConnectionPoolModel['model']; model: ConnectionPoolModel['model'];
store: ConnectionPoolModel['store']; store: ConnectionPoolModel['store'];
@ -19,7 +17,7 @@ export class ConnectionPool extends BI.Widget {
selected: (selected: string) => { selected: (selected: string) => {
this.title.setText(selected); this.title.setText(selected);
}, },
}; }
mounted() { mounted() {
const defaultSelected = this.model.connectionJDBC.length > 0 ? this.model.connectionJDBC[0].connectionName : ''; const defaultSelected = this.model.connectionJDBC.length > 0 ? this.model.connectionJDBC[0].connectionName : '';
@ -30,34 +28,31 @@ export class ConnectionPool extends BI.Widget {
if (BI.size(this.model.connectionJDBC) === 0) { if (BI.size(this.model.connectionJDBC) === 0) {
return this.renderNoConnection(); return this.renderNoConnection();
} }
return { return {
type: BI.HTapeLayout.xtype, type: Htape,
items: [ items: [
{ {
el: { el: {
type: BI.VTapeLayout.xtype, type: Vtape,
cls: 'bi-border-right', cls: 'bi-border-right',
hgap: 10,
items: [ items: [
{ {
el: { el: {
type: BI.Label.xtype, type: Label,
cls: 'bi-border-bottom', cls: 'bi-border-bottom',
textAlign: 'left', textAlign: 'left',
text: BI.i18nText('Dec-Dcm_Data_Connections'), text: BI.i18nText('Dec-Dcm_Data_Connections'),
lgap: 10,
}, },
height: 40, height: 40,
}, },
{ {
el: { type: Loader,
type: BI.Loader.xtype, itemsCreator: (options: {times: number}, populate) => {
itemsCreator: (options: { times: number }, populate) => { populate(this.renderList((options.times - 1) * PAGE_SIZE, options.times * PAGE_SIZE));
populate(this.renderList((options.times - 1) * PAGE_SIZE, options.times * PAGE_SIZE));
},
hasNext: options => options.times * PAGE_SIZE < BI.size(this.model.connectionJDBC),
}, },
vgap: 10, hasNext: options => options.times * PAGE_SIZE < BI.size(this.model.connectionJDBC),
}, },
], ],
}, },
@ -70,22 +65,22 @@ export class ConnectionPool extends BI.Widget {
private renderPool() { private renderPool() {
return { return {
type: BI.VTapeLayout.xtype, type: Vtape,
items: [ items: [
{ {
el: { el: {
type: BI.Label.xtype, type: Label,
cls: 'bi-border-bottom', cls: 'bi-border-bottom',
textAlign: 'left', textAlign: 'left',
lgap: 10, lgap: 10,
ref: (_ref: Label) => { ref: (_ref: any) => {
this.title = _ref; this.title = _ref;
}, },
}, },
height: 40, height: 40,
}, },
{ {
type: Pool.xtype, type: PoolXtype,
}, },
], ],
}; };
@ -93,22 +88,22 @@ export class ConnectionPool extends BI.Widget {
private renderNoConnection() { private renderNoConnection() {
return { return {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
items: [ items: [
{ {
type: BI.VTapeLayout.xtype, type: Vtape,
width: 260, width: 260,
height: 150, height: 150,
items: [ items: [
{ {
el: { el: {
type: BI.Layout.xtype, type: Layout,
cls: 'data-connection-background', cls: 'data-connection-background',
}, },
height: 130, height: 130,
}, },
{ {
type: BI.Label.xtype, type: Label,
cls: 'bi-tips', cls: 'bi-tips',
text: BI.i18nText('Dec-Dcm_Connection_NO_Connection_Pool'), text: BI.i18nText('Dec-Dcm_Connection_NO_Connection_Pool'),
}, },
@ -120,15 +115,14 @@ export class ConnectionPool extends BI.Widget {
private renderList(start = 0, end = 0) { private renderList(start = 0, end = 0) {
const defaultSelected = this.model.connectionJDBC.length > 0 ? this.model.connectionJDBC[0].connectionName : ''; const defaultSelected = this.model.connectionJDBC.length > 0 ? this.model.connectionJDBC[0].connectionName : '';
return this.model.connectionJDBC.slice(start, end) return this.model.connectionJDBC.slice(start, end).map(item => {
.map(item => { return {
return { type: ListItemXtype,
type: ListItem.xtype, name: item.connectionName,
name: item.connectionName, value: item.connectionName,
value: item.connectionName, selected: item.connectionName === defaultSelected,
selected: item.connectionName === defaultSelected, };
}; });
});
} }
} }

13
src/modules/pages/connection_pool/list_item/list_item.model.ts

@ -1,14 +1,13 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { ConnectionPoolModel } from '../connection_pool.model'; import { ConnectionPoolModel } from '../connection_pool.model';
@model() export const ListItemModelXtype = 'dec.dcm.model.connection_pool.list_item';
@model(ListItemModelXtype)
export class ListItemModel extends Model<{ export class ListItemModel extends Model<{
types : { context : {
selected: ConnectionPoolModel['TYPE']['selected']; selected: ConnectionPoolModel['$$childContext']['selected'];
}, }
context: ListItemModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection_pool.list_item'; context = ['selected'];
context = <const>['selected'];
actions = { actions = {
setSelected: (selected: string) => { setSelected: (selected: string) => {
this.model.selected = selected; this.model.selected = selected;

14
src/modules/pages/connection_pool/list_item/list_item.ts

@ -1,10 +1,10 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { ListItemModel } from './list_item.model'; import { VerticalAdapt, Label } from 'ui';
@shortcut() import { ListItemModel, ListItemModelXtype } from './list_item.model';
@store(ListItemModel) export const ListItemXtype = 'dec.dcm.connection_pool.list_item';
@shortcut(ListItemXtype)
@store(ListItemModelXtype)
export class ListItem extends BI.BasicButton { export class ListItem extends BI.BasicButton {
static xtype = 'dec.dcm.connection_pool.list_item';
props = { props = {
name: '', name: '',
height: 25, height: 25,
@ -16,11 +16,11 @@ export class ListItem extends BI.BasicButton {
render() { render() {
return { return {
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
lgap: 5, lgap: 5,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
text: this.options.name, text: this.options.name,
title: this.options.name, title: this.options.name,
width: 250, width: 250,

14
src/modules/pages/connection_pool/pool/pool.model.ts

@ -3,16 +3,14 @@ import { ConnectionPoolModel } from '../connection_pool.model';
import { ConnectionPoolType } from '../../../crud/crud.typings'; import { ConnectionPoolType } from '../../../crud/crud.typings';
import { ApiFactory } from '../../../crud/apiFactory'; import { ApiFactory } from '../../../crud/apiFactory';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
@model() export const PoolModelXtype = 'dec.dcm.model.connection_pool.pool';
@model(PoolModelXtype)
export class PoolModel extends Model<{ export class PoolModel extends Model<{
types : { context : {
selected: ConnectionPoolModel['TYPE']['selected']; selected: ConnectionPoolModel['$$childContext']['selected'];
}, }
context: PoolModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.connection_pool.poo'; context = ['selected'];
context = <const>['selected'];
state () { state () {
return { return {

71
src/modules/pages/connection_pool/pool/pool.ts

@ -1,77 +1,76 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { PoolModel } from './pool.model'; import { PoolModel, PoolModelXtype } from './pool.model';
import { FloatCenter, Vertical, CenterAdapt, Label, VerticalAdapt } from 'ui';
import './pool.less'; import './pool.less';
import { ConnectionPoolType } from '../../../crud/crud.typings'; import { ConnectionPoolType } from '../../../crud/crud.typings';
import { Label } from '@fui/core';
@shortcut() export const PoolXtype = 'dec.dcm.connection_pool.pool';
@store(PoolModel) @shortcut(PoolXtype)
@store(PoolModelXtype)
export class Pool extends BI.Widget { export class Pool extends BI.Widget {
static xtype = 'dec.dcm.connection_pool.pool';
props = { props = {
baseCls: 'dec-dcm-connection-pool', baseCls: 'dec-dcm-connection-pool',
$testId: 'dec-dcm-connection-pool', $testId: 'dec-dcm-connection-pool',
} }
model: PoolModel['model']; model: PoolModel['model'];
maxActive: Label; maxActive: any;
maxIdle: Label; maxIdle: any;
numActive: Label; numActive: any;
numIdle: Label; numIdle: any;
watch = { watch = {
pool: (pool: ConnectionPoolType) => { pool: (pool: ConnectionPoolType) => {
this.maxActive.setText(`${pool.maxActive}`); this.maxActive.setText(pool.maxActive);
this.maxIdle.setText(`${pool.maxIdle}`); this.maxIdle.setText(pool.maxIdle);
this.numActive.setText(`${pool.numActive}`); this.numActive.setText(pool.numActive);
this.numIdle.setText(`${pool.numIdle}`); this.numIdle.setText(pool.numIdle);
}, },
} }
render() { render() {
return { return {
type: BI.VerticalLayout.xtype, type: Vertical,
items: [ items: [
{ {
type: BI.FloatCenterLayout.xtype, type: FloatCenter,
hgap: 20, hgap: 20,
vgap: 10, vgap: 10,
height: 200, height: 200,
items: [ items: [
{ {
el: { el: {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
cls: 'bi-background', cls: 'bi-background',
items: [ items: [
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
cls: 'right-status-board-item', cls: 'right-status-board-item',
items: [ items: [
{ {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
items: [ items: [
{ {
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
$testId: 'dec-dcm-pool-status-number', $testId: 'dec-dcm-pool-status-number',
$value: 'active', $value: 'active',
cls: 'bi-high-light card-font-heighlight', cls: 'bi-high-light card-font-heighlight',
ref: (_ref: Label) => { ref: (_ref: any) => {
this.numActive = _ref; this.numActive = _ref;
}, },
}, },
{ {
type: BI.Label.xtype, type: Label,
text: '/', text: '/',
}, },
{ {
type: BI.Label.xtype, type: Label,
$testId: 'dec-dcm-pool-status-max', $testId: 'dec-dcm-pool-status-max',
$value: 'active', $value: 'active',
ref: (_ref: Label) => { ref: (_ref: any) => {
this.maxActive = _ref; this.maxActive = _ref;
}, },
}, },
@ -80,7 +79,7 @@ export class Pool extends BI.Widget {
], ],
}, },
{ {
type: BI.Label.xtype, type: Label,
text: BI.i18nText('Dec-Dcm_Active_Connections_Number'), text: BI.i18nText('Dec-Dcm_Active_Connections_Number'),
}, },
], ],
@ -89,37 +88,37 @@ export class Pool extends BI.Widget {
}, },
}, },
{ {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
cls: 'bi-background', cls: 'bi-background',
items: [ items: [
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
cls: 'right-status-board-item', cls: 'right-status-board-item',
items: [ items: [
{ {
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
items: [ items: [
{ {
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
$testId: 'dec-dcm-pool-status-number', $testId: 'dec-dcm-pool-status-number',
$value: 'idle', $value: 'idle',
cls: 'bi-high-light card-font-heighlight', cls: 'bi-high-light card-font-heighlight',
ref: (_ref: Label) => { ref: (_ref: any) => {
this.numIdle = _ref; this.numIdle = _ref;
}, },
}, },
{ {
type: BI.Label.xtype, type: Label,
text: '/', text: '/',
}, },
{ {
type: BI.Label.xtype, type: Label,
$testId: 'dec-dcm-pool-status-max', $testId: 'dec-dcm-pool-status-max',
$value: 'idle', $value: 'idle',
ref: (_ref: Label) => { ref: (_ref: any) => {
this.maxIdle = _ref; this.maxIdle = _ref;
}, },
}, },
@ -128,7 +127,7 @@ export class Pool extends BI.Widget {
], ],
}, },
{ {
type: BI.Label.xtype, type: Label,
text: BI.i18nText('Dec-Dcm_Leisure_Connections_Number'), text: BI.i18nText('Dec-Dcm_Leisure_Connections_Number'),
}, },
], ],

17
src/modules/pages/database/database.constant.ts

@ -1,17 +0,0 @@
import { DATEBASE_FILTER_TYPE } from "@constants/constant";
BI.constant('dec.constant.database.filter.type', [
{
text: BI.i18nText('Dec-Dcm_Connection_Commonly'),
value: DATEBASE_FILTER_TYPE.COMMONLY,
selected: true,
},
{
text: BI.i18nText('Dec-Dcm_Connection_All'),
value: DATEBASE_FILTER_TYPE.ALL,
},
{
text: BI.i18nText('Dec-Dcm_Connection_Other'),
value: DATEBASE_FILTER_TYPE.OTHER,
},
]);

37
src/modules/pages/database/database.model.ts

@ -2,50 +2,36 @@ import { model, Model } from '@core/core';
import { AppModel } from 'src/modules/app.model'; import { AppModel } from 'src/modules/app.model';
import { getAllDatabaseTypes } from '../../app.service'; import { getAllDatabaseTypes } from '../../app.service';
import { DatabaseType } from '../../app.typings'; import { DatabaseType } from '../../app.typings';
import { connectionType } from '@constants/env';
import { OTHER_JDBC } from '@constants/constant';
@model() export const DatebaseModelXtype = 'dec.dcm.model.datebase';
@model(DatebaseModelXtype)
export class DatebaseModel extends Model<{ export class DatebaseModel extends Model<{
types: { context : {
filter: AppModel['TYPE']['filter']; filter: AppModel['$$childContext']['filter'];
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
}, }
context: DatebaseModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.datebase'; context = ['filter', 'datebaseTypeSelected'];
context = <const>['filter', 'datebaseTypeSelected'];
state() { state() {
return { return {
search: '', search: '',
isInternal: true, isInternal: true,
isPlugin: true, isPlugin: true,
datebaseTypes: getAllDatabaseTypes().filter(item => item.commonly), datebaseTypes: getAllDatabaseTypes().filter(item => item.commonly),
isJNDILimit: false,
}; };
} }
computed = {
otherDatabases: () => {
return this.model.isJNDILimit
? [OTHER_JDBC]
: [OTHER_JDBC, connectionType.JNDI];
}
}
actions = { actions = {
setSearch: (search: string) => { setSearch:(search: string) => {
this.model.search = search; this.model.search = search;
}, },
setFilter: (filter: string) => { setFilter:(filter: string) => {
this.model.filter = filter; this.model.filter = filter;
}, },
setDatebaseTypes: (datebaseTypes: DatabaseType[]) => { setDatebaseTypes: (datebaseTypes: DatabaseType[]) => {
this.model.datebaseTypes = datebaseTypes; this.model.datebaseTypes = datebaseTypes;
this.model.datebaseTypeSelected = ''; this.model.datebaseTypeSelected = '';
}, },
setInternal: (isInternal: boolean) => { setInternal:(isInternal: boolean) => {
this.model.isInternal = isInternal; this.model.isInternal = isInternal;
}, },
setPlugin: (isPlugin: boolean) => { setPlugin: (isPlugin: boolean) => {
@ -54,8 +40,5 @@ export class DatebaseModel extends Model<{
setDatebaseTypeSelected(datebaseType: string) { setDatebaseTypeSelected(datebaseType: string) {
this.model.datebaseTypeSelected = datebaseType; this.model.datebaseTypeSelected = datebaseType;
}, },
setJNDILimit: (v: boolean) => {
this.model.isJNDILimit = v;
},
} }
} }

117
src/modules/pages/database/database.ts

@ -1,27 +1,21 @@
import { SearchEditor, Vtape, Right, Htape, Vertical, ButtonGroup, Left, Label, MultiSelectItem, CenterAdapt } from 'ui';
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { Filter } from './filter/filter'; import { FilterXtype } from './filter/filter';
import { DatebaseModel } from './database.model'; import { DatebaseModel, DatebaseModelXtype } from './database.model';
import { DATEBASE_FILTER_TYPE, OTHER_JDBC } from '@constants/constant'; import { DATEBASE_FILTER_TYPE, OTHER_JDBC } from '@constants/constant';
import { connectionType } from '@constants/env'; import { connectionType } from '@constants/env';
import { DatebaseType } from './database_type/database_type'; import { DatebaseTypeXtype } from './database_type/database_type';
import { getAllDatabaseTypes } from '../../app.service'; import { getAllDatabaseTypes } from '../../app.service';
import { ButtonGroup, MultiSelectItem, SearchEditor } from '@fui/core'; export const DatebaseXtype = 'dec.dcm.datebase';
import { ApiFactory } from 'src/modules/crud/apiFactory'; @shortcut(DatebaseXtype)
import './database.constant' @store(DatebaseModelXtype)
const api = new ApiFactory().create();
@shortcut()
@store(DatebaseModel)
export class Datebase extends BI.Widget { export class Datebase extends BI.Widget {
static xtype = 'dec.dcm.datebase'; filter: any;
search: any;
filter: ButtonGroup; datebaseType: any;
search: SearchEditor;
datebaseType: ButtonGroup;
typeFilterWidget: any; typeFilterWidget: any;
internalWidget: MultiSelectItem; internalWidget: any;
pluginWidget: MultiSelectItem; pluginWidget: any;
allDatabaseTypes = getAllDatabaseTypes(); allDatabaseTypes = getAllDatabaseTypes();
@ -70,28 +64,27 @@ export class Datebase extends BI.Widget {
mounted() { mounted() {
this.store.setFilter(DATEBASE_FILTER_TYPE.COMMONLY); this.store.setFilter(DATEBASE_FILTER_TYPE.COMMONLY);
this.store.setDatebaseTypeSelected(''); this.store.setDatebaseTypeSelected('');
this.getDatabaseTypeLimit();
} }
render() { render() {
return { return {
type: BI.VTapeLayout.xtype, type: Vtape,
vgap: 10, vgap: 10,
hgap: 10, hgap: 10,
items: [ items: [
{ {
el: { el: {
type: BI.VerticalLayout.xtype, type: Vertical,
items: [ items: [
{ {
type: BI.FloatRightLayout.xtype, type: Right,
items: [ items: [
{ {
type: BI.SearchEditor.xtype, type: SearchEditor,
$value: 'database-type', $value: 'database-type',
width: 300, width: 300,
watermark: BI.i18nText('BI-Basic_Search'), watermark: BI.i18nText('BI-Basic_Search'),
ref: (_ref: SearchEditor) => { ref: (_ref: any) => {
this.search = _ref; this.search = _ref;
}, },
listeners: [ listeners: [
@ -110,48 +103,62 @@ export class Datebase extends BI.Widget {
height: 25, height: 25,
}, },
{ {
type: BI.HTapeLayout.xtype, type: Htape,
items: [ items: [
{ {
el: { el: {
type: BI.ButtonGroup.xtype, type: ButtonGroup,
cls: 'bi-border-right', cls: 'bi-border-right',
layouts: [{ layouts: [{
type: BI.VerticalLayout.xtype, type: Vertical,
}], }],
ref: (_ref: ButtonGroup) => { ref: (_ref: any) => {
this.filter = _ref; this.filter = _ref;
}, },
items: () => BI.map(BI.Constants.getConstant('dec.constant.database.filter.type'), (_, value) => { items: [
return { {
type: Filter.xtype, type: FilterXtype,
...value, text: BI.i18nText('Dec-Dcm_Connection_Commonly'),
} value: DATEBASE_FILTER_TYPE.COMMONLY,
}), selected: true,
},
{
type: FilterXtype,
text: BI.i18nText('Dec-Dcm_Connection_All'),
value: DATEBASE_FILTER_TYPE.ALL,
},
{
type: FilterXtype,
text: BI.i18nText('Dec-Dcm_Connection_Other'),
value: DATEBASE_FILTER_TYPE.OTHER,
},
],
}, },
width: 200, width: 200,
}, },
{ {
type: BI.VTapeLayout.xtype, type: Vtape,
items: [ items: [
{ {
el: { el: {
type: BI.VerticalAdaptLayout.xtype, type: Htape,
hgap: 20, hgap: 20,
invisible: true, invisible: true,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
width: 70,
textAlign: 'left', textAlign: 'left',
text: BI.i18nText('Dec-Dcm_Connection_Type_Filter'), text: BI.i18nText('Dec-Dcm_Connection_Type_Filter'),
title: BI.i18nText('Dec-Dcm_Connection_Type_Filter'), title: BI.i18nText('Dec-Dcm_Connection_Type_Filter'),
}, },
{ {
type: BI.MultiSelectItem.xtype, type: MultiSelectItem,
width: 80,
selected: this.model.isInternal, selected: this.model.isInternal,
text: BI.i18nText('Dec-Dcm_Connection_Support_Inner'), text: BI.i18nText('Dec-Dcm_Connection_Support_Inner'),
title: BI.i18nText('Dec-Dcm_Connection_Support_Inner'), title: BI.i18nText('Dec-Dcm_Connection_Support_Inner'),
ref: (_ref: MultiSelectItem) => { ref: (_ref: any) => {
this.internalWidget = _ref; this.internalWidget = _ref;
}, },
handler: () => { handler: () => {
@ -159,11 +166,12 @@ export class Datebase extends BI.Widget {
}, },
}, },
{ {
type: BI.MultiSelectItem.xtype, type: MultiSelectItem,
width: 80,
selected: this.model.isPlugin, selected: this.model.isPlugin,
text: BI.i18nText('Dec-Dcm_Connection_Support_Plugin'), text: BI.i18nText('Dec-Dcm_Connection_Support_Plugin'),
title: BI.i18nText('Dec-Dcm_Connection_Support_Plugin'), title: BI.i18nText('Dec-Dcm_Connection_Support_Plugin'),
ref: (_ref: MultiSelectItem) => { ref: (_ref: any) => {
this.pluginWidget = _ref; this.pluginWidget = _ref;
}, },
handler: () => { handler: () => {
@ -171,7 +179,7 @@ export class Datebase extends BI.Widget {
}, },
}, },
{ {
type: BI.Label.xtype, type: Label,
cls: 'bi-tips', cls: 'bi-tips',
textAlign: 'left', textAlign: 'left',
text: BI.i18nText('Dec-Dcm_Connection_Filter_Tip'), text: BI.i18nText('Dec-Dcm_Connection_Filter_Tip'),
@ -185,14 +193,14 @@ export class Datebase extends BI.Widget {
height: 24, height: 24,
}, },
{ {
type: BI.ButtonGroup.xtype, type: ButtonGroup,
hgap: 15, hgap: 15,
layouts: [{ layouts: [{
type: BI.FloatLeftLayout.xtype, type: Left,
scrolly: true, scrolly: true,
}], }],
items: this.renderDatebaseType(), items: this.renderDatebaseType(),
ref: (_ref: ButtonGroup) => { ref: (_ref: any) => {
this.datebaseType = _ref; this.datebaseType = _ref;
}, },
}, },
@ -211,7 +219,7 @@ export class Datebase extends BI.Widget {
return this.model.datebaseTypes.map(item => { return this.model.datebaseTypes.map(item => {
return { return {
type: DatebaseType.xtype, type: DatebaseTypeXtype,
text: item.text, text: item.text,
value: item.databaseType, value: item.databaseType,
keyword: this.model.search, keyword: this.model.search,
@ -224,11 +232,11 @@ export class Datebase extends BI.Widget {
private renderNoResult() { private renderNoResult() {
return [{ return [{
type: BI.CenterAdaptLayout.xtype, type: CenterAdapt,
height: '100%', height: '100%',
width: '100%', width: '100%',
items: [{ items: [{
type: BI.Label.xtype, type: Label,
cls: 'bi-tips', cls: 'bi-tips',
text: BI.i18nText('Dec-Dcm_Connection_No_Search_Result'), text: BI.i18nText('Dec-Dcm_Connection_No_Search_Result'),
}], }],
@ -241,20 +249,11 @@ export class Datebase extends BI.Widget {
this.store.setDatebaseTypes(this.allDatabaseTypes.filter(item => item.commonly)); this.store.setDatebaseTypes(this.allDatabaseTypes.filter(item => item.commonly));
break; break;
case DATEBASE_FILTER_TYPE.OTHER: case DATEBASE_FILTER_TYPE.OTHER:
this.store.setDatebaseTypes(this.allDatabaseTypes.filter(item => this.model.otherDatabases.includes(item.type))); this.store.setDatebaseTypes(this.allDatabaseTypes.filter(item => item.type === connectionType.JNDI || item.type === OTHER_JDBC));
break;
case DATEBASE_FILTER_TYPE.ALL:
this.store.setDatebaseTypes(this.allDatabaseTypes.filter(item => item.type !== connectionType.JNDI && item.type !== OTHER_JDBC));
break; break;
default: default:
this.store.setDatebaseTypes(this.allDatabaseTypes.filter(item => item.marker && (item.marker === filter))); this.store.setDatebaseTypes(this.allDatabaseTypes.filter(item => item.type !== connectionType.JNDI && item.type !== OTHER_JDBC));
break; break;
} }
} }
// 获取JNDI
private async getDatabaseTypeLimit() {
const result = await api.getJNDIDatabaseStatus();
this.store.setJNDILimit(result.data);
}
} }

12
src/modules/pages/database/database.typings.d.ts vendored

@ -0,0 +1,12 @@
export interface DatabaseType {
text: string;
databaseType: string;
driver?: string;
drivers?: string[];
url?: string;
commonly: boolean;
internal: boolean;
type: string;
hasSchema?: boolean;
kerberos?: boolean;
}

20
src/modules/pages/database/database_type/database_type.model.ts

@ -1,18 +1,15 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { AppModel } from 'src/modules/app.model'; import { AppModel } from 'src/modules/app.model';
@model() export const DatebaseTypeModelXtype = 'dec.dcm.model.datebase.type';
@model(DatebaseTypeModelXtype)
export class DatebaseTypeModel extends Model< export class DatebaseTypeModel extends Model<
{ {
types: { context: {
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
noTestConnection: AppModel['TYPE']['noTestConnection']; }
datebaseTypeSelectedOne: AppModel['TYPE']['datebaseTypeSelectedOne'];
},
context: DatebaseTypeModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.datebase.type'; context = ['datebaseTypeSelected', 'pageIndex'];
context = <const>['datebaseTypeSelected', 'pageIndex', 'noTestConnection', 'datebaseTypeSelectedOne'];
actions = { actions = {
setDatebaseTypeSelected: (datebaseTypeSelected: string) => { setDatebaseTypeSelected: (datebaseTypeSelected: string) => {
@ -21,8 +18,5 @@ export class DatebaseTypeModel extends Model<
setPageIndex: (index: string) => { setPageIndex: (index: string) => {
this.model.pageIndex = index; this.model.pageIndex = index;
}, },
setNoTestConnection: (value: boolean) => {
this.model.noTestConnection = value;
}
} }
} }

27
src/modules/pages/database/database_type/database_type.ts

@ -1,15 +1,14 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { DatebaseTypeModel } from './database_type.model'; import { Vtape, Label, Absolute, Img } from 'ui';
import { DatebaseTypeModel, DatebaseTypeModelXtype } from './database_type.model';
import { ImgPrefix, PluginImgPrefix } from '@constants/env'; import { ImgPrefix, PluginImgPrefix } from '@constants/env';
import './database_type.less'; import './database_type.less';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { Img } from '@fui/core';
@shortcut() export const DatebaseTypeXtype = 'dec.dcm.datebase.type';
@store(DatebaseTypeModel) @shortcut(DatebaseTypeXtype)
@store(DatebaseTypeModelXtype)
export class DatebaseType extends BI.BasicButton { export class DatebaseType extends BI.BasicButton {
static xtype = 'dec.dcm.datebase.type';
props = { props = {
text: '', text: '',
url: '', url: '',
@ -23,7 +22,7 @@ export class DatebaseType extends BI.BasicButton {
$testId: 'dec-dcm-database-type', $testId: 'dec-dcm-database-type',
} }
img: Img; img: any;
store: DatebaseTypeModel['store']; store: DatebaseTypeModel['store'];
@ -31,25 +30,25 @@ export class DatebaseType extends BI.BasicButton {
const { text, keyword, databaseType, iconUrl } = this.options; const { text, keyword, databaseType, iconUrl } = this.options;
return { return {
type: BI.AbsoluteLayout.xtype, type: Absolute,
items: [ items: [
{ {
el: { el: {
type: BI.VTapeLayout.xtype, type: Vtape,
cls: 'bi-list-item-active bi-border', cls: 'bi-list-item-active bi-border',
items: [ items: [
{ {
el: { el: {
type: BI.Img.xtype, type: Img,
src: iconUrl ? this.getIconUrl(iconUrl) : `${ImgPrefix}${databaseType}.jpg`, src: iconUrl ? this.getIconUrl(iconUrl) : `${ImgPrefix}${databaseType}.jpg`,
ref: (_ref: Img) => { ref: (_ref: any) => {
this.img = _ref; this.img = _ref;
}, },
}, },
height: 90, height: 90,
}, },
{ {
type: BI.Label.xtype, type: Label,
cls: 'bi-header-background', cls: 'bi-header-background',
text, text,
title: text, title: text,
@ -70,7 +69,6 @@ export class DatebaseType extends BI.BasicButton {
const { value } = this.options; const { value } = this.options;
this.store.setDatebaseTypeSelected(value); this.store.setDatebaseTypeSelected(value);
this.store.setPageIndex(PAGE_INDEX.MAINTAIN); this.store.setPageIndex(PAGE_INDEX.MAINTAIN);
this.store.setNoTestConnection(this.model.datebaseTypeSelectedOne.isHideConnection);
} }
mounted() { mounted() {
@ -89,9 +87,6 @@ export class DatebaseType extends BI.BasicButton {
if (url.startsWith('/')) { if (url.startsWith('/')) {
return `${PluginImgPrefix}${url}`; return `${PluginImgPrefix}${url}`;
} }
if (url.startsWith('http')) {
return url;
}
return `${PluginImgPrefix}/${url}`; return `${PluginImgPrefix}/${url}`;
} }

13
src/modules/pages/database/filter/filter.model.ts

@ -1,15 +1,14 @@
import { Model, model } from '@core/core'; import { Model, model } from '@core/core';
import { AppModel } from 'src/modules/app.model'; import { AppModel } from 'src/modules/app.model';
@model() export const FilterModelXtype = 'dec.dcm.model.datebase.filter';
@model(FilterModelXtype)
export class FilterModel extends Model<{ export class FilterModel extends Model<{
types : { context : {
filter: AppModel['TYPE']['filter']; filter: AppModel['$$childContext']['filter'];
}, }
context: FilterModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.datebase.filter'; context = ['filter'];
context = <const>['filter'];
actions = { actions = {
setFilter:(filter: string) => { setFilter:(filter: string) => {

11
src/modules/pages/database/filter/filter.ts

@ -1,10 +1,11 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { FilterModel } from './filter.model'; import { Label } from 'ui';
import { FilterModel, FilterModelXtype } from './filter.model';
@shortcut() export const FilterXtype = 'dec.dcm.datebase.filter';
@store(FilterModel) @shortcut(FilterXtype)
@store(FilterModelXtype)
export class Filter extends BI.BasicButton { export class Filter extends BI.BasicButton {
static xtype = 'dec.dcm.datebase.filter';
store: FilterModel['store'] store: FilterModel['store']
props = { props = {
text: '', text: '',
@ -17,7 +18,7 @@ export class Filter extends BI.BasicButton {
const { text } = this.options; const { text } = this.options;
return { return {
type: BI.Label.xtype, type: Label,
textAlign: 'left', textAlign: 'left',
height: 25, height: 25,
lgap: 10, lgap: 10,

10
src/modules/pages/index.ts

@ -0,0 +1,10 @@
import { ConnectionXtype } from './connection/connection';
import { DatebaseXtype } from './database/database';
import { MaintainXtype } from './maintain/maintain';
import { ConnectionPoolXtype } from './connection_pool/connection_pool';
export {
ConnectionXtype,
DatebaseXtype,
MaintainXtype,
ConnectionPoolXtype,
};

133
src/modules/pages/maintain/components/driverselector/driverselector.model.ts

@ -1,133 +0,0 @@
import { model, Model } from '@core/core';
import { ConnectionJDBC } from '../../../../crud/crud.typings';
import { getJdbcDatabaseType } from '../../../../app.service';
import { ApiFactory } from '../../../../crud/apiFactory';
const api = new ApiFactory().create();
@model()
export class DriverSelectorModel extends Model {
static xtype = 'dec.dcm.model.maintain.form.jdbc.driver_selector';
state = () => {
const defaultDrivers = this.getDrivers();
const [driverSource, selectedDriver] = this.resolveSelectedDriverType();
return {
defaultDrivers,
driverSource,
selectedDriverType: driverSource === '' ? 'default' : 'custom',
customDrivers: [],
defaultDriver: {
driver: driverSource === '' ? selectedDriver : '',
},
customDriver: {
driver: driverSource !== '' ? selectedDriver : '',
value: driverSource !== '' ? `${this.options.driver} (${driverSource})` : '',
},
};
};
computed = {
driverClassItems: () => this.model.customDrivers.map(driver => {
return {
text: `${driver.driverClass} (${driver.name})`,
value: `${driver.driverClass} (${driver.name})`,
driverClass: driver.driverClass,
};
}),
driverTypeComboValue: () => this.model.driverSource === '' ? 'default' : 'custom',
driverManageEntryVisible: () => this.model.selectedDriverType === 'custom' && BI.Services.getService('dec.service.global').isAdmin(),
};
actions = {
initDriverClassList: cb => {
api.getSimpleDriverList().then(res => {
this.model.customDrivers = res.data.filter(driver => {
return BI.isKey(driver.driverClass);
});
cb();
});
},
changeDefaultDriver: driver => {
this.model.defaultDriver.driver = driver;
this.model.driverSource = '';
},
changeCustomDriver: value => {
const item = this.model.driverClassItems.find(item => {
return item.value === value;
});
const driver = item.driverClass;
this.model.customDriver.driver = driver;
this.model.customDrivers.some(customDriver => {
// DEC-21469 存在driver值相同但driver名不同的场景,因此要用拼接名判断
if (`${customDriver.driverClass} (${customDriver.name})` === value) {
this.model.driverSource = customDriver.name;
this.model.customDriver.value = `${driver} (${customDriver.name})`;
return true;
}
return false;
});
},
changeSelectedDriverType: driverTypeComboValue => {
this.model.selectedDriverType = driverTypeComboValue;
this.model.driverSource = driverTypeComboValue === 'default' ? '' : this.model.driverSource;
},
changeDriverSource: driverTypeComboValue => {
this.model.driverSource = driverTypeComboValue === 'default' ? '' : this.model.driverSource;
},
setDefaultDrivers: version => {
const defaultDrivers = this.getDrivers(version);
this.model.defaultDrivers = defaultDrivers;
this.changeDefaultDriver(defaultDrivers[0]?.value);
}
};
private resolveSelectedDriverType = () => {
if (BI.isNotEmptyString(this.options.driverSource)) {
return [this.options.driverSource, this.options.driver];
}
return [this.options.driverSource, this.options.driver];
};
private getDrivers = (version?: string) => {
const connectionData = this.options.connectionData as ConnectionJDBC;
const connectionType = getJdbcDatabaseType(connectionData.database, connectionData.driver);
const selectedVersion = version ?? this.options.version;
const drivers = connectionType.drivers ?
(BI.isUndefined(connectionType.versions) ? connectionType.drivers : connectionType.drivers[selectedVersion]).map(item => {
return {
text: item,
value: item,
};
}) :
[{
text: connectionType.driver,
value: connectionType.driver,
}];
if (BI.isUndefined(connectionType.versions) && !drivers.some(item => item.text === connectionData.driver)) {
return [
{
text: connectionData.driver,
value: connectionData.driver,
},
...drivers,
];
}
return drivers;
};
}

196
src/modules/pages/maintain/components/driverselector/driverselector.ts

@ -1,196 +0,0 @@
import { shortcut, store } from '@core/core';
import {
Button,
EditorIconCheckCombo,
SearchTextValueCombo,
TextValueCombo,
} from '@fui/core';
import { ConnectionJDBC } from '../../../../crud/crud.typings';
import { getJdbcDatabaseType } from '../../../../app.service';
import { DriverSelectorModel } from './driverselector.model';
@shortcut()
@store(DriverSelectorModel, {
props(this: DriverSelector) {
return this.options;
},
})
export class DriverSelector extends BI.Widget {
static xtype = 'dec.dcm.maintain.form.jdbc.driver_selector';
props = {
driver: '',
driverSource: '',
connectionData: {} as ConnectionJDBC,
version: '',
};
defaultDrivers: EditorIconCheckCombo = null;
customDrivers: SearchTextValueCombo = null;
beforeRender(cb: Function) {
this.store.initDriverClassList(cb);
}
watch = {
driverClassItems: items => {
this.customDrivers.populate(items);
this.customDrivers.setValue(this.model.customDriver.value);
},
driverManageEntryVisible: b => {
this.driverManageEntry.setVisible(b);
},
defaultDrivers: items => {
this.defaultDrivers.populate(items);
this.defaultDrivers.setValue(this.model.defaultDriver.driver);
this.fireEvent('EVENT_CHANGE');
}
};
private driverManageEntry = null;
render() {
const { driver } = this.options.connectionData;
return {
type: BI.VerticalAdaptLayout.xtype,
rgap: 10,
items: [
{
el: {
type: BI.TextValueCombo.xtype,
width: 86,
value: this.model.selectedDriverType,
items: [
{
text: BI.i18nText('Dec-Basic_Default'),
value: 'default',
}, {
text: BI.i18nText('Dec-Basic_Custom'),
value: 'custom',
},
],
listeners: [
{
eventName: BI.TextValueCombo.EVENT_CHANGE,
action: value => {
this.store.changeSelectedDriverType(value);
if (value === 'default') {
this.defaultDrivers.setVisible(true);
this.customDrivers.setVisible(false);
this.fireEvent('EVENT_CHANGE');
return;
}
this.defaultDrivers.setVisible(false);
this.customDrivers.setVisible(true);
if (BI.isKey(this.customDrivers.getValue()[0])) {
this.fireEvent('EVENT_CHANGE');
}
},
},
],
},
}, {
el: {
type: BI.EditorIconCheckCombo.xtype,
$testId: 'dec-editor-icon-check-combo',
$value: 'driver',
ref: _ref => {
this.defaultDrivers = _ref;
},
invisible: this.model.driverSource !== '',
width: 204,
items: this.model.defaultDrivers,
value: this.model.defaultDriver.driver,
listeners: [
{
eventName: BI.EditorIconCheckCombo.EVENT_CHANGE,
action: () => {
this.store.changeDefaultDriver(this.defaultDrivers.getValue());
this.fireEvent('EVENT_CHANGE');
},
},
],
},
}, {
el: {
type: BI.SearchTextValueCombo.xtype,
$testId: 'dec-editor-icon-check-combo',
$value: 'driver',
ref: _ref => {
this.customDrivers = _ref;
},
invisible: this.model.driverSource === '',
width: 204,
watermark: BI.i18nText('Dec-Please_Input'),
items: this.model.driverClassItems,
value: this.model.customDriver.value,
text: () => this.model.customDriver.value || '',
defaultText: BI.i18nText('Dec-Please_Select_One'),
warningTitle: BI.i18nText('Dec-Dcm-Driver_Driver_File_Lost'),
listeners: [
{
eventName: BI.SearchTextValueCombo.EVENT_CHANGE,
action: () => {
this.store.changeCustomDriver(this.customDrivers.getValue()[0]);
this.fireEvent('EVENT_CHANGE');
},
},
],
},
}, {
el: {
type: 'dec.connection.driver.entry',
ref: (_ref: Button) => {
this.driverManageEntry = _ref;
},
el: {
type: BI.Button.xtype,
level: 'ignore',
text: BI.i18nText('Dec-Dcm_Create_New_Driver'),
},
from: '.dec-dcm',
invisible: !this.model.driverManageEntryVisible,
listeners: [
{
eventName: 'EVENT_CLOSE',
action: () => {
this.store.initDriverClassList(BI.emptyFn);
},
},
],
},
},
],
};
}
validation(): boolean {
if (this.model.selectedDriverType === 'default' && BI.isKey(this.model.defaultDriver.driver)) {
return true;
}
if (this.model.selectedDriverType === 'custom' && BI.isKey(this.model.customDriver.driver)) {
return true;
}
BI.Msg.toast(BI.i18nText('Dec-Dcm_Driver_Class_Not_Allow_Empty'), { level: 'error' });
return false;
}
getValue() {
return {
driverSource: this.model.driverSource,
driver: this.model.driverSource === '' ? this.model.defaultDriver.driver : this.model.customDriver.driver,
};
}
setDefaultDrivers(version: string) {
this.store.setDefaultDrivers(version);
}
}

29
src/modules/pages/maintain/components/form_item/form_item.ts

@ -1,30 +1,23 @@
import { shortcut } from '@core/core'; import { shortcut } from '@core/core';
import { Label } from '@fui/core'; import { Label, Left } from 'ui';
import { CONNECTION_LAYOUT } from '@constants/constant'; import { CONNECTION_LAYOUT } from '@constants/constant';
export const FormItemXtype = 'dec.dcm.Maintain_form_item';
@shortcut() @shortcut(FormItemXtype)
export class FormItem extends BI.Widget { export class FormItem extends BI.Widget {
static xtype = 'dec.dcm.Maintain_form_item';
props = { props = {
name: '', name: '',
forms: '', forms: '',
nameWidth: 140, nameWidth: 140,
isBold: true, isBold: true,
$testId: 'dec-dcm-maintain-form-item', $testId: 'dec-dcm-maintain-form-item',
}; }
nameLabel: Label;
render() { render () {
return { return {
type: BI.FloatLeftLayout.xtype, type: Left,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
ref: (ref: Label) => {
this.nameLabel = ref;
},
cls: this.options.isBold ? 'bi-font-bold' : '', cls: this.options.isBold ? 'bi-font-bold' : '',
width: this.options.nameWidth, width: this.options.nameWidth,
textAlign: 'left', textAlign: 'left',
@ -35,12 +28,4 @@ export class FormItem extends BI.Widget {
], ],
}; };
} }
/**
*
* @param name
*/
setName(name: string) {
this.nameLabel.setText(name);
}
} }

2677
src/modules/pages/maintain/forms/components/form.jdbc.ts

File diff suppressed because it is too large Load Diff

169
src/modules/pages/maintain/forms/components/form.jndi.ts

@ -1,20 +1,19 @@
import {shortcut} from '@core/core'; import { shortcut } from '@core/core';
import {FormItem} from '../../components/form_item/form_item'; import { Vertical, TextEditor, Htape, Left, Label, TextValueCombo, EdirotIconCheckCombo } from 'ui';
import {ConnectionJNDI, Connection, ContextHashtable} from 'src/modules/crud/crud.typings'; import { FormItemXtype } from '../../components/form_item/form_item';
import {CONNECT_CHARSET, CONNECTION_LAYOUT, JNDI_FACTORYS} from '@constants/constant'; import { ConnectionJNDI, Connection, ContextHashtable } from 'src/modules/crud/crud.typings';
import {Collapse, EVENT_CHANGE} from 'src/modules/components/collapse/collapse'; import { CONNECT_CHARSET, CONNECTION_LAYOUT, JNDI_FACTORYS } from '@constants/constant';
import {connectionType} from '@constants/env'; import { CollapseXtype, EVENT_CHANGE } from 'src/modules/components/collapse/collapse';
import {TextChecker} from '../../../../components/text_checker/text_checker'; import { connectionType } from '@constants/env';
import {EditorIconCheckCombo, TextEditor, TextValueCombo, VerticalLayout} from '@fui/core'; import { TextCheckerXtype } from '../../../../components/text_checker/text_checker';
export const FormJndiXtype = 'dec.dcm.maintain.form.jndi';
@shortcut() @shortcut(FormJndiXtype)
export class FormJndi extends BI.Widget { export class FormJndi extends BI.Widget {
static xtype = 'dec.dcm.maintain.form.jndi';
props = { props = {
formData: {} as Connection, formData: {} as Connection,
} }
advancedSet: VerticalLayout; advancedSet: any;
testStatus: any;
form = { form = {
connectionName: null, connectionName: null,
jndiName: null, jndiName: null,
@ -37,54 +36,54 @@ export class FormJndi extends BI.Widget {
} }
render() { render() {
const {connectionName, connectionData} = this.options.formData; const { connectionName, connectionData } = this.options.formData;
const {jndiName, newCharsetName, contextHashtable} = connectionData as ConnectionJNDI; const { jndiName, newCharsetName, contextHashtable } = connectionData as ConnectionJNDI;
const {hgap, vgap} = CONNECTION_LAYOUT; const { hgap, vgap } = CONNECTION_LAYOUT;
return { return {
type: BI.VerticalLayout.xtype, type: Vertical,
hgap, hgap,
vgap, vgap,
items: [ items: [
{ {
type: FormItem.xtype, type: FormItemXtype,
name: BI.i18nText('Dec-Dcm_Connection_Name'), name: BI.i18nText('Dec-Dcm_Connection_Name'),
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: TextChecker.xtype, type: TextCheckerXtype,
$value: 'connection-name', $value: 'connection-name',
width: 300, width: 300,
value: connectionName, value: connectionName,
ref: (_ref: TextChecker) => { ref: (_ref: any) => {
this.form.connectionName = _ref; this.form.connectionName = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_ConnectionName'), name: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_ConnectionName'),
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'jdni-name', $value: 'jdni-name',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: jndiName, value: jndiName,
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.jndiName = _ref; this.form.jndiName = _ref;
}, },
}], }],
}, },
{ {
type: BI.HTapeLayout.xtype, type: Htape,
height: 175, height: 175,
items: [ items: [
{ {
el: { el: {
type: BI.FloatLeftLayout.xtype, type: Left,
items: [ items: [
{ {
type: BI.Label.xtype, type: Label,
cls: 'bi-font-bold', cls: 'bi-font-bold',
textAlign: 'left', textAlign: 'left',
text: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_Connection'), text: BI.i18nText('Dec-Dcm_Connection_JNDI_Form_Connection'),
@ -94,22 +93,22 @@ export class FormJndi extends BI.Widget {
width: 200, width: 200,
}, },
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
bgap: 15, bgap: 15,
height: 175, height: 175,
items: [ items: [
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'INTIAL_CONTEXT_FACTORY', name: 'INTIAL_CONTEXT_FACTORY',
nameWidth: 200, nameWidth: 200,
isBold: false, isBold: false,
forms: [{ forms: [{
type: BI.EditorIconCheckCombo.xtype, type: EdirotIconCheckCombo,
$testId: 'dec-editor-icon-check-combo', $testId: 'dec-editor-icon-check-combo',
$value: 'initial', $value: 'initial',
width: 300, width: 300,
value: contextHashtable['java.naming.factory.initial'], value: contextHashtable['java.naming.factory.initial'],
ref: (_ref: EditorIconCheckCombo) => { ref: (_ref: any) => {
this.form.initial = _ref; this.form.initial = _ref;
}, },
items: JNDI_FACTORYS.map(item => { items: JNDI_FACTORYS.map(item => {
@ -129,55 +128,55 @@ export class FormJndi extends BI.Widget {
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'PROVIDER_URL', name: 'PROVIDER_URL',
isBold: false, isBold: false,
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'provider-url', $value: 'provider-url',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.provider.url'], value: contextHashtable['java.naming.provider.url'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.providerUrl = _ref; this.form.providerUrl = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'SECURITY_PRINCIPAL', name: 'SECURITY_PRINCIPAL',
isBold: false, isBold: false,
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'security-principal', $value: 'security-principal',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.security.principal'], value: contextHashtable['java.naming.security.principal'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.securityPrincipal = _ref; this.form.securityPrincipal = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'SECURITY_CREDENTIALS', name: 'SECURITY_CREDENTIALS',
isBold: false, isBold: false,
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'security-credentials', $value: 'security-credentials',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.security.credentials'], value: contextHashtable['java.naming.security.credentials'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.securityCredentials = _ref; this.form.securityCredentials = _ref;
}, },
}], }],
}, },
{ {
type: BI.Label.xtype, type: Label,
bgap: -15, bgap: -15,
cls: 'bi-tips', cls: 'bi-tips',
textAlign: 'left', textAlign: 'left',
@ -188,22 +187,22 @@ export class FormJndi extends BI.Widget {
], ],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: BI.i18nText('Dec-Dcm_Connection_Form_OriginalCharsetName'), name: BI.i18nText('Dec-Dcm_Connection_Form_OriginalCharsetName'),
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextValueCombo.xtype, type: TextValueCombo,
$value: 'original-charset-name', $value: 'new-charset-name',
width: 300, width: 300,
value: newCharsetName ? newCharsetName : '', value: newCharsetName ? newCharsetName : '',
items: CONNECT_CHARSET, items: CONNECT_CHARSET,
ref: (_ref: TextValueCombo) => { ref: (_ref: any) => {
this.form.newCharsetName = _ref; this.form.newCharsetName = _ref;
}, },
}], }],
}, },
{ {
type: Collapse.xtype, type: CollapseXtype,
width: 70, width: 70,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Advanced_Setting'), name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Advanced_Setting'),
listeners: [ listeners: [
@ -216,175 +215,175 @@ export class FormJndi extends BI.Widget {
], ],
}, },
{ {
type: BI.VerticalLayout.xtype, type: Vertical,
vgap, vgap,
tgap: -15, tgap: -15,
invisible: true, invisible: true,
ref: (_ref: VerticalLayout) => { ref: (_ref: any) => {
this.advancedSet = _ref; this.advancedSet = _ref;
}, },
items: [ items: [
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'OBJECT_FACTORIES', name: 'OBJECT_FACTORIES',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'factory-object', $value: 'factory-object',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.factory.object'], value: contextHashtable['java.naming.factory.object'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.factoryObject = _ref; this.form.factoryObject = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'STATE_FACTORIES', name: 'STATE_FACTORIES',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'factory-state', $value: 'factory-state',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.factory.state'], value: contextHashtable['java.naming.factory.state'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.factoryState = _ref; this.form.factoryState = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'URL_PKG_PREFIXES', name: 'URL_PKG_PREFIXES',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'factory-url-pkgs', $value: 'factory-url-pkgs',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.factory.url.pkgs'], value: contextHashtable['java.naming.factory.url.pkgs'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.factoryUrlPkgs = _ref; this.form.factoryUrlPkgs = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'DNS_URL', name: 'DNS_URL',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'dns-url', $value: 'dns-url',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.dns.url'], value: contextHashtable['java.naming.dns.url'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.dnsUrl = _ref; this.form.dnsUrl = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'AUTHORITATIVE', name: 'AUTHORITATIVE',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'authoritative', $value: 'authoritative',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.authoritative'], value: contextHashtable['java.naming.authoritative'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.authoritative = _ref; this.form.authoritative = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'BATCHSIZE', name: 'BATCHSIZE',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'batchsize', $value: 'batchsize',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.batchsize'], value: contextHashtable['java.naming.batchsize'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.batchsize = _ref; this.form.batchsize = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'REFERRAL', name: 'REFERRAL',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'referral', $value: 'referral',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.referral'], value: contextHashtable['java.naming.referral'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.referral = _ref; this.form.referral = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'SECURITY_PROTOCOL', name: 'SECURITY_PROTOCOL',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'security-protocol', $value: 'security-protocol',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.security.protocol'], value: contextHashtable['java.naming.security.protocol'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.securityProtocol = _ref; this.form.securityProtocol = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'SECURITY_AUTHENTICATION', name: 'SECURITY_AUTHENTICATION',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'security-authentication', $value: 'security-authentication',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.security.authentication'], value: contextHashtable['java.naming.security.authentication'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.authentication = _ref; this.form.authentication = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'LANGUAGE', name: 'LANGUAGE',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'language', $value: 'language',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.language'], value: contextHashtable['java.naming.language'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.language = _ref; this.form.language = _ref;
}, },
}], }],
}, },
{ {
type: FormItem.xtype, type: FormItemXtype,
name: 'APPLET', name: 'APPLET',
nameWidth: 200, nameWidth: 200,
forms: [{ forms: [{
type: BI.TextEditor.xtype, type: TextEditor,
$value: 'applet', $value: 'applet',
width: 300, width: 300,
allowBlank: true, allowBlank: true,
value: contextHashtable['java.naming.applet'], value: contextHashtable['java.naming.applet'],
ref: (_ref: TextEditor) => { ref: (_ref: any) => {
this.form.applet = _ref; this.form.applet = _ref;
}, },
}], }],
@ -399,9 +398,7 @@ export class FormJndi extends BI.Widget {
this.form.connectionName.setError(value); this.form.connectionName.setError(value);
} }
public getSubmitValue(): Connection { public getSubmitValue():Connection {
const connectionData = this.options.formData.connectionData as ConnectionJNDI;
const contextHashtable = { const contextHashtable = {
'java.naming.factory.initial': this.form.initial.getValue(), 'java.naming.factory.initial': this.form.initial.getValue(),
'java.naming.provider.url': this.form.providerUrl.getValue(), 'java.naming.provider.url': this.form.providerUrl.getValue(),
@ -425,18 +422,18 @@ export class FormJndi extends BI.Widget {
delete contextHashtable[propName]; delete contextHashtable[propName];
} }
} }
return { return {
connectionId: this.form.connectionName.getValue(), connectionId: this.form.connectionName.getValue(),
connectionName: this.form.connectionName.getValue(), connectionName: this.form.connectionName.getValue(),
connectionType: connectionType.JNDI, connectionType: connectionType.JNDI,
connectionData: <ConnectionJNDI>BI.extend({}, connectionData, { connectionData: {
jndiName: this.form.jndiName.getValue(), jndiName: this.form.jndiName.getValue(),
newCharsetName: this.form.newCharsetName.getValue()[0] || '', newCharsetName: this.form.newCharsetName.getValue()[0] || '',
originalCharsetName: this.form.newCharsetName.getValue()[0] || '', originalCharsetName: this.form.newCharsetName.getValue()[0] || '',
creator: Dec ? Dec.personal.username : '', creator: Dec ? Dec.personal.username : '',
contextHashtable: contextHashtable as ContextHashtable, contextHashtable: contextHashtable as ContextHashtable,
}), },
}; };
} }
} }

31
src/modules/pages/maintain/forms/components/form.plugin.ts

@ -1,44 +1,35 @@
import { shortcut } from '@core/core'; import { shortcut } from '@core/core';
import { Connection, ConnectionPlugin } from 'src/modules/crud/crud.typings'; import { Connection } from 'src/modules/crud/crud.typings';
import { getPluginWidgetEdit } from '../../../../app.service'; import { getPluginWidgetEdit } from '../../../../app.service';
export const FormPluginXtype = 'dec.dcm.maintain_plugin';
@shortcut() @shortcut(FormPluginXtype)
export class FormPlugin extends BI.Widget { export class FormPlugin extends BI.Widget {
static xtype = 'dec.dcm.maintain_plugin';
props = { props = {
formData: {} as Connection, formData: {} as Connection,
}; }
plugin: any; plugin: any;
render() { render() {
const { connectionType, connectionId, connectionName, connectionData } = this.options.formData; const { connectionType } = this.options.formData;
return { return {
type: getPluginWidgetEdit(connectionType), type: getPluginWidgetEdit(connectionType),
ref: (_ref: any) => { ref: (_ref: any) => {
this.plugin = _ref; this.plugin = _ref;
}, },
value: connectionData, // 兼容 value: this.options.formData.connectionData,
connectionData,
connectionId,
connectionType,
connectionName,
}; };
} }
public getSubmitValue(): Connection { public getSubmitValue(): Connection {
const { connectionType, connectionId, connectionName, connectionData } = this.options.formData; const { connectionType, connectionId, connectionName } = this.options.formData;
return { return {
connectionId, connectionId,
connectionType, connectionType,
connectionName: this.plugin.getConnectionName ? this.plugin.getConnectionName() : connectionName, connectionName,
connectionData: <ConnectionPlugin>BI.extend({}, connectionData, this.plugin.getValue()), connectionData: this.plugin.getValue(),
}; };
} }
public getSaveFn() {
return this.plugin.save;
}
} }

43
src/modules/pages/maintain/forms/form.model.ts

@ -5,35 +5,21 @@ import { ApiFactory } from 'src/modules/crud/apiFactory';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { testConnection } from './form.server'; import { testConnection } from './form.server';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
export const MaintainFormModelXtype = 'dec.dcm.model.maintain_form';
@model() @model(MaintainFormModelXtype)
export class MaintainFormModel extends Model<{ export class MaintainFormModel extends Model<{
types : { context : {
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
datebaseTypeSelectedOne: AppModel['TYPE']['datebaseTypeSelectedOne']; datebaseTypeSelectedOne: AppModel['$$childContext']['datebaseTypeSelectedOne'];
connectionSelectedOne: AppModel['TYPE']['connectionSelectedOne']; connectionSelectedOne: AppModel['$$childContext']['connectionSelectedOne'];
saveEvent: AppModel['TYPE']['saveEvent']; saveEvent: AppModel['$$childContext']['saveEvent'];
testEvent: AppModel['TYPE']['testEvent']; testEvent: AppModel['$$childContext']['testEvent'];
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
connections: AppModel['TYPE']['connections']; connections: AppModel['$$childContext']['connections'];
isCopy: AppModel['TYPE']['isCopy']; isCopy: AppModel['$$childContext']['isCopy'];
connectionSelected: AppModel['TYPE']['connectionSelected']; }
},
context: MaintainFormModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.maintain_form'; context = ['datebaseTypeSelected', 'datebaseTypeSelectedOne', 'connectionSelectedOne', 'saveEvent', 'pageIndex', 'testEvent', 'connections', 'isCopy'];
context = <const>[
'datebaseTypeSelected',
'datebaseTypeSelectedOne',
'connectionSelectedOne',
'saveEvent',
'pageIndex',
'testEvent',
'connections',
'isCopy',
'connectionSelected',
];
actions = { actions = {
addConnection: (data: Connection) => api.addConnection(data), addConnection: (data: Connection) => api.addConnection(data),
@ -53,8 +39,5 @@ export class MaintainFormModel extends Model<{
goFirstPage() { goFirstPage() {
this.model.pageIndex = PAGE_INDEX.CONNECTION; this.model.pageIndex = PAGE_INDEX.CONNECTION;
}, },
setConnectionSelected(name: string) {
this.model.connectionSelected = name;
}
} }
} }

82
src/modules/pages/maintain/forms/form.server.ts

@ -1,11 +1,9 @@
import { Connection, ConnectionJDBC } from '../../../crud/crud.typings'; import { Connection, ConnectionJDBC } from '../../../crud/crud.typings';
import { connectionType, errorCode } from '@constants/env'; import { connectionType, errorCode } from '@constants/env';
import { DATA_BASE_DRIVER_LINK, JDBC_ODBC_DRIVER, JDBC_ODBC_DRIVER_HELP_LINK, DEFAULT_HELP_LINK } from '@constants/constant'; import { DATA_BASE_DRIVER_LINK, JDBC_ODBC_DRIVER, JDBC_ODBC_DRIVER_HELP_LINK } from '@constants/constant';
import { TestStatus } from '../../../components/test_status/test_status'; import { TestStatusXtype, EVENT_RELOAD, EVENT_CLOSE } from '../../../components/test_status/test_status';
import { getJdbcDatabaseType } from '../../../app.service';
import { ApiFactory } from '../../../crud/apiFactory'; import { ApiFactory } from '../../../crud/apiFactory';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
export function testConnection(value: Connection): Promise<string[]> { export function testConnection(value: Connection): Promise<string[]> {
return new Promise(resolve => { return new Promise(resolve => {
let testStatus = null; let testStatus = null;
@ -13,45 +11,34 @@ export function testConnection(value: Connection): Promise<string[]> {
BI.Msg.toast(BI.i18nText('Dec-Dcm_Connection_ConnectionName_Cannt_Null'), { BI.Msg.toast(BI.i18nText('Dec-Dcm_Connection_ConnectionName_Cannt_Null'), {
level: 'error', level: 'error',
}); });
return false; return false;
} }
const id = BI.UUID(); const id = BI.UUID();
const testConnection = () => { const testConnection = () => {
const formValue = value; const formValue = value;
api.testConnection(formValue).then(re => { api.testConnection(formValue).then(re => {
if (re && re.errorCode) { if (re && re.errorCode) {
if (re.errorCode === DecCst.ErrorCode.NO_IP_AUTHORIZED) { // 判断是否是缺少驱动,如果缺少驱动则显示下载驱动的连接
testStatus.setFail();
return;
}
// 判断是否是缺少驱动,如果缺少驱动则显示下载驱动的连接
if (api.isDriverError(re.errorCode)) { if (api.isDriverError(re.errorCode)) {
if (formValue.connectionType === connectionType.JDBC) { if (formValue.connectionType === connectionType.JDBC) {
const driver = (formValue.connectionData as ConnectionJDBC).driver; const driver = (formValue.connectionData as ConnectionJDBC).driver;
// DEC-14009 1.8以上版本JDK支持ODBC连接 // DEC-14009 1.8以上版本JDK支持ODBC连接
if (driver === JDBC_ODBC_DRIVER) { if (driver === JDBC_ODBC_DRIVER) {
testStatus.setFail(re.errorMsg, driver, Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][JDBC_ODBC_DRIVER_HELP_LINK]); testStatus.setFail(re.errorMsg, driver, Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][JDBC_ODBC_DRIVER_HELP_LINK]);
return; return;
} }
const databaseType = (formValue.connectionData as ConnectionJDBC).database; const databaseType = (formValue.connectionData as ConnectionJDBC).database;
const databaseLink = BI.get(DATA_BASE_DRIVER_LINK.find(item => item.databaseType === databaseType), 'link', DEFAULT_HELP_LINK); const databaseLink = BI.get(DATA_BASE_DRIVER_LINK.find(item => item.databaseType === databaseType), 'link');
const link = BI.get(getJdbcDatabaseType(databaseType, driver), 'link') || Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][databaseLink]; testStatus.setFail(re.errorMsg, driver, Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][databaseLink]);
testStatus.setFail(re.errorMsg, driver, link);
} else { } else {
testStatus.setFail(re.errorMsg); testStatus.setFail(re.errorMsg);
} }
} else if (re.errorCode === errorCode.DUPLICATE_NAMES) { } else if (re.errorCode === errorCode.DUPLICATE_NAMES) {
testStatus.setFail(BI.i18nText(re.errorMsg)); testStatus.setFail(BI.i18nText(re.errorMsg));
} else { } else {
// 不缺少驱动,但连接失败,打印出当前驱动加载路径,并显示检测驱动按钮
testStatus.setFail(re.errorMsg); testStatus.setFail(re.errorMsg);
api.getDriverLoadPath(formValue).then(res => {
testStatus.setExtraContainer(createDriverTestContainer(res.data));
})
} }
} else if (re.data) { } else if (re.data) {
testStatus.setSuccess(); testStatus.setSuccess();
@ -66,62 +53,15 @@ export function testConnection(value: Connection): Promise<string[]> {
BI.Maskers.remove(id); BI.Maskers.remove(id);
} }
}); });
/**
*
*/
function createDriverTestContainer(path: string) {
return {
type: BI.VerticalLayout.xtype,
vgap: 5,
items: [
{
type: BI.Label.xtype,
text: BI.i18nText('Dec-Connection_Driver_Current_Load_Path', path),
textAlign: 'left',
whiteSpace: 'normal',
},
{
type: BI.TextButton.xtype,
cls: 'bi-high-light',
text: BI.i18nText('Dec-Connection_Driver_Check'),
textAlign: 'left',
handler: () => {
api.checkDriverStatus({
driver: (formValue.connectionData as ConnectionJDBC).driver,
path,
}).then(res => {
const isDriverConflict = res.data;
testStatus.setExtraContainer({
type: BI.VerticalLayout.xtype,
items: [
{
type: BI.Label.xtype,
textAlign: 'left',
text: isDriverConflict
? BI.i18nText('Dec-Connection_Driver_Has_Confilt_Tip')
: BI.i18nText('Dec-Connection_Driver_No_Confilt_Tip'),
cls: isDriverConflict ? 'bi-error' : '',
}
]
})
});
}
}
]
}
}
}; };
BI.Maskers.create(id, null, { BI.Maskers.create(id, null, {
render: { render: {
type: TestStatus.xtype, type: TestStatusXtype,
loadingText: BI.i18nText('Dec-Dcm_Connection_Testing'), loadingText: BI.i18nText('Dec-Dcm_Connection_Testing'),
loadingCls: 'upload-loading-icon', loadingCls: 'upload-loading-icon',
successText: BI.i18nText('Dec-Dcm_Connection_Test_Success'), successText: BI.i18nText('Dec-Dcm_Connection_Test_Success'),
successCls: 'upload-success-icon', successCls: 'upload-success-icon',
failText: BI.i18nText('Dec-Dcm_Connection_Test_Fail', ''), failText: BI.i18nText('Dec-Dcm_Connection_Test_Fail', name),
failCls: 'upload-fail-icon', failCls: 'upload-fail-icon',
retryText: BI.i18nText('Dec-Dcm_Connection_ReConnect'), retryText: BI.i18nText('Dec-Dcm_Connection_ReConnect'),
ref: (_ref: any) => { ref: (_ref: any) => {
@ -129,14 +69,14 @@ export function testConnection(value: Connection): Promise<string[]> {
}, },
listeners: [ listeners: [
{ {
eventName: TestStatus.EVENT_RELOAD, eventName: EVENT_RELOAD,
action: () => { action: () => {
testStatus.setLoading(); testStatus.setLoading();
testConnection(); testConnection();
}, },
}, },
{ {
eventName: TestStatus.EVENT_CLOSE, eventName: EVENT_CLOSE,
action: () => { action: () => {
BI.Maskers.remove(id); BI.Maskers.remove(id);
}, },

195
src/modules/pages/maintain/forms/form.ts

@ -1,27 +1,23 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { MaintainFormModel } from './form.model'; import { MaintainFormModelXtype, MaintainFormModel } from './form.model';
import { FormJdbc } from './components/form.jdbc'; import { FormJdbc, FormJdbcXtype } from './components/form.jdbc';
import { FormJndi } from './components/form.jndi'; import { FormJndiXtype } from './components/form.jndi';
import { FormPlugin } from './components/form.plugin'; import { FormPluginXtype } from './components/form.plugin';
import { connectionType, errorCode } from '@constants/env'; import { connectionType, errorCode } from '@constants/env';
import { ConnectionJDBC, Connection, ResultType } from 'src/modules/crud/crud.typings'; import { ConnectionJDBC, Connection, ResultType } from 'src/modules/crud/crud.typings';
import { DEFAULT_JNDI_DATA, DEFAULT_JDBC_POOL, DATEBASE_FILTER_TYPE } from '@constants/constant'; import { DEFAULT_JNDI_DATA, DEFAULT_JDBC_POOL, DATEBASE_FILTER_TYPE } from '@constants/constant';
import { getJdbcDatabaseType, getChartLength, getAllDatabaseTypes } from '../../../app.service'; import { getJdbcDatabaseType, getChartLength } from '../../../app.service';
import { NAME_MAX_LENGTH } from '../../../app.constant'; import { NAME_MAX_LENGTH } from '../../../app.constant';
import { checkIllegalStrings } from "@core/index"; export const MaintainFormXtype = 'dec.dcm.maintain.form';
@shortcut(MaintainFormXtype)
@shortcut() @store(MaintainFormModelXtype)
@store(MaintainFormModel)
export class MaintainForm extends BI.Widget { export class MaintainForm extends BI.Widget {
static xtype = 'dec.dcm.maintain.form';
static EVENT_TESTCONNECTION = 'EVENT_TEST_CONNECTION';
props = { props = {
connectionType: '', connectionType: '',
}; }
isEdit = false; isEdit = false;
connectionName = ''; connectionName = '';
model: MaintainFormModel['model']; model: MaintainFormModel['model'];
store: MaintainFormModel['store']; store: MaintainFormModel['store'];
@ -30,42 +26,34 @@ export class MaintainForm extends BI.Widget {
watch = { watch = {
saveEvent: () => { saveEvent: () => {
const sonSave = this.form.getSaveFn?.(); if (!this.testValue()) {
if (sonSave) { return;
sonSave().then((success: boolean) => { }
if (success) { if (this.connectionName && !this.model.isCopy) {
this.store.goFirstPage(); const value = this.form.getSubmitValue();
BI.Msg.toast(BI.i18nText("Dec-Basic_Save_Success"), { (value.connectionData as ConnectionJDBC).creator = BI.get(this.getFormData(), 'creator');
level: "success", // DEC-10155 为了适配插件的数据连接,在外层也加一个creator字段
}); value.creator = BI.get(this.getFormData(), 'creator');
} else { this.store.updateConnection(this.connectionName, value).then(result => {
BI.Msg.toast(BI.i18nText("Dec-Basic_Save_Fail"), { if (result.errorCode) {
level: "error", this.showError(result);
});
}
});
//只有外来插件才可以使用是否不执行平台的保存逻辑
if (this.model.datebaseTypeSelected) {
const isPluginDatabase = BI.some(BI.Providers.getProvider('dec.connection.provider.datebase').customDatabaseType, (_index, value) => value.databaseType === this.model.datebaseTypeSelected);
if (isPluginDatabase && this.model.datebaseTypeSelectedOne.isNoSave) {
return;
}
} else {
const databaseType = this.model.connectionSelectedOne.connectionType;
const database = BI.find(getAllDatabaseTypes(), (_index, value) => value.databaseType === databaseType);
if (this.model.connectionSelectedOne.pluginConnection && database?.isNoSave) {
return; return;
} }
} this.store.goFirstPage();
});
} else {
const form = this.form.getSubmitValue();
form.connectionId = this.connectionName;
// DEC-10155 为了适配插件的数据连接,在外层也加一个creator字段
form.creator = Dec ? Dec.personal.username : '';
this.addConnection(form);
} }
this.save();
}, },
testEvent: () => { testEvent: () => {
this.testConnection(); this.testConnection();
}, },
}; }
render() { render() {
const formData = BI.clone(this.getFormData()); const formData = BI.clone(this.getFormData());
@ -73,7 +61,7 @@ export class MaintainForm extends BI.Widget {
formData.connectionName = this.getConnectionName(formData.connectionName); formData.connectionName = this.getConnectionName(formData.connectionName);
this.isEdit = false; this.isEdit = false;
} }
return { return {
type: this.getFormType(), type: this.getFormType(),
formData, formData,
@ -81,7 +69,7 @@ export class MaintainForm extends BI.Widget {
this.form = _ref; this.form = _ref;
}, },
listeners: [{ listeners: [{
eventName: MaintainForm.EVENT_TESTCONNECTION, eventName: 'EVENT_TEST_CONNECTION',
action: () => { action: () => {
this.testConnection(); this.testConnection();
}, },
@ -98,17 +86,17 @@ export class MaintainForm extends BI.Widget {
private getFormType() { private getFormType() {
switch (this.options.connectionType) { switch (this.options.connectionType) {
case connectionType.JDBC: case connectionType.JDBC:
return FormJdbc.xtype; return FormJdbcXtype;
case connectionType.JNDI: case connectionType.JNDI:
return FormJndi.xtype; return FormJndiXtype;
case DATEBASE_FILTER_TYPE.OTHER: case DATEBASE_FILTER_TYPE.OTHER:
return FormJdbc.xtype; return FormJdbcXtype;
default: default:
return FormPlugin.xtype; return FormPluginXtype;
} }
} }
private getFormData(): Connection { private getFormData():Connection {
switch (this.options.connectionType) { switch (this.options.connectionType) {
case connectionType.JDBC: case connectionType.JDBC:
return this.getJdbcConnection(); return this.getJdbcConnection();
@ -121,22 +109,19 @@ export class MaintainForm extends BI.Widget {
} }
} }
private getJdbcConnection(): Connection { private getJdbcConnection():Connection {
const connectionName = this.getConnectionName(); const connectionName = this.getConnectionName();
let editConnection: Connection; let editConnection: Connection;
let connectionData: ConnectionJDBC; let connectionData: ConnectionJDBC;
if (this.model.datebaseTypeSelected) { if (this.model.datebaseTypeSelected) {
const { databaseType: database, fetchSize } = this.model.datebaseTypeSelectedOne;
connectionData = { connectionData = {
...this.model.datebaseTypeSelectedOne, driver: this.model.datebaseTypeSelectedOne.driver,
database, url: this.model.datebaseTypeSelectedOne.url,
database: this.model.datebaseTypeSelectedOne.databaseType,
connectionName, connectionName,
connectionPoolAttr: DEFAULT_JDBC_POOL, connectionPoolAttr: DEFAULT_JDBC_POOL,
port: '', port:'',
host: 'localhost', host: 'localhost',
fetchSize: fetchSize ?? -1,
identity: BI.UUID(),
}; };
editConnection = { editConnection = {
connectionId: '', connectionId: '',
@ -144,22 +129,19 @@ export class MaintainForm extends BI.Widget {
connectionType: connectionType.JDBC, connectionType: connectionType.JDBC,
connectionName, connectionName,
}; };
return editConnection; return editConnection;
} }
this.isEdit = true; this.isEdit = true;
this.connectionName = this.model.connectionSelectedOne.connectionName; this.connectionName = this.model.connectionSelectedOne.connectionName;
const connection = BI.clone(this.model.connectionSelectedOne); const connection = BI.clone(this.model.connectionSelectedOne);
connectionData = connection.connectionData as ConnectionJDBC; const { database, driver } = connection.connectionData as ConnectionJDBC;
const { database, driver } = connectionData; (connection.connectionData as ConnectionJDBC).database = getJdbcDatabaseType(database, driver).databaseType;
connectionData.database = getJdbcDatabaseType(database, driver).databaseType;
if (this.model.isCopy) {
connectionData.identity = BI.UUID();
}
return connection; return connection;
} }
private getJndiConnection(): Connection { private getJndiConnection():Connection {
if (this.model.datebaseTypeSelected) { if (this.model.datebaseTypeSelected) {
return { return {
connectionId: '', connectionId: '',
@ -170,18 +152,18 @@ export class MaintainForm extends BI.Widget {
} }
this.connectionName = this.model.connectionSelectedOne.connectionName; this.connectionName = this.model.connectionSelectedOne.connectionName;
this.isEdit = true; this.isEdit = true;
return this.model.connectionSelectedOne; return this.model.connectionSelectedOne;
} }
private getPluginConnection(): Connection { private getPluginConnection():Connection {
if (!this.model.datebaseTypeSelected) { if (!this.model.datebaseTypeSelected) {
this.connectionName = this.model.connectionSelectedOne.connectionName; this.connectionName = this.model.connectionSelectedOne.connectionName;
this.isEdit = true; this.isEdit = true;
return this.model.connectionSelectedOne; return this.model.connectionSelectedOne;
} }
return { return {
connectionId: '', connectionId: '',
connectionType: this.model.datebaseTypeSelectedOne.databaseType, connectionType: this.model.datebaseTypeSelectedOne.databaseType,
@ -190,37 +172,27 @@ export class MaintainForm extends BI.Widget {
}; };
} }
private testValue(): boolean { private testValue():boolean {
const value = this.form.getSubmitValue(); const value = this.form.getSubmitValue();
if (!value.connectionName) { if (!value.connectionName) {
this.setFromError(BI.i18nText('Dec-Dcm_Connection_ConnectionName_Cannt_Null')); this.setFromError(BI.i18nText('Dec-Dcm_Connection_ConnectionName_Cannt_Null'));
return false; return false;
} }
if (this.connectionName !== value.connectionName) { if (this.connectionName !== value.connectionName) {
const hasNamed = this.model.connections.some(item => item.connectionName === value.connectionName); const hasNamed = this.model.connections.some(item => item.connectionName === value.connectionName);
if (hasNamed) { if (hasNamed) {
this.setFromError(BI.i18nText('Dec-Dcm_Connection_Is_Existence')); this.setFromError(BI.i18nText('Dec-Dcm_Connection_Is_Existence'));
return false; return false;
} }
} }
if (getChartLength(value.connectionName) > NAME_MAX_LENGTH) { if (getChartLength(value.connectionName) > NAME_MAX_LENGTH) {
this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH)); this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH));
return false;
}
if (this.form.validation && !this.form.validation()) {
return false;
}
const result = checkIllegalStrings(value.connectionName);
if (!result.legal) {
this.setFromError(result.errorMsg);
return false; return false;
} }
return true; return true;
} }
@ -230,7 +202,7 @@ export class MaintainForm extends BI.Widget {
BI.Msg.toast(BI.i18nText(result.errorMsg), { BI.Msg.toast(BI.i18nText(result.errorMsg), {
level: 'error', level: 'error',
}); });
return; return;
} }
@ -246,19 +218,14 @@ export class MaintainForm extends BI.Widget {
const formValue = this.form.getSubmitValue(); const formValue = this.form.getSubmitValue();
if (!formValue.connectionName) { if (!formValue.connectionName) {
this.setFromError(BI.i18nText('Dec-Dcm_Connection_ConnectionName_Cannt_Null')); this.setFromError(BI.i18nText('Dec-Dcm_Connection_ConnectionName_Cannt_Null'));
return false; return;
} }
if (getChartLength(formValue.connectionName) > NAME_MAX_LENGTH) { if (getChartLength(formValue.connectionName) > NAME_MAX_LENGTH) {
this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH)); this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH));
return false;
}
if (this.form.validation && !this.form.validation()) {
return false; return false;
} }
if (this.isEdit || this.model.isCopy) { if (this.isEdit || this.model.isCopy) {
formValue.connectionId = this.connectionName; formValue.connectionId = this.connectionName;
} }
@ -270,11 +237,6 @@ export class MaintainForm extends BI.Widget {
private addConnection(form: Connection) { private addConnection(form: Connection) {
this.store.addConnection(form).then(result => { this.store.addConnection(form).then(result => {
if (result.errorCode) { if (result.errorCode) {
if (result.errorCode === DecCst.ErrorCode.NO_IP_AUTHORIZED) {
BI.Msg.toast(BI.i18nText("Dec-Basic_Save_Fail"), {
level: "error",
});
}
if (result.errorCode === errorCode.DUPLICATE_NAMES) { if (result.errorCode === errorCode.DUPLICATE_NAMES) {
if (form.connectionType !== connectionType.JDBC && form.connectionType !== connectionType.JNDI) { if (form.connectionType !== connectionType.JDBC && form.connectionType !== connectionType.JNDI) {
// 如果不是jdbc或jndi,即如果是插件,名称重复的时候需要修改名字重新提交给后台 // 如果不是jdbc或jndi,即如果是插件,名称重复的时候需要修改名字重新提交给后台
@ -292,44 +254,11 @@ export class MaintainForm extends BI.Widget {
level: 'error', level: 'error',
}); });
} }
return; return;
} }
// 新增之后connections待更新,connectionSelected先置空
this.store.setConnectionSelected('');
this.store.goFirstPage(); this.store.goFirstPage();
this.store.setIsCopy(false); this.store.setIsCopy(false);
}); });
} }
private save() {
if (!this.testValue()) {
return;
}
if (this.connectionName && !this.model.isCopy) {
const value = this.form.getSubmitValue();
(value.connectionData as ConnectionJDBC).creator = BI.get(this.getFormData(), 'creator');
// DEC-10155 为了适配插件的数据连接,在外层也加一个creator字段
value.creator = BI.get(this.getFormData(), 'creator');
this.store.updateConnection(this.connectionName, value).then(result => {
if (result.errorCode) {
if (result.errorCode === DecCst.ErrorCode.NO_IP_AUTHORIZED) {
BI.Msg.toast(BI.i18nText("Dec-Basic_Save_Fail"), {
level: "error",
});
}
this.showError(result);
return;
}
this.store.goFirstPage();
});
} else {
const form = this.form.getSubmitValue();
form.connectionId = this.connectionName;
// DEC-10155 为了适配插件的数据连接,在外层也加一个creator字段
form.creator = Dec ? Dec.personal.username : '';
this.addConnection(form);
}
}
} }

23
src/modules/pages/maintain/maintain.model.ts

@ -1,19 +1,18 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { AppModel } from '../../app.model'; import { AppModel } from '../../app.model';
@model() export const MaintainModelXtype = 'dec.dcm.model.maintain';
@model(MaintainModelXtype)
export class MaintainModel extends Model<{ export class MaintainModel extends Model<{
types : { context : {
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
connections: AppModel['TYPE']['connections']; connections: AppModel['$$childContext']['connections'];
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
datebaseTypeSelectedOne: AppModel['TYPE']['datebaseTypeSelectedOne']; datebaseTypeSelectedOne: AppModel['$$childContext']['datebaseTypeSelectedOne'];
connectionSelectedOne: AppModel['TYPE']['connectionSelectedOne']; connectionSelectedOne: AppModel['$$childContext']['connectionSelectedOne'];
isCopy: AppModel['TYPE']['isCopy']; isCopy: AppModel['$$childContext']['isCopy'];
}, }
context: MaintainModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.maintain'; context = ['pageIndex', 'datebaseTypeSelected', 'datebaseTypeSelectedOne', 'connectionSelectedOne', 'isCopy'];
context = <const>['pageIndex', 'datebaseTypeSelected', 'datebaseTypeSelectedOne', 'connectionSelectedOne', 'isCopy'];
actions = { actions = {
setPageIndex:(index: string) => { setPageIndex:(index: string) => {

46
src/modules/pages/maintain/maintain.ts

@ -1,7 +1,7 @@
import { Vtape, Label, VerticalAdapt, ListView, IconButton } from 'ui';
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { MaintainModel } from './maintain.model'; import { MaintainModel, MaintainModelXtype } from './maintain.model';
import { MaintainForm } from './forms/form'; import { MaintainFormXtype } from './forms/form';
import { LinkButton } from 'src/modules/components/link_button/link';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { ApiFactory } from 'src/modules/crud/apiFactory'; import { ApiFactory } from 'src/modules/crud/apiFactory';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
@ -9,35 +9,32 @@ import './maintain.less';
import { connectionType } from '@constants/env'; import { connectionType } from '@constants/env';
import { getJdbcDatabaseType, getTextByDatabaseType } from '../../app.service'; import { getJdbcDatabaseType, getTextByDatabaseType } from '../../app.service';
import { ConnectionJDBC } from 'src/modules/crud/crud.typings'; import { ConnectionJDBC } from 'src/modules/crud/crud.typings';
import { ButtonGroup } from '@fui/core';
@shortcut() export const MaintainXtype = 'dec.dcm.maintain';
@store(MaintainModel) @shortcut(MaintainXtype)
@store(MaintainModelXtype)
export class Maintain extends BI.Widget { export class Maintain extends BI.Widget {
static xtype = 'dec.dcm.maintain';
model: MaintainModel['model']; model: MaintainModel['model'];
store: MaintainModel['store']; store: MaintainModel['store'];
buttonGroup: ButtonGroup; listView: any;
socketTip: LinkButton;
render() { render() {
const { isEdit, databaseType } = this.getEditConnection(); const { isEdit, databaseType } = this.getEditConnection();
const titleText = getTextByDatabaseType(databaseType); const titleText = getTextByDatabaseType(databaseType);
return { return {
type: BI.VTapeLayout.xtype, type: Vtape,
hgap: 16, hgap: 5,
items: [ items: [
{ {
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
cls: 'bi-border-bottom', cls: 'bi-border-bottom',
height: 40, height: 40,
hgap: 5, hgap: 5,
items: [ items: [
{ {
type: BI.IconButton.xtype, type: IconButton,
$value: 'back-databases', $value: 'back-databases',
cls: 'dcm-back-font', cls: 'dcm-back-font',
height: 15, height: 15,
@ -47,26 +44,16 @@ export class Maintain extends BI.Widget {
}, },
}, },
{ {
type: BI.Label.xtype, type: Label,
text: titleText, text: titleText,
height: 15, height: 15,
}, },
{
type: LinkButton.xtype,
invisible: true,
lgap: 10,
text: BI.i18nText('Dec-Dcm_Socket_Unable_Connect_Tip'),
link: api.getHyperlink(DecCst.Hyperlink.WEBSOCKET_CONNECT),
ref: (_ref: LinkButton) => {
this.socketTip = _ref;
},
},
], ],
}, },
{ {
type: BI.ButtonGroup.xtype, type: ListView,
ref: (_ref: ButtonGroup) => { ref: (_ref: any) => {
this.buttonGroup = _ref; this.listView = _ref;
}, },
items: this.renderItems(), items: this.renderItems(),
}, },
@ -79,7 +66,6 @@ export class Maintain extends BI.Widget {
BI.Msg.toast(BI.i18nText('Dec-Dcm_Socket_Unable_Connect'), { BI.Msg.toast(BI.i18nText('Dec-Dcm_Socket_Unable_Connect'), {
level: 'warning', level: 'warning',
}); });
this.socketTip.setVisible(true);
} }
} }
@ -87,7 +73,7 @@ export class Maintain extends BI.Widget {
const { type } = this.getEditConnection(); const { type } = this.getEditConnection();
return [{ return [{
type: MaintainForm.xtype, type: MaintainFormXtype,
connectionType: type, connectionType: type,
}]; }];
} }

96
src/modules/pages/setting/setting.ts

@ -1,96 +0,0 @@
import { shortcut } from '@core/core';
import { ApiFactory } from 'src/modules/crud/apiFactory';
const api = new ApiFactory().create();
@shortcut()
export class TimeOutSetting extends BI.Widget {
public static xtype = 'dec.dcm.page.timeout.setting';
public props = {
value: 0,
};
beforeRender(cb: Function) {
const self = this;
api.getTimeOut().then(res => {
self.props.value = res.data.count;
cb();
});
}
public render() {
const { value } = this.props;
const self = this;
return {
type: 'bi.vtape',
cls: 'bi-background',
items: [{
type: 'dec.setting.header',
height: 40,
listeners: [{
eventName: 'EVENT_CANCEL',
action: function () {
self.fireEvent('EVENT_CHANGE');
},
}, {
eventName: 'EVENT_SAVE',
action: function () {
api.putTimeOut(Number(self.editor.getValue()));
self.fireEvent('EVENT_CHANGE');
},
}],
}, {
type: 'bi.vertical',
cls: 'bi-card',
vgap: 10,
items: [
{
el: {
type: 'bi.vertical_adapt',
cls: 'bi-border-bottom',
height: 40,
items: [{
type: 'bi.label',
textAlign: 'left',
width: 120,
cls: 'dec-font-weight-bold',
text: BI.i18nText('Dec-Dcm_Connection_Timeout_Detection'),
}]
}, tgap: -10, hgap: 16,
},
{
type: 'bi.vertical_adapt',
hgap: 16,
items: [{
type: 'dec.label.editor.item',
text: BI.i18nText('Dec-Over_Time'),
textWidth: 100,
editorWidth: 80,
allowBlank: false,
value: value,
validationChecker: function(v) {
return BI.isPositiveInteger(v);
},
errorText: BI.i18nText('BI-Please_Input_Positive_Integer'),
ref: function (_ref) {
self.editor = _ref;
},
}, {
el: {
type: 'bi.label',
text: BI.i18nText('Dec-Dcm_Connection_Timeout_Millisecond'),
},
lgap: 10,
}]
},
]
}],
ref: function (_ref) {
self.setting = _ref;
},
};
}
}

16
src/modules/title/title.model.ts

@ -1,17 +1,15 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { AppModel } from '../app.model'; import { AppModel } from '../app.model';
@model() export const TitleModelXtype = 'dec.dcm.model.title';
@model(TitleModelXtype)
export class TitleModel extends Model<{ export class TitleModel extends Model<{
types: { context : {
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
}, }
context: TitleModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.title'; context = ['pageIndex', 'datebaseTypeSelected']
context = <const>['pageIndex', 'datebaseTypeSelected']
actions = { actions = {
setPageIndex: (index: string) => { setPageIndex: (index: string) => {

42
src/modules/title/title.ts

@ -1,20 +1,19 @@
import { LeftRightVerticalAdapt, VerticalAdapt, LinearSegment, Tab } from 'ui';
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { TitleModel } from './title.model'; import { TitleModel, TitleModelXtype } from './title.model';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { TitleDatabase } from './title_database/title_datebase'; import { TitleDatabase } from './title_database/title_datebase';
import { TitleMaintain } from './title_maintain/title_maintain'; import { TitleMaintain } from './title_maintain/title_maintain';
import { LinearSegment, Tab } from '@fui/core'; export const TitleXtype = 'dec.dcm.title';
@shortcut() @shortcut(TitleXtype)
@store(TitleModel) @store(TitleModelXtype)
export class Title extends BI.Widget { export class Title extends BI.Widget {
static xtype = 'dec.dcm.title';
props = { props = {
baseCls: '', baseCls: 'bi-card',
} }
tab: Tab; tab: any;
linearSegment: LinearSegment; linearSegment: any;
model: TitleModel['model']; model: TitleModel['model'];
store: TitleModel['store']; store: TitleModel['store'];
@ -28,26 +27,18 @@ export class Title extends BI.Widget {
render() { render() {
return { return {
type: BI.LeftRightVerticalAdaptLayout.xtype, type: LeftRightVerticalAdapt,
items: { items: {
left: [ left: [
{ {
type: 'bi.icon_button', type: LinearSegment,
cls: 'setting-font',
_lgap: 15,
handler: () => {
this.fireEvent('EVENT_CLICK_SETTING');
},
},
{
type: BI.LinearSegment.xtype,
cls: 'bi-font-bold', cls: 'bi-font-bold',
height: 40, height: 40,
hgap: 10, hgap: 10,
layouts: [{ layouts: [{
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
}], }],
ref: (_ref: LinearSegment) => { ref: (_ref: any) => {
this.linearSegment = _ref; this.linearSegment = _ref;
}, },
items: [ items: [
@ -75,22 +66,21 @@ export class Title extends BI.Widget {
], ],
right: [ right: [
{ {
type: BI.Tab.xtype, type: Tab,
height: 40, height: 40,
showIndex: this.model.pageIndex, showIndex: this.model.pageIndex,
width:200, ref: (_ref: any) => {
ref: (_ref: Tab) => {
this.tab = _ref; this.tab = _ref;
}, },
cardCreator: (index: string) => { cardCreator: (index: string) => {
switch (index) { switch (index) {
case PAGE_INDEX.DATEBASE: case PAGE_INDEX.DATEBASE:
return { return {
type: TitleDatabase.xtype, type: TitleDatabase,
}; };
case PAGE_INDEX.MAINTAIN: case PAGE_INDEX.MAINTAIN:
return { return {
type: TitleMaintain.xtype, type: TitleMaintain,
}; };
default: default:
return { return {

16
src/modules/title/title_database/title_datebase.model.ts

@ -1,17 +1,15 @@
import { model, Model } from '@core/core'; import { model, Model } from '@core/core';
import { AppModel } from 'src/modules/app.model'; import { AppModel } from 'src/modules/app.model';
@model() export const TitleDatebaseModelXtype = 'dec.dcm.model.title_datebase';
@model(TitleDatebaseModelXtype)
export class TitleDatebaseModel extends Model<{ export class TitleDatebaseModel extends Model<{
types: { context: {
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
datebaseTypeSelected: AppModel['TYPE']['datebaseTypeSelected']; datebaseTypeSelected: AppModel['$$childContext']['datebaseTypeSelected'];
}, }
context: TitleDatebaseModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.title_datebase'; context = ['pageIndex', 'datebaseTypeSelected'];
context = <const>['pageIndex', 'datebaseTypeSelected'];
actions = { actions = {
setPageIndex: (index: string) => { setPageIndex: (index: string) => {

29
src/modules/title/title_database/title_datebase.ts

@ -1,17 +1,17 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { TitleDatebaseModel } from './title_datebase.model'; import { Right, Button, VerticalAdapt } from 'ui';
import { TitleDatebaseModel, TitleDatebaseModelXtype } from './title_datebase.model';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { Button } from '@fui/core';
@shortcut() export const TitleDatabase = 'dec.dcm.title.datebase';
@store(TitleDatebaseModel)
export class TitleDatabase extends BI.Widget {
static xtype = 'dec.dcm.title.datebase';
@shortcut(TitleDatabase)
@store(TitleDatebaseModelXtype)
export class TitleDatabaseWidget extends BI.Widget {
store: TitleDatebaseModel['store']; store: TitleDatebaseModel['store'];
model: TitleDatebaseModel['model']; model: TitleDatebaseModel['model'];
submitButton: Button; submitButton: any;
watch = { watch = {
datebaseTypeSelected: (datebaseTypeSelected: string) => { datebaseTypeSelected: (datebaseTypeSelected: string) => {
@ -21,27 +21,27 @@ export class TitleDatabase extends BI.Widget {
render() { render() {
return { return {
type: BI.FloatRightLayout.xtype, type: Right,
items: [{ items: [{
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
height: 40, height: 40,
rgap: 16, rgap: 5,
items: [ items: [
{ {
type: BI.Button.xtype, type: Button,
$value: 'title-database-cancel', $value: 'title-database-cancel',
text: BI.i18nText('BI-Basic_Cancel'), text: BI.i18nText('BI-Basic_Cancel'),
light: true, level: 'ignore',
handler: () => { handler: () => {
this.store.setPageIndex(PAGE_INDEX.CONNECTION); this.store.setPageIndex(PAGE_INDEX.CONNECTION);
}, },
}, },
{ {
type: BI.Button.xtype, type: Button,
$value: 'title-database-save', $value: 'title-database-save',
text: BI.i18nText('BI-Basic_Save'), text: BI.i18nText('BI-Basic_Save'),
disabled: !this.model.datebaseTypeSelected, disabled: !this.model.datebaseTypeSelected,
ref: (_ref: Button) => { ref: (_ref: any) => {
this.submitButton = _ref; this.submitButton = _ref;
}, },
handler: () => { handler: () => {
@ -49,7 +49,6 @@ export class TitleDatabase extends BI.Widget {
}, },
}, },
], ],
_rgap: -16,
}], }],
}; };
} }

24
src/modules/title/title_maintain/title_maintain.model.ts

@ -2,22 +2,18 @@ import { model, Model } from '@core/core';
import { AppModel } from 'src/modules/app.model'; import { AppModel } from 'src/modules/app.model';
import { ApiFactory } from 'src/modules/crud/apiFactory'; import { ApiFactory } from 'src/modules/crud/apiFactory';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
export const TitleMaintainModelXtype = 'dec.dcm.model.title_maintain';
@model() @model(TitleMaintainModelXtype)
export class TitleMaintainModel extends Model<{ export class TitleMaintainModel extends Model<{
types : { context : {
pageIndex: AppModel['TYPE']['pageIndex']; pageIndex: AppModel['$$childContext']['pageIndex'];
saveEvent: AppModel['TYPE']['saveEvent']; saveEvent: AppModel['$$childContext']['saveEvent'];
connectionSelected: AppModel['TYPE']['connectionSelected']; connectionSelected: AppModel['$$childContext']['connectionSelected'];
testEvent: AppModel['TYPE']['testEvent']; testEvent: AppModel['$$childContext']['testEvent'];
isCopy: AppModel['TYPE']['isCopy']; isCopy: AppModel['$$childContext']['isCopy'];
noTestConnection: AppModel['TYPE']['noTestConnection']; }
},
context: TitleMaintainModel['context'];
}> { }> {
static xtype = 'dec.dcm.model.title_maintain'; context = ['pageIndex', 'saveEvent', 'testEvent', 'connectionSelected', 'isCopy'];
context = <const>['pageIndex', 'saveEvent', 'testEvent', 'connectionSelected', 'isCopy', 'noTestConnection'];
actions = { actions = {
setPageIndex: (index: string) => { setPageIndex: (index: string) => {

36
src/modules/title/title_maintain/title_maintain.ts

@ -1,29 +1,27 @@
import { shortcut, store } from '@core/core'; import { shortcut, store } from '@core/core';
import { TitleMaintainModel } from './title_maintain.model'; import { Right, Button, VerticalAdapt } from 'ui';
import { TitleMaintainModel, TitleMaintainModelXtype } from './title_maintain.model';
import { PAGE_INDEX } from '@constants/constant'; import { PAGE_INDEX } from '@constants/constant';
import { Button } from '@fui/core';
@shortcut()
@store(TitleMaintainModel)
export class TitleMaintain extends BI.Widget {
static xtype = 'dec.dcm.title.maintain';
export const TitleMaintain = 'dec.dcm.title.maintain';
@shortcut(TitleMaintain)
@store(TitleMaintainModelXtype)
export class TitleMaintainWidget extends BI.Widget {
store: TitleMaintainModel['store']; store: TitleMaintainModel['store'];
model: TitleMaintainModel['model']; model: TitleMaintainModel['model'];
render() { render() {
return { return {
type: BI.FloatRightLayout.xtype, type: Right,
items: [{ items: [{
type: BI.VerticalAdaptLayout.xtype, type: VerticalAdapt,
height: 40, height: 40,
rgap: 5,
items: [ items: [
{ {
type: BI.Button.xtype, type: Button,
$value: 'title-maintain-cancel', $value: 'title-maintain-cancel',
text: BI.i18nText('BI-Basic_Cancel'), text: BI.i18nText('BI-Basic_Cancel'),
clear: true, level: 'ignore',
_rgap: 16,
handler: () => { handler: () => {
this.store.setIsCopy(false); this.store.setIsCopy(false);
this.store.setPageIndex(PAGE_INDEX.CONNECTION); this.store.setPageIndex(PAGE_INDEX.CONNECTION);
@ -31,22 +29,16 @@ export class TitleMaintain extends BI.Widget {
}, },
}, },
{ {
type: BI.Button.xtype, type: Button,
ref: (_ref) => {
this.testConnectionBtn = _ref;
},
invisible: () => this.model.noTestConnection,
_rgap: 16,
$value: 'title-maintain-connection-test', $value: 'title-maintain-connection-test',
text: BI.i18nText('Dec-Dcm_Connection_Test'), text: BI.i18nText('Dec-Dcm_Connection_Test'),
light: true, level: 'ignore',
handler: () => { handler: () => {
this.store.setTestEvent(); this.store.setTestEvent();
}, },
}, },
{ {
type: BI.Button.xtype, type: Button,
_rgap: 16,
$value: 'title-maintain-save', $value: 'title-maintain-save',
text: BI.i18nText('BI-Basic_Save'), text: BI.i18nText('BI-Basic_Save'),
handler: () => { handler: () => {

74
src/ui/fineui.ts

@ -0,0 +1,74 @@
export const Icon = 'bi.icon';
export const IconTextItem = 'bi.icon_text_item';
export const IconTextIconItem = 'bi.icon_text_icon_item';
export const IconButton = 'bi.icon_button';
export const IconChangeButton = 'bi.icon_change_button';
export const TextButton = 'bi.text_button';
export const DownListCombo = 'bi.down_list_combo';
export const Label = 'bi.label';
export const SmallTextEditor = 'bi.small_text_editor';
export const MultiFileEditor = 'bi.multifile_editor';
export const SignEditor = 'bi.sign_editor';
export const Button = 'bi.button';
export const TextEditor = 'bi.text_editor';
export const MultiSelectInsertCombo = 'bi.multi_select_insert_combo';
export const MultiSelectCombo = 'bi.multi_select_combo';
export const ButtonGroup = 'bi.button_group';
export const AllValueChooserCombo = 'bi.all_value_chooser_combo';
export const TextAreaEditor = 'bi.textarea_editor';
export const MultiSelectItem = 'bi.multi_select_item';
export const BarPopOver = 'bi.bar_popover';
export const DynamicDateCombo = 'bi.dynamic_date_combo';
export const DynamicDateTimeCombo = 'bi.dynamic_date_time_combo';
export const MultiTreeCombo = 'bi.multi_tree_combo';
export const RichEditor = 'bi.rich_editor';
export const NicEditor = 'bi.nic_editor';
export const Editor = 'bi.editor';
export const MultiTreePopupView = 'bi.multi_tree_popup_view';
export const SingleSelectRadioItem = 'bi.single_select_radio_item';
export const SingleSelectInsertCombo = 'bi.single_select_insert_combo';
export const SingleSelectCombo = 'bi.single_select_combo';
export const Tab = 'bi.tab';
export const DynamicYearMonthCombo = 'bi.dynamic_year_month_combo';
export const Text = 'bi.text';
export const Combo = 'bi.combo';
export const TimeCombo = 'bi.time_combo';
export const IFrame = 'bi.iframe';
export const MultiTreeInsertCombo = 'bi.multi_tree_insert_combo';
export const MultiTreeListCombo = 'bi.multi_tree_list_combo';
export const MultilayerSingleTreeCombo = 'bi.multilayer_single_tree_combo';
export const MultilayerSelectTreeCombo = 'bi.multilayer_select_tree_combo';
export const AsyncTree = 'bi.async_tree';
export const ListAsyncTree = 'bi.list_async_tree';
export const MultilayerSingleTreePopup = 'bi.multilayer_single_tree_popup';
export const MultilayerSelectTreePopup = 'bi.multilayer_select_tree_popup';
export const IconLabel = 'bi.icon_label';
export const Radio = 'bi.radio';
export const LinearSegment = 'bi.linear_segment';
export const SearchEditor = 'bi.search_editor';
export const Img = 'bi.img';
export const BubbleCombo = 'bi.bubble_combo';
export const TextBubblePopupBarView = 'bi.text_bubble_bar_popup_view';
export const TextValueCombo = 'bi.text_value_combo';
export const Loader = 'bi.loader';
export const EdirotIconCheckCombo = 'bi.editor_icon_check_combo';
// 布局
export const VerticalAdapt = 'bi.vertical_adapt';
export const Vtape = 'bi.vtape';
export const CenterAdapt = 'bi.center_adapt';
export const Htape = 'bi.htape';
export const Layout = 'bi.layout';
export const Absolute = 'bi.absolute';
export const Vertical = 'bi.vertical';
export const Left = 'bi.left';
export const Right = 'bi.right';
export const HorizontalAdapt = 'bi.horizontal_adapt';
export const AbsoluteCenterAdapt = 'bi.absolute_center_adapt';
export const TableAdapt = 'bi.table_adapt';
export const RightVerticalAdapt = 'bi.right_vertical_adapt';
export const LeftRightVerticalAdapt = 'bi.left_right_vertical_adapt';
export const ListView = 'bi.list_view';
export const VirtualGroup = 'bi.virtual_group';
export const HorizotalAuto = 'bi.horizontal_auto';
export const Horizotal = 'bi.horizontal';
export const FloatCenter = 'bi.float_center';

1
src/ui/index.ts

@ -0,0 +1 @@
export * from './fineui';

27
tsconfig.json

@ -5,8 +5,8 @@
"module": "es2015", "module": "es2015",
"moduleResolution": "node", "moduleResolution": "node",
"lib": [ "lib": [
"es2017", "es2017",
"dom" "dom"
], ],
"declaration": true, "declaration": true,
"experimentalDecorators": true, "experimentalDecorators": true,
@ -19,23 +19,12 @@
// "noUnusedParameters": true, // "noUnusedParameters": true,
// "noImplicitReturns": true, // "noImplicitReturns": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"skipLibCheck": false,
"paths": { "paths": {
"ui": [ "ui": ["./src/ui"],
"./src/ui" "ReportCst": ["./private/constants"],
], "types": ["./types/index.d.ts"],
"ReportCst": [ "@core/*": ["./src/modules/core/*"],
"./private/constants" "@constants/*": ["./src/modules/constants/*"]
],
"types": [
"./types/index.d.ts"
],
"@core/*": [
"./src/modules/core/*"
],
"@constants/*": [
"./src/modules/constants/*"
]
} }
}, },
"include": [ "include": [
@ -43,6 +32,6 @@
"src/**/*.ts", "src/**/*.ts",
"private/*.ts", "private/*.ts",
"private/**/*.ts", "private/**/*.ts",
"types" "types/globals.d.ts"
] ]
} }

26
types/globals.d.ts vendored

@ -2,9 +2,7 @@ interface Obj {
[key: string]: any; [key: string]: any;
} }
type RequestFunction = (url: string, data: any, callback: (re: any) => void) => void; declare let BI: Obj & import('fineui')._BI;
declare let BI: Obj & import('@fui/core').BI & import('@fui/materials').BI;
declare const Fix: Obj; declare const Fix: Obj;
declare const DecCst: Obj; declare const DecCst: Obj;
declare const Dec: { declare const Dec: {
@ -12,21 +10,11 @@ declare const Dec: {
socket: { socket: {
connected: boolean; connected: boolean;
}; };
system: {};
personal: { personal: {
username: string; username: string;
}; };
Utils: Obj; reqGet: (url: string, data: any, callback: (re: any) => void) => void;
reqByEncrypt: (method: AxiosType.X_Method, url: string, data?: any, config?: AxiosType.X_AxiosRequestConfig) => {}, reqPost: (url: string, data: any, callback: (re: any) => void) => void;
socketEmit: (type: string, name: string, callback: (re: any) => void) => void; reqPut: (url: string, data: any, callback: (re: any) => void) => void;
// req reqDelete: (url: string, data: any, callback: (re: any) => void) => void;
reqGet: RequestFunction; };
reqPost: RequestFunction;
reqPut: RequestFunction;
reqDelete: RequestFunction;
// reqHandle
reqGetHandle: RequestFunction;
reqPostHandle: RequestFunction;
reqPutHandle: RequestFunction;
reqDeleteHandle: RequestFunction;
};

9
types/request.d.ts vendored

@ -1,9 +0,0 @@
import { Method, AxiosRequestConfig } from 'axios';
declare namespace AxiosType {
type X_Method = Method
interface X_AxiosRequestConfig extends AxiosRequestConfig { }
}
export = AxiosType;
export as namespace AxiosType;

2
webpack/webpack.common.js

@ -49,7 +49,7 @@ module.exports = {
options: { options: {
plugins: [vars({ plugins: [vars({
variables: { variables: {
fontUrl: '../node_modules/@fui/core/dist/font/', fontUrl: '../node_modules/fineui/dist/font/',
imageUrl: '/webroot/decision/resources?path=/com/fr/web/resources/dist/images/1x', imageUrl: '/webroot/decision/resources?path=/com/fr/web/resources/dist/images/1x',
image2xUrl: '/webroot/decision/resources?path=/com/fr/web/resources/dist/images/2x', image2xUrl: '/webroot/decision/resources?path=/com/fr/web/resources/dist/images/2x',
} }

5
webpack/webpack.dev.js

@ -6,7 +6,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const chokidar = require('chokidar'); const chokidar = require('chokidar');
const { execSync } = require('child_process'); const { execSync } = require('child_process');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const dirs = require('./dirs'); const dirs = require('./dirs');
const common = require('./webpack.common.js'); const common = require('./webpack.common.js');
@ -65,9 +65,6 @@ module.exports = merge(common, {
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../index.html'), template: path.resolve(__dirname, '../index.html'),
}), }),
new ForkTsCheckerWebpackPlugin({
watch: ['./src'],
}),
new OptimizeCssAssetsPlugin({ new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g, assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'), cssProcessor: require('cssnano'),

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

Loading…
Cancel
Save