Browse Source

feat: 完成数据连接的修改删除复制等功能

master
alan 6 years ago
parent
commit
933aa8145d
  1. 22
      src/app/app.component.scss
  2. 3
      src/app/app.model.ts
  3. 23
      src/app/link_set/left/left_item/left.item.component.ts
  4. 87
      src/app/link_set/left/left_item/left.item.icon.component.ts
  5. 48
      src/app/link_set/left/left_item/left.item.model.ts
  6. 48
      src/app/link_set/right/right_detail/right.detail.component.ts
  7. 6
      src/app/link_set/right/right_detail/right.detail.model.ts
  8. 260
      src/app/link_set/right/right_edit/right.edit.component.ts
  9. 41
      src/app/link_set/right/right_edit/right.edit.constant.ts
  10. 11
      src/app/link_set/right/right_edit/right.edit.model.ts
  11. 48
      src/app/link_set/right/right_title/right.title.component.ts
  12. 15
      src/app/link_set/right/right_title/right.title.model.ts
  13. 8
      src/app/link_set/select/select.model.ts
  14. 6
      src/shared/components/both.side.component.ts
  15. 29
      src/shared/components/form.item.component.ts
  16. 45
      src/shared/crud/crud.request.ts
  17. 2
      src/shared/crud/curd.mock.ts
  18. 34
      src/shared/service/dialog.service.ts
  19. 3
      src/ui/fineui.ts

22
src/app/app.component.scss

