mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-16 01:40:53 +08:00
Merge branch 'feat-optimize-5' of ssh://icode.baidu.com:8235/baidu/amis/editor into feat-optimize-5
Change-Id: I4069efb456327526eb44cca5de88a5908602e636
This commit is contained in:
commit
4a6bfebbe6
@ -155,6 +155,7 @@ import './renderer/DataMappingControl';
|
||||
import './renderer/DataPickerControl';
|
||||
import './renderer/event-control/index';
|
||||
import './renderer/TreeOptionControl';
|
||||
import './renderer/TransferTableControl';
|
||||
|
||||
export * from './component/BaseControl';
|
||||
export * from './icons/index';
|
||||
|
@ -84,6 +84,9 @@ export class AnchorNavPlugin extends BasePlugin {
|
||||
draggable: true,
|
||||
minLength: 1,
|
||||
addButtonText: '添加锚点',
|
||||
deleteBtn: {
|
||||
icon: 'fa fa-trash'
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'input-text',
|
||||
@ -150,7 +153,8 @@ export class AnchorNavPlugin extends BasePlugin {
|
||||
value: '1'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
getSchemaTpl('status')
|
||||
])
|
||||
},
|
||||
{
|
||||
|
@ -1,14 +1,16 @@
|
||||
import React from 'react';
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
RegionConfig,
|
||||
RendererInfo
|
||||
RendererInfo,
|
||||
getSchemaTpl,
|
||||
noop
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {noop} from 'amis-editor-core';
|
||||
import {cloneDeep, assign} from 'lodash';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {tipedLabel} from '../component/BaseControl';
|
||||
|
||||
export class DialogPlugin extends BasePlugin {
|
||||
// 关联渲染器名字
|
||||
@ -83,108 +85,152 @@ export class DialogPlugin extends BasePlugin {
|
||||
];
|
||||
|
||||
panelTitle = '弹框';
|
||||
panelJustify = true;
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
return getSchemaTpl('tabs', [
|
||||
{
|
||||
title: '常规',
|
||||
body: [
|
||||
title: '属性',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
label: '标题',
|
||||
type: 'input-text',
|
||||
name: 'title'
|
||||
},
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '数据映射',
|
||||
name: 'data',
|
||||
className: 'block m-b-xs',
|
||||
pipeIn: (value: any) => !!value,
|
||||
pipeOut: (value: any) => (value ? {'&': '$$'} : null)
|
||||
}),
|
||||
|
||||
{
|
||||
type: 'tpl',
|
||||
visibleOn: '!this.data',
|
||||
tpl:
|
||||
'<p class="text-sm text-muted">当没开启数据映射时,弹框中默认会拥有触发打开弹框按钮所在环境的所有数据。</p>'
|
||||
},
|
||||
|
||||
{
|
||||
type: 'input-kv',
|
||||
syncDefaultValue: false,
|
||||
name: 'data',
|
||||
visibleOn: 'this.data',
|
||||
descriptionClassName: 'help-block text-xs m-b-none',
|
||||
description:
|
||||
'<p>当开启数据映射时,弹框中的数据只会包含设置的部分,请绑定数据。如:<code>{"a": "\\${a}", "b": 2}</code></p><p>如果希望在默认的基础上定制,请先添加一个 Key 为 `&` Value 为 `\\$$` 作为第一行。</p><div>当值为 <code>__undefined</code>时,表示删除对应的字段,可以结合<code>{"&": "\\$$"}</code>来达到黑名单效果。</div>',
|
||||
messages: {
|
||||
validateFailed: '数据映射中存在错误,请仔细检查'
|
||||
}
|
||||
},
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '按 Esc 关闭弹框',
|
||||
name: 'closeOnEsc',
|
||||
value: false
|
||||
}),
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '点击弹框外区域关闭弹框',
|
||||
name: 'closeOnOutside',
|
||||
value: false
|
||||
})
|
||||
]
|
||||
title: '基本',
|
||||
body: [
|
||||
{
|
||||
label: '标题',
|
||||
type: 'input-text',
|
||||
name: 'title'
|
||||
},
|
||||
{
|
||||
label: '尺寸',
|
||||
type: 'button-group-select',
|
||||
value: 'md',
|
||||
name: 'size',
|
||||
size: 'sm',
|
||||
options: [
|
||||
{
|
||||
label: '小',
|
||||
value: 'sm'
|
||||
},
|
||||
{
|
||||
label: '中',
|
||||
value: 'md'
|
||||
},
|
||||
{
|
||||
label: '大',
|
||||
value: 'lg'
|
||||
},
|
||||
{
|
||||
label: '超大',
|
||||
value: 'xl'
|
||||
}
|
||||
]
|
||||
},
|
||||
getSchemaTpl('switch', {
|
||||
label: '展示关闭按钮',
|
||||
name: 'showCloseButton',
|
||||
value: true
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: '可按 Esc 关闭',
|
||||
name: 'closeOnEsc',
|
||||
value: false
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: '左下角展示报错消息',
|
||||
name: 'showErrorMsg',
|
||||
value: true
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: '左下角展示loading动画',
|
||||
name: 'showLoading',
|
||||
value: true
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'数据映射',
|
||||
'<div> 当开启数据映射时,弹框中的数据只会包含设置的部分,请绑定数据。如:{"a": "${a}", "b": 2}。</div>'
|
||||
+ '<div>当值为 __undefined时,表示删除对应的字段,可以结合{"&": "$$"}来达到黑名单效果。</div>'
|
||||
),
|
||||
name: 'dataMapSwitch',
|
||||
value: false,
|
||||
className: 'm-b-xs',
|
||||
onChange: (value: any, oldValue: any, model: any, form: any) => {
|
||||
const newDataValue = value ? {} : null;
|
||||
form.setValues({
|
||||
__dataMap: newDataValue,
|
||||
data: newDataValue
|
||||
});
|
||||
}
|
||||
}),
|
||||
{
|
||||
type: 'alert',
|
||||
level: 'info',
|
||||
visibleOn: 'this.dataMapSwitch',
|
||||
className: 'relative',
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '${data["&"] ? "已开启定制参数功能,可点击关闭该功能。" : "如果需要在默认数据的基础上定制参数,请配置开启参数定制再定义key和value。"}'
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
label: '${data["&"] ? "立即关闭" : "立即开启"}',
|
||||
level: 'link',
|
||||
className: 'absolute bottom-3 right-10',
|
||||
onClick: (e: any, props: any) => {
|
||||
const newData = props.data.data?.['&'] === '$$' ? {} : {'&': '$$'};
|
||||
// 用onBulkChange保证代码视图和编辑区域数据保持同步
|
||||
props.onBulkChange({
|
||||
data: newData,
|
||||
__dataMap: {}
|
||||
});
|
||||
}
|
||||
}
|
||||
],
|
||||
showCloseButton: true
|
||||
},
|
||||
getSchemaTpl('combo-container', {
|
||||
type: 'input-kv',
|
||||
syncDefaultValue: false,
|
||||
name: '__dataMap',
|
||||
value: null,
|
||||
visibleOn: 'this.dataMapSwitch',
|
||||
className: 'block -mt-5',
|
||||
deleteBtn: {
|
||||
icon: 'fa fa-trash'
|
||||
},
|
||||
onChange: (value: any, oldValue: any, model: any, form: any) => {
|
||||
// 用assign保证'&'第一个被遍历到
|
||||
const newDataMap = form.data.data?.['&'] ?
|
||||
assign({'&': '$$'}, value) : cloneDeep(value);
|
||||
form.setValues({
|
||||
data: newDataMap
|
||||
});
|
||||
form.setValues({
|
||||
data: newDataMap
|
||||
});
|
||||
}
|
||||
}),
|
||||
]
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '外观',
|
||||
body: [
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
label: '尺寸',
|
||||
type: 'button-group-select',
|
||||
name: 'size',
|
||||
size: 'sm',
|
||||
className: 'block',
|
||||
pipeIn: defaultValue(''),
|
||||
options: [
|
||||
{
|
||||
label: '小',
|
||||
value: 'sm'
|
||||
},
|
||||
{
|
||||
label: '默认',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '中',
|
||||
value: 'md'
|
||||
},
|
||||
{
|
||||
label: '大',
|
||||
value: 'lg'
|
||||
},
|
||||
{
|
||||
label: '超大',
|
||||
value: 'xl'
|
||||
}
|
||||
title: 'CSS类名',
|
||||
body: [
|
||||
getSchemaTpl('className', {
|
||||
name: 'className',
|
||||
label: '外层'
|
||||
}),
|
||||
getSchemaTpl('className', {
|
||||
name: 'bodyClassName',
|
||||
label: '内容区域'
|
||||
})
|
||||
]
|
||||
},
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '是否显示关闭按钮',
|
||||
name: 'showCloseButton',
|
||||
value: true
|
||||
}),
|
||||
|
||||
getSchemaTpl('className', {
|
||||
name: 'headerClassName',
|
||||
label: '顶部 CSS 类名'
|
||||
}),
|
||||
|
||||
getSchemaTpl('className', {
|
||||
name: 'bodyClassName',
|
||||
label: '内容 CSS 类名'
|
||||
})
|
||||
]
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '事件',
|
||||
|
@ -1,14 +1,17 @@
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
BaseEventContext,
|
||||
BasePlugin,
|
||||
RegionConfig,
|
||||
RendererInfo
|
||||
RendererInfo,
|
||||
defaultValue,
|
||||
getSchemaTpl,
|
||||
noop
|
||||
} from 'amis-editor-core';
|
||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||
import {noop} from 'amis-editor-core';
|
||||
import {assign, cloneDeep} from 'lodash';
|
||||
import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {InlineModal} from './Dialog';
|
||||
import {tipedLabel} from '../component/BaseControl';
|
||||
|
||||
export class DrawerPlugin extends BasePlugin {
|
||||
// 关联渲染器名字
|
||||
@ -83,153 +86,213 @@ export class DrawerPlugin extends BasePlugin {
|
||||
];
|
||||
|
||||
panelTitle = '弹框';
|
||||
panelJustify = true;
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
return getSchemaTpl('tabs', [
|
||||
{
|
||||
title: '常规',
|
||||
body: [
|
||||
title: '属性',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
label: '标题',
|
||||
type: 'input-text',
|
||||
name: 'title'
|
||||
},
|
||||
|
||||
// {
|
||||
// children: (
|
||||
// <Button
|
||||
// size="sm"
|
||||
// className="m-b-sm"
|
||||
// level="info"
|
||||
// block
|
||||
// onClick={() => this.manager.showInsertPanel('body')}
|
||||
// >
|
||||
// 新增内容
|
||||
// </Button>
|
||||
// )
|
||||
// },
|
||||
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
|
||||
{
|
||||
label: '位置',
|
||||
type: 'button-group-select',
|
||||
name: 'position',
|
||||
value: 'right',
|
||||
size: 'sm',
|
||||
mode: 'inline',
|
||||
className: 'block',
|
||||
options: [
|
||||
title: '基本',
|
||||
body: [
|
||||
{
|
||||
label: '左',
|
||||
value: 'left'
|
||||
label: '标题',
|
||||
type: 'input-text',
|
||||
name: 'title'
|
||||
},
|
||||
{
|
||||
label: '上',
|
||||
value: 'top'
|
||||
type: 'button-group-select',
|
||||
name: 'position',
|
||||
label: '位置',
|
||||
value: 'right',
|
||||
mode: 'horizontal',
|
||||
options: [
|
||||
{
|
||||
label: '左',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '上',
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: '右',
|
||||
value: 'right'
|
||||
},
|
||||
{
|
||||
label: '下',
|
||||
value: 'bottom'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '右',
|
||||
value: 'right'
|
||||
type: 'button-group-select',
|
||||
name: 'size',
|
||||
label: '尺寸',
|
||||
value: 'md',
|
||||
size: 'sm',
|
||||
mode: 'horizontal',
|
||||
options: [
|
||||
{
|
||||
label: '超小',
|
||||
value: 'xs'
|
||||
},
|
||||
{
|
||||
label: '小',
|
||||
value: 'sm'
|
||||
},
|
||||
{
|
||||
label: '中',
|
||||
value: 'md'
|
||||
},
|
||||
{
|
||||
label: '大',
|
||||
value: 'lg'
|
||||
},
|
||||
{
|
||||
label: '超大',
|
||||
value: 'xl'
|
||||
}
|
||||
]
|
||||
},
|
||||
getSchemaTpl('switch', {
|
||||
name: 'overlay',
|
||||
label: '显示蒙层',
|
||||
pipeIn: defaultValue(true)
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
name: 'showCloseButton',
|
||||
label: '展示关闭按钮',
|
||||
pipeIn: defaultValue(true)
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
name: 'closeOnOutside',
|
||||
label: '点击外部关闭'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: '可按 Esc 关闭',
|
||||
name: 'closeOnEsc'
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
name: 'resizable',
|
||||
label: '可拖拽抽屉大小',
|
||||
value: false
|
||||
}),
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'数据映射',
|
||||
'<div> 当开启数据映射时,弹框中的数据只会包含设置的部分,请绑定数据。如:{"a": "${a}", "b": 2}。</div>'
|
||||
+ '<div>当值为 __undefined时,表示删除对应的字段,可以结合{"&": "$$"}来达到黑名单效果。</div>'
|
||||
),
|
||||
name: 'dataMapSwitch',
|
||||
value: false,
|
||||
className: 'm-b-xs',
|
||||
onChange: (value: any, oldValue: any, model: any, form: any) => {
|
||||
const newDataValue = value ? {} : null;
|
||||
form.setValues({
|
||||
__dataMap: newDataValue,
|
||||
data: newDataValue
|
||||
});
|
||||
}
|
||||
}),
|
||||
{
|
||||
label: '下',
|
||||
value: 'bottom'
|
||||
}
|
||||
],
|
||||
description: '定义弹框从什么位置呼出'
|
||||
},
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '数据映射',
|
||||
name: 'data',
|
||||
className: 'm-b-xs',
|
||||
pipeIn: (value: any) => !!value,
|
||||
pipeOut: (value: any) => (value ? {'&': '$$'} : null)
|
||||
}),
|
||||
|
||||
{
|
||||
type: 'tpl',
|
||||
visibleOn: '!this.data',
|
||||
tpl:
|
||||
'<p class="text-sm text-muted">当没开启数据映射时,弹框中默认会拥有触发打开弹框按钮所在环境的所有数据。</p>'
|
||||
},
|
||||
|
||||
{
|
||||
type: 'input-kv',
|
||||
syncDefaultValue: false,
|
||||
name: 'data',
|
||||
visibleOn: 'this.data',
|
||||
descriptionClassName: 'help-block text-xs m-b-none',
|
||||
description:
|
||||
'<p>当开启数据映射时,弹框中的数据只会包含设置的部分,请绑定数据。如:<code>{"a": "\\${a}", "b": 2}</code></p><p>如果希望在默认的基础上定制,请先添加一个 Key 为 `&` Value 为 `\\$$` 作为第一行。</p><div>当值为 <code>__undefined</code>时,表示删除对应的字段,可以结合<code>{"&": "\\$$"}</code>来达到黑名单效果。</div>'
|
||||
},
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
name: 'closeOnOutside',
|
||||
label: '点击外部关闭弹框'
|
||||
}),
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '按 Esc 可关闭',
|
||||
name: 'closeOnEsc'
|
||||
})
|
||||
]
|
||||
type: 'alert',
|
||||
level: 'info',
|
||||
visibleOn: 'this.dataMapSwitch',
|
||||
className: 'relative',
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '${data["&"] ? "已开启定制参数功能,可点击关闭该功能。" : "如果需要在默认数据的基础上定制参数,请配置开启参数定制再定义key和value。"}'
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
label: '${data["&"] ? "立即关闭" : "立即开启"}',
|
||||
level: 'link',
|
||||
className: 'absolute bottom-3 right-10',
|
||||
onClick: (e: any, props: any) => {
|
||||
const newData = props.data.data?.['&'] === '$$' ? {} : {'&': '$$'};
|
||||
// 用onBulkChange保证代码视图和编辑区域数据保持同步
|
||||
props.onBulkChange({
|
||||
data: newData,
|
||||
__dataMap: {}
|
||||
});
|
||||
}
|
||||
}
|
||||
],
|
||||
showCloseButton: true
|
||||
},
|
||||
getSchemaTpl('combo-container', {
|
||||
type: 'input-kv',
|
||||
syncDefaultValue: false,
|
||||
name: '__dataMap',
|
||||
value: null,
|
||||
visibleOn: 'this.dataMapSwitch',
|
||||
className: 'block -mt-5',
|
||||
deleteBtn: {
|
||||
icon: 'fa fa-trash'
|
||||
},
|
||||
onChange: (value: any, oldValue: any, model: any, form: any) => {
|
||||
// 用assign保证'&'第一个被遍历到
|
||||
const newDataMap = form.data.data?.['&'] ?
|
||||
assign({'&': '$$'}, value) : cloneDeep(value);
|
||||
form.setValues({
|
||||
data: newDataMap
|
||||
});
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '外观',
|
||||
body: [
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
label: '尺寸',
|
||||
type: 'button-group-select',
|
||||
name: 'size',
|
||||
size: 'sm',
|
||||
mode: 'inline',
|
||||
className: 'block',
|
||||
options: [
|
||||
title: '基本',
|
||||
body: [
|
||||
{
|
||||
label: '超小',
|
||||
value: 'xs'
|
||||
type: 'input-text',
|
||||
name: 'width',
|
||||
label: tipedLabel(
|
||||
'宽度',
|
||||
'位置为 "左" 或 "右" 时生效。 默认宽度为"尺寸"字段配置的宽度,值单位默认为 px,也支持百分比等单位 ,如:100%'
|
||||
),
|
||||
disabledOn: 'this.position === "top" || this.position === "bottom"',
|
||||
tooltip: '位置为 为 "左" 或 "右" 时生效'
|
||||
},
|
||||
{
|
||||
label: '小',
|
||||
value: 'sm'
|
||||
},
|
||||
{
|
||||
label: '中',
|
||||
value: 'md'
|
||||
},
|
||||
{
|
||||
label: '大',
|
||||
value: 'lg'
|
||||
},
|
||||
{
|
||||
label: '超大',
|
||||
value: 'xl'
|
||||
type: 'input-text',
|
||||
name: 'height',
|
||||
label: tipedLabel(
|
||||
'高度',
|
||||
'位置为 "上" 或 "下" 时生效。 默认宽度为"尺寸"字段配置的高度,值单位默认为 px,也支持百分比等单位 ,如:100%'
|
||||
),
|
||||
disabledOn: 'this.position === "left" || this.position === "right"'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
name: 'overlay',
|
||||
label: '是否显示蒙层',
|
||||
pipeIn: defaultValue(true)
|
||||
}),
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
name: 'resizable',
|
||||
label: '可拉拽',
|
||||
description: '定义弹框是否可拉拽调整大小',
|
||||
pipeIn: defaultValue(false)
|
||||
}),
|
||||
|
||||
getSchemaTpl('className'),
|
||||
getSchemaTpl('className', {
|
||||
label: 'bodyClassName 类名',
|
||||
name: 'bodyClassName'
|
||||
})
|
||||
]
|
||||
{
|
||||
title: 'CSS类名',
|
||||
body: [
|
||||
getSchemaTpl('className', {
|
||||
label: '外层'
|
||||
}),
|
||||
getSchemaTpl('className', {
|
||||
label: '标题区域',
|
||||
name: 'headClassName'
|
||||
}),
|
||||
getSchemaTpl('className', {
|
||||
label: '内容区域',
|
||||
name: 'bodyClassName'
|
||||
}),
|
||||
getSchemaTpl('className', {
|
||||
label: '页脚区域',
|
||||
name: 'footClassName'
|
||||
})
|
||||
]
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '事件',
|
||||
|
@ -59,58 +59,90 @@ export class ButtonToolbarControlPlugin extends BasePlugin {
|
||||
|
||||
panelTitle = '工具栏';
|
||||
|
||||
panelJustify = true;
|
||||
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
return formItemControl(
|
||||
return getSchemaTpl('tabs', [
|
||||
{
|
||||
common: {
|
||||
replace: true,
|
||||
body: [
|
||||
getSchemaTpl('formItemName', {
|
||||
required: true
|
||||
}),
|
||||
getSchemaTpl('label'),
|
||||
getSchemaTpl('remark'),
|
||||
getSchemaTpl('labelRemark'),
|
||||
getSchemaTpl('description')
|
||||
]
|
||||
},
|
||||
option: {
|
||||
title: '按钮管理',
|
||||
replace: true,
|
||||
body: [
|
||||
title: '属性',
|
||||
body: [
|
||||
getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
name: 'buttons',
|
||||
type: 'combo',
|
||||
label: '',
|
||||
multiple: true,
|
||||
addable: true,
|
||||
minLength: 1,
|
||||
draggable: true,
|
||||
draggableTip: '',
|
||||
editable: false,
|
||||
visibleOn: 'this.buttons && this.buttons.length',
|
||||
items: [
|
||||
{
|
||||
type: 'tpl',
|
||||
inline: false,
|
||||
tpl:
|
||||
'<span class="label label-default"><% if (data.type === "button-group") { %> 按钮组 <% } else { %><%= data.label %><% if (data.icon) { %><i class="<%= data.icon %>"/><% }%><% } %></span>'
|
||||
}
|
||||
],
|
||||
addButtonText: '新增按钮',
|
||||
scaffold: {
|
||||
type: 'button',
|
||||
label: '按钮'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
event: {
|
||||
hidden: false
|
||||
}
|
||||
title: '基本',
|
||||
body: [
|
||||
getSchemaTpl('formItemName', {
|
||||
required: true
|
||||
}),
|
||||
getSchemaTpl('label'),
|
||||
getSchemaTpl('valueFormula', {
|
||||
rendererSchema: {
|
||||
type: 'input-text'
|
||||
}
|
||||
}),
|
||||
getSchemaTpl('labelRemark'),
|
||||
getSchemaTpl('remark'),
|
||||
getSchemaTpl('description'),
|
||||
getSchemaTpl('combo-container', {
|
||||
type: 'combo',
|
||||
label: '按钮管理',
|
||||
name: 'buttons',
|
||||
mode: 'normal',
|
||||
multiple: true,
|
||||
addable: true,
|
||||
minLength: 1,
|
||||
draggable: true,
|
||||
editable: false,
|
||||
items: [
|
||||
{
|
||||
type: 'tpl',
|
||||
inline: false,
|
||||
className: 'p-t-xs',
|
||||
tpl: '<span class="label label-default"><% if (data.type === "button-group") { %> 按钮组 <% } else { %><%= data.label %><% if (data.icon) { %><i class="<%= data.icon %>"/><% }%><% } %></span>'
|
||||
}
|
||||
],
|
||||
addButtonText: '新增按钮',
|
||||
scaffold: {
|
||||
type: 'button',
|
||||
label: '按钮'
|
||||
}
|
||||
}),
|
||||
]
|
||||
},
|
||||
getSchemaTpl('status', {
|
||||
isFormItem: true,
|
||||
})
|
||||
]),
|
||||
]
|
||||
},
|
||||
context
|
||||
);
|
||||
{
|
||||
title: '外观',
|
||||
body: [
|
||||
getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本',
|
||||
body: [
|
||||
getSchemaTpl('formItemMode'),
|
||||
getSchemaTpl('horizontal', {
|
||||
label: '',
|
||||
visibleOn:
|
||||
'data.mode == "horizontal" && data.label !== false && data.horizontal'
|
||||
}),
|
||||
]
|
||||
},
|
||||
getSchemaTpl('style:classNames', {
|
||||
isFormItem: true,
|
||||
schema: [
|
||||
getSchemaTpl('className', {
|
||||
label: '描述',
|
||||
name: 'descriptionClassName',
|
||||
visibleOn: "this.description"
|
||||
})
|
||||
]
|
||||
}),
|
||||
])
|
||||
]
|
||||
}
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -218,6 +218,10 @@ export class TabsTransferPlugin extends BasePlugin {
|
||||
}
|
||||
];
|
||||
|
||||
notRenderFormZone = true;
|
||||
|
||||
panelJustify = true;
|
||||
|
||||
panelDefinitions = {
|
||||
options: {
|
||||
label: '选项 Options',
|
||||
@ -269,65 +273,64 @@ export class TabsTransferPlugin extends BasePlugin {
|
||||
{
|
||||
title: '属性',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
getSchemaTpl('switchDefaultValue'),
|
||||
|
||||
{
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
label: '默认值',
|
||||
source: '${options}',
|
||||
multiple: true,
|
||||
visibleOn: 'typeof this.value !== "undefined"'
|
||||
},
|
||||
title: '基本',
|
||||
body: [
|
||||
getSchemaTpl('formItemName', {
|
||||
required: true
|
||||
}),
|
||||
getSchemaTpl('label'),
|
||||
|
||||
getSchemaTpl('searchable'),
|
||||
|
||||
getSchemaTpl('api', {
|
||||
label: '检索接口',
|
||||
name: 'searchApi'
|
||||
}),
|
||||
|
||||
{
|
||||
label: '查询时勾选展示模式',
|
||||
name: 'searchResultMode',
|
||||
type: 'select',
|
||||
mode: 'inline',
|
||||
className: 'w-full',
|
||||
options: [
|
||||
getSchemaTpl('searchable'),
|
||||
|
||||
getSchemaTpl('api', {
|
||||
label: '检索接口',
|
||||
name: 'searchApi'
|
||||
}),
|
||||
|
||||
{
|
||||
label: '列表形式',
|
||||
value: 'list'
|
||||
label: '查询时勾选展示模式',
|
||||
name: 'searchResultMode',
|
||||
type: 'select',
|
||||
mode: 'normal',
|
||||
options: [
|
||||
{
|
||||
label: '列表形式',
|
||||
value: 'list'
|
||||
},
|
||||
{
|
||||
label: '表格形式',
|
||||
value: 'table'
|
||||
},
|
||||
{
|
||||
label: '树形选择形式',
|
||||
value: 'tree'
|
||||
},
|
||||
{
|
||||
label: '级联选择形式',
|
||||
value: 'chained'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '表格形式',
|
||||
value: 'table'
|
||||
},
|
||||
{
|
||||
label: '树形选择形式',
|
||||
value: 'tree'
|
||||
},
|
||||
{
|
||||
label: '级联选择形式',
|
||||
value: 'chained'
|
||||
}
|
||||
|
||||
getSchemaTpl('sortable'),
|
||||
|
||||
getSchemaTpl('formulaControl', {
|
||||
label: '左侧选项标题',
|
||||
name: 'selectTitle',
|
||||
type: 'input-text',
|
||||
inputClassName: 'is-inline '
|
||||
}),
|
||||
|
||||
getSchemaTpl('formulaControl', {
|
||||
label: '右侧结果标题',
|
||||
name: 'resultTitle',
|
||||
type: 'input-text',
|
||||
inputClassName: 'is-inline '
|
||||
})
|
||||
]
|
||||
},
|
||||
|
||||
getSchemaTpl('sortable'),
|
||||
|
||||
{
|
||||
label: '左侧的标题文字',
|
||||
name: 'selectTitle',
|
||||
type: 'input-text'
|
||||
},
|
||||
|
||||
{
|
||||
label: '右侧结果的标题文字',
|
||||
name: 'resultTitle',
|
||||
type: 'input-text'
|
||||
},
|
||||
|
||||
getSchemaTpl('fieldSet', {
|
||||
title: '选项',
|
||||
body: [
|
||||
{
|
||||
@ -340,7 +343,8 @@ export class TabsTransferPlugin extends BasePlugin {
|
||||
getSchemaTpl('extractValue'),
|
||||
getSchemaTpl('autoFill')
|
||||
]
|
||||
})
|
||||
},
|
||||
getSchemaTpl('status', {isFormItem: true})
|
||||
])
|
||||
},
|
||||
{
|
||||
|
@ -7,6 +7,9 @@ import {
|
||||
RendererPluginEvent
|
||||
} from 'amis-editor-core';
|
||||
|
||||
import {ValidatorTag} from '../../validator';
|
||||
import {tipedLabel} from '../../component/BaseControl';
|
||||
|
||||
export class TransferPlugin extends BasePlugin {
|
||||
// 关联渲染器名字
|
||||
rendererName = 'transfer';
|
||||
@ -26,43 +29,28 @@ export class TransferPlugin extends BasePlugin {
|
||||
name: 'transfer',
|
||||
options: [
|
||||
{
|
||||
label: '法师',
|
||||
children: [
|
||||
{
|
||||
label: '诸葛亮',
|
||||
value: 'zhugeliang'
|
||||
}
|
||||
]
|
||||
label: '诸葛亮',
|
||||
value: 'zhugeliang'
|
||||
},
|
||||
{
|
||||
label: '战士',
|
||||
children: [
|
||||
{
|
||||
label: '曹操',
|
||||
value: 'caocao'
|
||||
},
|
||||
{
|
||||
label: '钟无艳',
|
||||
value: 'zhongwuyan'
|
||||
}
|
||||
]
|
||||
label: '曹操',
|
||||
value: 'caocao'
|
||||
},
|
||||
{
|
||||
label: '打野',
|
||||
children: [
|
||||
{
|
||||
label: '李白',
|
||||
value: 'libai'
|
||||
},
|
||||
{
|
||||
label: '韩信',
|
||||
value: 'hanxin'
|
||||
},
|
||||
{
|
||||
label: '云中君',
|
||||
value: 'yunzhongjun'
|
||||
}
|
||||
]
|
||||
label: '钟无艳',
|
||||
value: 'zhongwuyan'
|
||||
},
|
||||
{
|
||||
label: '李白',
|
||||
value: 'libai'
|
||||
},
|
||||
{
|
||||
label: '韩信',
|
||||
value: 'hanxin'
|
||||
},
|
||||
{
|
||||
label: '云中君',
|
||||
value: 'yunzhongjun'
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -181,7 +169,9 @@ export class TransferPlugin extends BasePlugin {
|
||||
}
|
||||
};
|
||||
|
||||
// notRenderFormZone = true;
|
||||
notRenderFormZone = true;
|
||||
|
||||
panelJustify = true;
|
||||
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
const renderer: any = context.info.renderer;
|
||||
@ -190,231 +180,150 @@ export class TransferPlugin extends BasePlugin {
|
||||
{
|
||||
title: '属性',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
getSchemaTpl('switchDefaultValue'),
|
||||
|
||||
{
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
label: '默认值',
|
||||
source: '${options}',
|
||||
visibleOn: '!data.multiple && typeof this.value !== "undefined"'
|
||||
},
|
||||
|
||||
{
|
||||
type: 'select',
|
||||
name: 'value',
|
||||
label: '默认值',
|
||||
source: '${options}',
|
||||
multiple: true,
|
||||
visibleOn: ' data.multiple && typeof this.value !== "undefined"'
|
||||
},
|
||||
|
||||
{
|
||||
label: '勾选展示模式',
|
||||
name: 'selectMode',
|
||||
type: 'select',
|
||||
mode: 'inline',
|
||||
className: 'w-full',
|
||||
options: [
|
||||
{
|
||||
label: '列表形式',
|
||||
value: 'list'
|
||||
},
|
||||
{
|
||||
label: '表格形式',
|
||||
value: 'table'
|
||||
},
|
||||
{
|
||||
label: '树形选择形式',
|
||||
value: 'tree'
|
||||
},
|
||||
{
|
||||
label: '级联选择形式',
|
||||
value: 'chained'
|
||||
},
|
||||
{
|
||||
label: '关联选择形式',
|
||||
value: 'associated'
|
||||
}
|
||||
title: '基本',
|
||||
body: [
|
||||
getSchemaTpl('formItemName', {
|
||||
required: true
|
||||
}),
|
||||
getSchemaTpl('label'),
|
||||
getSchemaTpl('labelRemark'),
|
||||
getSchemaTpl('remark'),
|
||||
getSchemaTpl('placeholder'),
|
||||
getSchemaTpl('description'),
|
||||
getSchemaTpl('switch', {
|
||||
label: '统计数据',
|
||||
name: 'statistics'
|
||||
})
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
name: 'columns',
|
||||
type: 'combo',
|
||||
multiple: true,
|
||||
label: false,
|
||||
strictMode: false,
|
||||
addButtonText: '新增一列',
|
||||
draggable: false,
|
||||
visibleOn: 'data.selectMode === "table"',
|
||||
items: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'label',
|
||||
placeholder: '标题'
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'name',
|
||||
placeholder: '绑定字段名'
|
||||
},
|
||||
title: '左侧选项面板',
|
||||
body: [
|
||||
|
||||
{
|
||||
label: '展示形式',
|
||||
name: 'selectMode',
|
||||
type: 'select',
|
||||
name: 'type',
|
||||
placeholder: '类型',
|
||||
value: 'input-text',
|
||||
options: [
|
||||
{
|
||||
value: 'text',
|
||||
label: '纯文本'
|
||||
label: '列表形式',
|
||||
value: 'list'
|
||||
},
|
||||
{
|
||||
value: 'tpl',
|
||||
label: '模板'
|
||||
label: '表格形式',
|
||||
value: 'table'
|
||||
},
|
||||
{
|
||||
value: 'image',
|
||||
label: '图片'
|
||||
},
|
||||
{
|
||||
value: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
value: 'progress',
|
||||
label: '进度'
|
||||
},
|
||||
{
|
||||
value: 'status',
|
||||
label: '状态'
|
||||
},
|
||||
{
|
||||
value: 'mapping',
|
||||
label: '映射'
|
||||
},
|
||||
{
|
||||
value: 'operation',
|
||||
label: '操作栏'
|
||||
label: '树形形式',
|
||||
value: 'tree'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
$ref: 'options',
|
||||
label: '左边的选项集',
|
||||
name: 'leftOptions',
|
||||
visibleOn: 'data.selectMode === "associated"'
|
||||
},
|
||||
|
||||
{
|
||||
label: '左侧选择形式',
|
||||
name: 'leftMode',
|
||||
type: 'select',
|
||||
mode: 'inline',
|
||||
className: 'w-full',
|
||||
visibleOn: 'data.selectMode === "associated"',
|
||||
options: [
|
||||
{
|
||||
label: '列表形式',
|
||||
value: 'list'
|
||||
],
|
||||
onChange: (value: any, origin: any, item: any, form: any) => {
|
||||
form.setValueByName('options', undefined);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '树形选择形式',
|
||||
value: 'tree'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
label: '右侧选择形式',
|
||||
name: 'rightMode',
|
||||
type: 'select',
|
||||
mode: 'inline',
|
||||
className: 'w-full',
|
||||
visibleOn: 'data.selectMode === "associated"',
|
||||
options: [
|
||||
getSchemaTpl('optionControl', {
|
||||
visibleOn: 'data.selectMode === "list"',
|
||||
multiple: true
|
||||
}),
|
||||
|
||||
{
|
||||
label: '列表形式',
|
||||
value: 'list'
|
||||
type: 'ae-transferTableControl',
|
||||
name: 'options',
|
||||
label: '数据',
|
||||
visibleOn: 'data.selectMode === "table"',
|
||||
mode: 'normal'
|
||||
},
|
||||
{
|
||||
label: '树形选择形式',
|
||||
value: 'tree'
|
||||
}
|
||||
]
|
||||
|
||||
getSchemaTpl('treeOptionControl', {
|
||||
visibleOn: 'data.selectMode === "tree"',
|
||||
}),
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '可检索',
|
||||
name: 'searchable'
|
||||
}),
|
||||
|
||||
getSchemaTpl('menuTpl', {
|
||||
label: tipedLabel('模板', '左侧选项渲染模板,支持JSX,变量使用\\${xx}')
|
||||
}),
|
||||
|
||||
getSchemaTpl('formulaControl', {
|
||||
label: '标题',
|
||||
name: 'selectTitle',
|
||||
type: 'input-text',
|
||||
inputClassName: 'is-inline '
|
||||
})
|
||||
],
|
||||
},
|
||||
|
||||
getSchemaTpl('searchable'),
|
||||
|
||||
getSchemaTpl('api', {
|
||||
label: '检索接口',
|
||||
name: 'searchApi'
|
||||
}),
|
||||
|
||||
{
|
||||
label: '查询时勾选展示模式',
|
||||
name: 'searchResultMode',
|
||||
type: 'select',
|
||||
mode: 'inline',
|
||||
className: 'w-full',
|
||||
options: [
|
||||
{
|
||||
label: '列表形式',
|
||||
value: 'list'
|
||||
},
|
||||
{
|
||||
label: '表格形式',
|
||||
value: 'table'
|
||||
},
|
||||
{
|
||||
label: '树形选择形式',
|
||||
value: 'tree'
|
||||
},
|
||||
{
|
||||
label: '级联选择形式',
|
||||
value: 'chained'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
getSchemaTpl('sortable'),
|
||||
|
||||
getSchemaTpl('selectFirst'),
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: '是否显示统计数据',
|
||||
name: 'statistics'
|
||||
}),
|
||||
|
||||
{
|
||||
label: '左侧的标题文字',
|
||||
name: 'selectTitle',
|
||||
type: 'input-text'
|
||||
},
|
||||
|
||||
{
|
||||
label: '右侧结果的标题文字',
|
||||
name: 'resultTitle',
|
||||
type: 'input-text'
|
||||
},
|
||||
|
||||
getSchemaTpl('fieldSet', {
|
||||
title: '选项',
|
||||
title: '右侧结果面板',
|
||||
body: [
|
||||
{
|
||||
$ref: 'options',
|
||||
name: 'options'
|
||||
type: 'button-group-select',
|
||||
label: '展示形式',
|
||||
name: 'resultListModeFollowSelect',
|
||||
inputClassName: 'items-center',
|
||||
options: [
|
||||
{label: '列表形式', value: false},
|
||||
{label: '跟随左侧', value: true},
|
||||
],
|
||||
},
|
||||
getSchemaTpl('source'),
|
||||
getSchemaTpl('joinValues'),
|
||||
getSchemaTpl('delimiter'),
|
||||
getSchemaTpl('extractValue'),
|
||||
getSchemaTpl('autoFill')
|
||||
|
||||
getSchemaTpl('switch', {
|
||||
label: tipedLabel(
|
||||
'可检索',
|
||||
'查询功能目前只支持根据名称或值来模糊匹配查询'
|
||||
),
|
||||
name: 'resultSearchable'
|
||||
}),
|
||||
|
||||
getSchemaTpl('sortable', {
|
||||
label: '支持排序',
|
||||
mode: 'horizontal',
|
||||
horizontal: {
|
||||
justify: true,
|
||||
left: 8
|
||||
},
|
||||
inputClassName: 'is-inline',
|
||||
visibleOn: 'data.selectMode === "list" && !data.resultListModeFollowSelect',
|
||||
}),
|
||||
|
||||
getSchemaTpl('menuTpl', {
|
||||
name: 'valueTpl',
|
||||
label: tipedLabel('模板', '结果选项渲染模板,支持JSX,变量使用\\${xx}')
|
||||
}),
|
||||
|
||||
getSchemaTpl('formulaControl', {
|
||||
label: '标题',
|
||||
name: 'resultTitle',
|
||||
type: 'input-text',
|
||||
inputClassName: 'is-inline '
|
||||
})
|
||||
]
|
||||
})
|
||||
},
|
||||
getSchemaTpl('status', {isFormItem: true}),
|
||||
getSchemaTpl('validation', {tag: ValidatorTag.MultiSelect})
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '外观',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
getSchemaTpl('style:formItem', renderer),
|
||||
getSchemaTpl('style:classNames', [
|
||||
getSchemaTpl('className', {
|
||||
label: '描述',
|
||||
name: 'descriptionClassName',
|
||||
visibleOn: 'this.description'
|
||||
}),
|
||||
getSchemaTpl('className', {
|
||||
name: 'addOn.className',
|
||||
label: 'AddOn',
|
||||
visibleOn: 'this.addOn && this.addOn.type === "text"'
|
||||
})
|
||||
])
|
||||
])
|
||||
},
|
||||
{
|
||||
|
459
packages/amis-editor/src/renderer/TransferTableControl.tsx
Normal file
459
packages/amis-editor/src/renderer/TransferTableControl.tsx
Normal file
@ -0,0 +1,459 @@
|
||||
/**
|
||||
* @file Transfer的表格对应选项
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render as amisRender, FormItem } from 'amis';
|
||||
import { omit } from 'lodash';
|
||||
import { SchemaApi } from 'amis/lib/Schema';
|
||||
import { autobind, getSchemaTpl } from 'amis-editor-core';
|
||||
import cx from 'classnames';
|
||||
import { tipedLabel } from '../component/BaseControl';
|
||||
|
||||
import type { FormControlProps } from 'amis-core';
|
||||
import type { Option } from 'amis';
|
||||
|
||||
interface OptionControlProps extends FormControlProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface OptionControlState {
|
||||
api: SchemaApi;
|
||||
labelField: string;
|
||||
valueField: string;
|
||||
source: 'custom' | 'api' | 'form';
|
||||
};
|
||||
|
||||
function BaseOptionControl(Cmpt: React.JSXElementConstructor<any>) {
|
||||
return class extends React.Component<OptionControlProps, OptionControlState> {
|
||||
|
||||
$comp: string; // 记录一下路径,不再从外部同步内部,只从内部同步外部
|
||||
|
||||
internalProps = ['checked', 'editing'];
|
||||
|
||||
constructor(props: OptionControlProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
api: props.data.source,
|
||||
labelField: props.data.labelField,
|
||||
valueField: props.data.valueField,
|
||||
source: props.data.source ? 'api' : 'custom'
|
||||
};
|
||||
|
||||
this.handleSourceChange = this.handleSourceChange.bind(this);
|
||||
this.handleAPIChange = this.handleAPIChange.bind(this);
|
||||
this.handleLableFieldChange = this.handleLableFieldChange.bind(this);
|
||||
this.handleValueFieldChange = this.handleValueFieldChange.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新options字段的统一出口
|
||||
*/
|
||||
onChange() {
|
||||
const { source } = this.state;
|
||||
const { onBulkChange } = this.props;
|
||||
|
||||
const data: Partial<OptionControlProps> = {
|
||||
source: undefined,
|
||||
options: undefined,
|
||||
labelField: undefined,
|
||||
valueField: undefined
|
||||
};
|
||||
|
||||
if (source === 'api') {
|
||||
const { api, labelField, valueField } = this.state;
|
||||
data.source = api;
|
||||
data.labelField = labelField;
|
||||
data.valueField = valueField;
|
||||
}
|
||||
|
||||
onBulkChange && onBulkChange(data);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换选项类型
|
||||
*/
|
||||
handleSourceChange(source: 'custom' | 'api' | 'form') {
|
||||
this.setState({ source: source }, this.onChange);
|
||||
}
|
||||
|
||||
handleAPIChange(source: SchemaApi) {
|
||||
this.setState({ api: source }, this.onChange);
|
||||
}
|
||||
|
||||
handleLableFieldChange(labelField: string) {
|
||||
this.setState({ labelField }, this.onChange);
|
||||
}
|
||||
|
||||
handleValueFieldChange(valueField: string) {
|
||||
this.setState({ valueField }, this.onChange);
|
||||
}
|
||||
|
||||
buildBatchAddSchema() {
|
||||
return {
|
||||
type: 'action',
|
||||
actionType: 'dialog',
|
||||
label: '批量添加',
|
||||
dialog: {
|
||||
title: '批量添加选项',
|
||||
headerClassName: 'font-bold',
|
||||
closeOnEsc: true,
|
||||
closeOnOutside: false,
|
||||
showCloseButton: true,
|
||||
body: [
|
||||
{
|
||||
type: 'alert',
|
||||
level: 'warning',
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '每个选项单列一行,将所有值不重复的项加为新的选项;<br/>每行可通过空格来分别设置label和value,例:"张三 zhangsan"'
|
||||
}
|
||||
],
|
||||
showIcon: true,
|
||||
className: 'mb-2.5'
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
wrapWithPanel: false,
|
||||
mode: 'normal',
|
||||
wrapperComponent: 'div',
|
||||
resetAfterSubmit: true,
|
||||
autoFocus: true,
|
||||
preventEnterSubmit: true,
|
||||
horizontal: {
|
||||
left: 0,
|
||||
right: 12
|
||||
},
|
||||
body: [
|
||||
{
|
||||
name: 'batchOption',
|
||||
type: 'textarea',
|
||||
label: '',
|
||||
placeholder: '请输入选项内容',
|
||||
trimContents: true,
|
||||
minRows: 10,
|
||||
maxRows: 50,
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
renderHeader() {
|
||||
const { render, label, labelRemark, useMobileUI, env, popOverContainer } =
|
||||
this.props;
|
||||
const classPrefix = env?.theme?.classPrefix;
|
||||
const { source } = this.state;
|
||||
const optionSourceList = (
|
||||
[
|
||||
{
|
||||
label: '自定义选项',
|
||||
value: 'custom'
|
||||
},
|
||||
{
|
||||
label: '接口获取',
|
||||
value: 'api'
|
||||
}
|
||||
] as Array<{
|
||||
label: string;
|
||||
value: 'custom' | 'api' | 'form';
|
||||
}>
|
||||
).map(item => ({
|
||||
...item,
|
||||
onClick: () => this.handleSourceChange(item.value)
|
||||
}));
|
||||
|
||||
return (
|
||||
<header className="ae-OptionControl-header">
|
||||
<label className={cx(`${classPrefix}Form-label`)}>
|
||||
{label || ''}
|
||||
{labelRemark
|
||||
? render('label-remark', {
|
||||
type: 'remark',
|
||||
icon: labelRemark.icon || 'warning-mark',
|
||||
tooltip: labelRemark,
|
||||
className: cx(`Form-lableRemark`, labelRemark?.className),
|
||||
useMobileUI,
|
||||
container: popOverContainer
|
||||
? popOverContainer
|
||||
: env && env.getModalContainer
|
||||
? env.getModalContainer
|
||||
: undefined
|
||||
})
|
||||
: null}
|
||||
</label>
|
||||
<div>
|
||||
{render(
|
||||
'validation-control-addBtn',
|
||||
{
|
||||
type: 'dropdown-button',
|
||||
level: 'link',
|
||||
size: 'sm',
|
||||
label: '${selected}',
|
||||
align: 'right',
|
||||
closeOnClick: true,
|
||||
closeOnOutside: true,
|
||||
buttons: optionSourceList
|
||||
},
|
||||
{
|
||||
popOverContainer: null,
|
||||
data: {
|
||||
selected: optionSourceList.find(item => item.value === source)!
|
||||
.label
|
||||
}
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
renderApiPanel() {
|
||||
const { render } = this.props;
|
||||
const { source, api, labelField, valueField } = this.state;
|
||||
if (source !== 'api') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return render(
|
||||
'api',
|
||||
getSchemaTpl('apiControl', {
|
||||
label: '接口',
|
||||
name: 'source',
|
||||
className: 'ae-ExtendMore',
|
||||
visibleOn: 'data.autoComplete !== false',
|
||||
value: api,
|
||||
onChange: this.handleAPIChange,
|
||||
footer: [
|
||||
{
|
||||
label: tipedLabel(
|
||||
'显示字段',
|
||||
'选项文本对应的数据字段,多字段合并请通过模板配置'
|
||||
),
|
||||
type: 'input-text',
|
||||
name: 'labelField',
|
||||
value: labelField,
|
||||
placeholder: '选项文本对应的字段',
|
||||
onChange: this.handleLableFieldChange
|
||||
},
|
||||
{
|
||||
label: '值字段',
|
||||
type: 'input-text',
|
||||
name: 'valueField',
|
||||
value: valueField,
|
||||
placeholder: '值对应的字段',
|
||||
onChange: this.handleValueFieldChange
|
||||
}
|
||||
]
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { source, api, labelField, valueField } = this.state;
|
||||
const { className } = this.props;
|
||||
const cmptProps = {
|
||||
...this.props,
|
||||
data: {
|
||||
api,
|
||||
labelField,
|
||||
valueField,
|
||||
...this.props?.data
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cx('ae-OptionControl', className)}>
|
||||
{this.renderHeader()}
|
||||
|
||||
{source === 'custom' ? (
|
||||
<Cmpt {...cmptProps} />
|
||||
) : null}
|
||||
|
||||
{this.renderApiPanel()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const renderInput = (
|
||||
name: string,
|
||||
placeholder: string,
|
||||
required: boolean = true
|
||||
) => {
|
||||
return {
|
||||
type: 'input-text',
|
||||
name,
|
||||
placeholder: placeholder,
|
||||
required
|
||||
}
|
||||
}
|
||||
|
||||
export default class TransferTableOption extends React.Component<OptionControlProps, {}> {
|
||||
|
||||
addColumns() {
|
||||
const { columns = [{ type: 'text' }] } = this.props.data;
|
||||
return {
|
||||
type: 'action',
|
||||
actionType: 'dialog',
|
||||
label: '添加表格列',
|
||||
level: 'enhance',
|
||||
dialog: {
|
||||
title: '设置表格列选项',
|
||||
headerClassName: 'font-bold',
|
||||
closeOnEsc: true,
|
||||
closeOnOutside: false,
|
||||
showCloseButton: true,
|
||||
body: [
|
||||
{
|
||||
name: 'columns',
|
||||
type: 'combo',
|
||||
multiple: true,
|
||||
label: false,
|
||||
strictMode: false,
|
||||
addButtonText: '新增一列',
|
||||
draggable: false,
|
||||
value: columns,
|
||||
onChange: (value: Array<Option>) => this.handleColumnsChange(value),
|
||||
items: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'label',
|
||||
placeholder: '标题'
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'name',
|
||||
placeholder: '绑定字段名'
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
name: 'type',
|
||||
placeholder: '类型',
|
||||
value: 'text',
|
||||
options: [
|
||||
{
|
||||
value: 'text',
|
||||
label: '纯文本'
|
||||
},
|
||||
{
|
||||
value: 'tpl',
|
||||
label: '模板'
|
||||
},
|
||||
{
|
||||
value: 'image',
|
||||
label: '图片'
|
||||
},
|
||||
{
|
||||
value: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
value: 'progress',
|
||||
label: '进度'
|
||||
},
|
||||
{
|
||||
value: 'status',
|
||||
label: '状态'
|
||||
},
|
||||
{
|
||||
value: 'mapping',
|
||||
label: '映射'
|
||||
},
|
||||
{
|
||||
value: 'operation',
|
||||
label: '操作栏'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
addRows() {
|
||||
const { columns = [], options = [{}] } = this.props.data;
|
||||
return {
|
||||
type: 'tooltip-wrapper',
|
||||
tooltip: '需设置表格列后,才能设置表格行',
|
||||
tooltipTheme: 'dark',
|
||||
placement: 'top',
|
||||
tooltipStyle: {
|
||||
fontSize: '12px'
|
||||
},
|
||||
className: 'ae-formItemControl-label-tip',
|
||||
body: [{
|
||||
type: 'action',
|
||||
actionType: 'dialog',
|
||||
label: '添加表格行',
|
||||
level: 'enhance',
|
||||
disabled: columns && columns.length === 0,
|
||||
block: true,
|
||||
dialog: {
|
||||
title: '设置表格行选项',
|
||||
headerClassName: 'font-bold',
|
||||
closeOnEsc: true,
|
||||
closeOnOutside: false,
|
||||
showCloseButton: true,
|
||||
size: columns.length >= 6 ? 'md' : '',
|
||||
body: [{
|
||||
name: 'options',
|
||||
type: 'combo',
|
||||
multiple: true,
|
||||
draggable: true,
|
||||
addButtonText: '新增',
|
||||
value: options,
|
||||
onChange: (value: Array<Option>) => this.handleRowsChange(value),
|
||||
items: [
|
||||
...columns.map((item: Option) => renderInput(item.name, item.label ?? '')),
|
||||
renderInput('value', '值', true)
|
||||
]
|
||||
}]
|
||||
}
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleColumnsChange(value: Array<Option>) {
|
||||
const { data } = this.props;
|
||||
const { onBulkChange } = this.props;
|
||||
data.columns = value.map(item => omit(item, 'id'));
|
||||
onBulkChange && onBulkChange(data);
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleRowsChange(value: Array<Option>) {
|
||||
const { data } = this.props;
|
||||
const { onBulkChange } = this.props;
|
||||
data.options = value;
|
||||
onBulkChange && onBulkChange(data);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='ae-OptionControl-footer'>
|
||||
{amisRender(this.addColumns())}
|
||||
{amisRender(this.addRows())}
|
||||
</div>)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const TransferTableControl = BaseOptionControl(TransferTableOption);
|
||||
|
||||
@FormItem({
|
||||
type: 'ae-transferTableControl',
|
||||
renderLabel: false
|
||||
})
|
||||
export class TransferTableControlRenderer extends TransferTableControl { }
|
Loading…
Reference in New Issue
Block a user