@ -55,12 +55,17 @@
&:hover{
background-color: rgba(54,133,242,.05);
.icons{
display: inline;
.action-icon{
visibility: visible !important;
}
}
}
.icons{
float: right !important;
display: none;
.action-icon{
visibility: hidden;
}
.b-font{
font-size: 16px;
}
@ -100,6 +105,9 @@
}
.right-show{
margin: 10px;
.right-form{
width: 100%;
}
}
}
}
@ -113,6 +121,16 @@
flex-shrink: 0;
font-weight: 700;
}
.hint{
padding-left: 5px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
position: relative;
flex-shrink: 0;
margin-left: 5px;
color: #9ea6b2;
}
}
.shared-component-title{
height: 24px;

3
src/app/app.model.ts

@ -4,12 +4,13 @@ import {LinkType} from '@ui/type';
const linkList: LinkType[] = [];
const Model: ModelType = {
childContext: ['tab', 'linkList', 'linkSelected'],
childContext: ['tab', 'linkList', 'linkSelected', 'linkUpdate'],
state () {
return {
tab: '数据连接管理',
linkList,
linkSelected: {},
linkUpdate: {},
};
},
computed: {

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

@ -1,4 +1,5 @@
import {WidgetType, Left, Label, Icon} from '@ui';
import ItemIcon from './left.item.icon.component';
import LeftItemModel from './left.item.model';
const className = 'fr.component.linkSet.left.item';
const Widget: WidgetType = {
@ -11,7 +12,7 @@ const Widget: WidgetType = {
return BI.Models.getModel(LeftItemModel);
},
render() {
const {title, extraCls, creator, text} = this.options;
const {title, extraCls, creator, text, id} = this.options;
return {
type: Left,
@ -38,32 +39,28 @@ const Widget: WidgetType = {
cls: 'icons',
items: [
{
type: Icon,
type: ItemIcon,
cls: 'link-text-font',
height: 24,
width: 26,
title: '测试连接',
id,
},
{
type: Icon,
type: ItemIcon,
cls: 'copy-font',
height: 24,
width: 26,
title: '复制',
id,
},
{
type: Icon,
type: ItemIcon,
cls: 'info-font',
height: 24,
width: 26,
title: `类型:${text === 'DESIGNER' ? '其他' : text} \r\n创建者:${creator}`,
id,
},
{
type: Icon,
type: ItemIcon,
cls: 'delete-font',
height: 24,
width: 26,
title: '删除',
id,
},
],
},

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

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

48
src/app/link_set/left/left_item/left.item.model.ts

@ -1,5 +1,7 @@
import {LinkType} from '@ui/type';
import {deleteConnection, testConnection} from '@shared/crud/crud.request';
import {databaseTyle, getCnnectionName} from '../../select/select.service';
import {confirm} from '@shared/service/dialog.service';
const className = 'fr.model.linkSet.left.item';
const Model = BI.inherit(Fix.Model, {
context: ['linkList', 'linkSelected'],
@ -10,12 +12,54 @@ const Model = BI.inherit(Fix.Model, {
if (item.connectionName === name) {
this.model.linkSelected = {
...item,
idEdit: false,
isSelected: false,
};
}
});
this.model.linkList = [...this.model.linkList];
},
onIconClick(title: string, id: string) {
switch (title) {
case '删除':
deleteConnection(id, (res: string) => {
});
break;
case '测试连接':
testConnection(id, (res: any) => {
});
break;
case '复制':
this.copyLink(id);
break;
default:
break;
}
},
copyLink(id: string) {
const name = getCnnectionName(this.model.linkList);
let data = {};
this.model.linkList.forEach((item: LinkType) => {
if (item.connectionId === id) {
data = item;
}
});
this.model.linkList.push({
...data,
connectionName:name,
isSelected: true,
});
this.model.linkSelected = {
...data,
isSelected: true,
connectionName:name,
};
this.model.linkUpdate = {
...data,
connectionName:name,
};
},
},
});
BI.model(className, Model);

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

@ -1,20 +1,62 @@
import {WidgetType, Vertical, Left, Label, Button} from '@ui/index';
import RightDetailModel from './right.detail.model';
import Title from '../right_title/right.title.component';
import RightShow from '../right_show/right.show.component';
import RightEdit from '../right_edit/right.edit.component';
import {LinkType} from '@ui/type';
const className = 'fr.component.right.detail';
let rightDetail: any = null;
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(RightDetailModel);
},
watch:{
linkSelected(linkSelected: LinkType) {
if (linkSelected.isSelected) {
rightDetail.populate(BI.createItems([
{
type: Title,
isEdit: true,
linkSelected,
}, {
type: RightEdit,
linkSelected,
},
]));
} else {
rightDetail.populate(BI.createItems([
{
type: Title,
isEdit: false,
linkSelected,
}, {
type: RightShow,
linkSelected,
},
]));
}
},
},
render() {
return {
type: Vertical,
cls:'right-content',
items: [
ref(_ref: any) {
rightDetail = _ref;
},
};
},
mounted() {
rightDetail.populate(BI.createItems([
{
type: Title,
isEdit: false,
linkSelected:false,
}, {
type: RightShow,
linkSelected:false,
},
],
};
]));
},
};
BI.shortcut(className, BI.inherit(BI.Widget, Widget));

6
src/app/link_set/right/right_detail/right.detail.model.ts

@ -0,0 +1,6 @@
const RightDetailModel = 'fr.model.linkSet.right.detail';
const Model = BI.inherit(Fix.Model, {
context: ['linkList', 'linkSelected'],
});
BI.model(RightDetailModel, Model);
export default RightDetailModel;

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

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

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

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

11
src/app/link_set/right/right_edit/right.edit.model.ts

@ -0,0 +1,11 @@
const RightEditModel = 'fr.model.linkSet.right.edit';
const Model = BI.inherit(Fix.Model, {
context: ['linkList', 'linkSelected', 'linkUpdate'],
actions: {
setLinkUpdate(value: any) {
this.model.linkUpdate = value;
},
},
});
BI.model(RightEditModel, Model);
export default RightEditModel;

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

@ -1,7 +1,17 @@
import {WidgetType, Left, Label, Button} from '@ui/index';
import RightTitleModel from './right.title.model';
import {LinkType} from '@ui/type';
import {addConnection, updateConnection} from '@shared/crud/crud.request';
const className = 'fr.component.right.title';
const Widget: WidgetType = {
_store() {
return BI.Models.getModel(RightTitleModel);
},
render() {
const linkSelected: LinkType = this.model.linkSelected;
const that = this;
const {isEdit} = this.options;
return {
type: Left,
height: 40,
@ -10,13 +20,49 @@ const Widget: WidgetType = {
{
type: Label,
cls: 'right-title-text',
text: '数据连接(APACHE KYLIN)',
text: `数据连接(${linkSelected.databaseType.toLocaleUpperCase().replace('-', ' ')})`,
},
{
type: Button,
cls:'right-title-button',
invisible: isEdit,
text: '编辑',
handler() {
that.store.setEdit(true);
},
},
{
type: Button,
cls:'right-title-button',
invisible: !isEdit,
text: '保存',
handler() {
if (that.model.linkUpdate.connectionId) {
addConnection(that.model.linkUpdate, (res: string) => {
if (res === 'success') {
that.store.setEdit(false);
}
});
} else {
updateConnection(that.model.linkUpdate, (res: string) => {
if (res === 'success') {
that.store.setEdit(false);
}
});
}
},
},
{
type: Button,
cls:'right-title-button',
invisible: !isEdit,
level: 'ignore',
text: '取消',
handler() {
that.store.setEdit(false);
},
},
],
};
},

15
src/app/link_set/right/right_title/right.title.model.ts

@ -0,0 +1,15 @@
const RightTitleModel = 'fr.model.linkSet.right.title';
const Model = BI.inherit(Fix.Model, {
context: ['linkList', 'linkSelected', 'linkUpdate'],
actions: {
setEdit(type: boolean) {
this.model.linkSelected = {
...this.model.linkSelected,
isSelected: type,
};
this.model.linkUpdate = this.model.linkSelected;
},
},
});
BI.model(RightTitleModel, Model);
export default RightTitleModel;

8
src/app/link_set/select/select.model.ts

@ -3,7 +3,7 @@ import {databaseTyle, getCnnectionName} from './select.service';
const className = 'fr.model.linkset.select';
const Model = BI.inherit(Fix.Model, {
context: ['linkList', 'linkSelected'],
context: ['linkList', 'linkSelected', 'linkUpdate'],
actions: {
setNewLink(value: string) {
const name = getCnnectionName(this.model.linkList);
@ -20,7 +20,11 @@ const Model = BI.inherit(Fix.Model, {
});
this.model.linkSelected = {
connectionName:name,
idEdit: true,
isSelected: true,
...data,
};
this.model.linkUpdate = {
connectionName:name,
...data,
};
},

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

@ -1,4 +1,4 @@
import {WidgetType, Htape} from '@ui/index';
import {WidgetType, Htape, Label} from '@ui/index';
const BothSide = 'fr.shared.component.both.side';
const Widget: WidgetType = {
render() {
@ -10,14 +10,14 @@ const Widget: WidgetType = {
height:24,
items: [{
el: {
type: 'bi.label',
type: Label,
cls: 'left',
textAlign: 'left',
text: leftText,
},
width: 115,
}, {
type: 'bi.label',
type: Label,
textAlign: 'left',
text: rightText,
}],

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

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

45
src/shared/crud/crud.request.ts

@ -1,4 +1,5 @@
import {linkList} from './curd.mock';
import {LinkType} from '@ui/type';
const Dec: any = (window as any).parent.Dec;
export function fetchLinkList(callback: Function): void {
@ -10,3 +11,47 @@ export function fetchLinkList(callback: Function): void {
callback(linkList.data);
}
}
export function addConnection(data: LinkType, cb: Function): void{
console.log('%cdata: ', 'color: MidnightBlue; background: Aquamarine;', data);
if (Dec) {
Dec.reqPost(`/v10/config/connection`, data, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}
export function updateConnection(data: LinkType, cb: Function): void{
console.log('%cdata: ', 'color: MidnightBlue; background: Aquamarine;', data);
if (Dec) {
Dec.reqPut(`/v10/config/connection`, data, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}
export function deleteConnection(id: string, cb: Function): void{
console.log('%cid: ', 'color: MidnightBlue; background: Aquamarine;', id);
if (Dec) {
Dec.reqDeleta(`/v10/config/connection/${id}`, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}
export function testConnection(id: string, cb: Function): void{
console.log('%cid: ', 'color: MidnightBlue; background: Aquamarine;', id);
if (Dec) {
Dec.reqDeleta(`/v10/config/connection/${id}/status`, (res: any) => {
cb(res.data);
});
} else {
cb('success');
}
}

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

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

34
src/shared/service/dialog.service.ts

@ -0,0 +1,34 @@
export const confirm = (message: string, onConfirm: Function): void => {
const id = BI.UUID();
BI.Popovers.create(id, {
type: 'bi.bar_popover',
size: 'normal',
header: '提示',
width: 450,
height: 220,
body: {
type: 'bi.left',
cls: 'comfirm-content',
items: [
{
type: 'bi.layout',
cls: 'comfirm-icon',
width: 50,
height: 50,
},
{
type: 'bi.label',
text: message,
},
],
},
listeners: [
{
eventName: 'EVENT_CONFIRM',
action () {
onConfirm ? onConfirm() : null;
},
},
],
}).open(id);
};

3
src/ui/fineui.ts

@ -29,6 +29,9 @@ export const SingleSelectRadioItem = 'bi.single_select_radio_item';
export const SingleSelectInsertCombo = 'bi.single_select_insert_combo';
export const Tab = 'bi.tab';
export const Combo = 'bi.combo';
export const TextValueCombo = 'bi.text_value_combo';
export const TextBubblePopupBarView = 'bi.text_bubble_bar_popup_view';
export const BubbleCombo = 'bi.bubble_combo';
// 布局
export const VerticalAdapt = 'bi.vertical_adapt';

Loading…
Cancel
Save