mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-30 19:08:45 +08:00
merge feat-optimize-4
Change-Id: I8974063a944df31cfcd401f416b69859fa53c04d
This commit is contained in:
parent
29bd6b5e91
commit
ec4170017f
@ -4,9 +4,12 @@
|
|||||||
|
|
||||||
import flatten from 'lodash/flatten';
|
import flatten from 'lodash/flatten';
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
import {getSchemaTpl, isObject} from 'amis-editor-core';
|
import {
|
||||||
import type {BaseEventContext} from 'amis-editor-core';
|
getSchemaTpl,
|
||||||
import {SchemaObject} from 'amis/lib/Schema';
|
isObject,
|
||||||
|
BaseEventContext,
|
||||||
|
tipedLabel
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
|
||||||
// 默认动作
|
// 默认动作
|
||||||
export const BUTTON_DEFAULT_ACTION = {
|
export const BUTTON_DEFAULT_ACTION = {
|
||||||
@ -370,25 +373,6 @@ export const formItemControl: (
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function tipedLabel(
|
|
||||||
body: string | Array<SchemaObject>,
|
|
||||||
tip: string,
|
|
||||||
style?: React.CSSProperties
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
type: 'tooltip-wrapper',
|
|
||||||
tooltip: tip,
|
|
||||||
tooltipTheme: 'dark',
|
|
||||||
placement: 'top',
|
|
||||||
tooltipStyle: {
|
|
||||||
fontSize: '12px',
|
|
||||||
...(style || {})
|
|
||||||
},
|
|
||||||
className: 'ae-formItemControl-label-tip',
|
|
||||||
body
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 信息提示组件模版
|
* 信息提示组件模版
|
||||||
*/
|
*/
|
||||||
@ -400,7 +384,7 @@ export function remarkTpl(config: {
|
|||||||
return {
|
return {
|
||||||
type: 'ae-switch-more',
|
type: 'ae-switch-more',
|
||||||
formType: 'dialog',
|
formType: 'dialog',
|
||||||
className:'ae-switch-more-flex',
|
className: 'ae-switch-more-flex',
|
||||||
label: config.labelRemark
|
label: config.labelRemark
|
||||||
? tipedLabel(config.label, config.labelRemark)
|
? tipedLabel(config.label, config.labelRemark)
|
||||||
: config.label,
|
: config.label,
|
||||||
|
@ -7,7 +7,7 @@ interface InputComponentNameProps extends RendererProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function InputComponentName(props: InputComponentNameProps) {
|
export function InputComponentName(props: InputComponentNameProps) {
|
||||||
const {value, onChange, render, name, node} = props;
|
const {value, onChange, render, name, node, placeholder} = props;
|
||||||
const [options, setOptions] = useState<Array<any>>([]);
|
const [options, setOptions] = useState<Array<any>>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -37,7 +37,8 @@ export function InputComponentName(props: InputComponentNameProps) {
|
|||||||
'inner',
|
'inner',
|
||||||
{
|
{
|
||||||
type: 'input-text',
|
type: 'input-text',
|
||||||
name
|
name,
|
||||||
|
placeholder
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value,
|
value,
|
||||||
|
@ -74,6 +74,7 @@ import './plugin/ButtonGroup';
|
|||||||
import './plugin/ButtonToolbar';
|
import './plugin/ButtonToolbar';
|
||||||
import './plugin/Breadcrumb';
|
import './plugin/Breadcrumb';
|
||||||
import './plugin/Card';
|
import './plugin/Card';
|
||||||
|
import './plugin/Card2';
|
||||||
import './plugin/Cards';
|
import './plugin/Cards';
|
||||||
import './plugin/Carousel';
|
import './plugin/Carousel';
|
||||||
import './plugin/Chart';
|
import './plugin/Chart';
|
||||||
@ -119,6 +120,8 @@ import './plugin/Steps';
|
|||||||
import './plugin/Sparkline';
|
import './plugin/Sparkline';
|
||||||
import './plugin/Submit';
|
import './plugin/Submit';
|
||||||
import './plugin/Table';
|
import './plugin/Table';
|
||||||
|
import './plugin/Table-v2';
|
||||||
|
import './plugin/TableCell-v2';
|
||||||
import './plugin/Tabs';
|
import './plugin/Tabs';
|
||||||
import './plugin/Tasks';
|
import './plugin/Tasks';
|
||||||
import './plugin/Time';
|
import './plugin/Time';
|
||||||
@ -131,6 +134,8 @@ import './plugin/TooltipWrapper';
|
|||||||
import './plugin/TableView';
|
import './plugin/TableView';
|
||||||
import './plugin/CodeView';
|
import './plugin/CodeView';
|
||||||
import './plugin/WebComponent';
|
import './plugin/WebComponent';
|
||||||
|
import './plugin/CRUD2';
|
||||||
|
import './plugin/ColumnToggler';
|
||||||
|
|
||||||
import {GridPlugin} from './plugin/Grid';
|
import {GridPlugin} from './plugin/Grid';
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ export class AlertPlugin extends BasePlugin {
|
|||||||
name: 'showCloseButton'
|
name: 'showCloseButton'
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
name: 'showIcon',
|
name: 'showIcon',
|
||||||
label: '图标',
|
label: '图标',
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||||
import {getSchemaTpl, defaultValue} from 'amis-editor-core';
|
import {getSchemaTpl, defaultValue} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
const DefaultSize = 40;
|
const DefaultSize = 40;
|
||||||
const DefaultBorderRadius = 20;
|
const DefaultBorderRadius = 20;
|
||||||
@ -173,7 +173,7 @@ export class AvatarPlugin extends BasePlugin {
|
|||||||
visibleOn: 'data.showtype === "text"'
|
visibleOn: 'data.showtype === "text"'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
// TODO 临时关闭,目前角标功能还没完善,待完善后再开启
|
// TODO 临时关闭,目前角标功能还没完善,待完善后再开启
|
||||||
// getSchemaTpl('badge')
|
// getSchemaTpl('badge')
|
||||||
]
|
]
|
||||||
|
@ -4,10 +4,11 @@ import {
|
|||||||
BasePlugin,
|
BasePlugin,
|
||||||
BasicRendererInfo,
|
BasicRendererInfo,
|
||||||
PluginInterface,
|
PluginInterface,
|
||||||
RendererInfoResolveEventContext
|
RendererInfoResolveEventContext,
|
||||||
|
tipedLabel
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {BUTTON_DEFAULT_ACTION, tipedLabel} from '../component/BaseControl';
|
import {BUTTON_DEFAULT_ACTION} from '../component/BaseControl';
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
import {SchemaObject} from 'amis/lib/Schema';
|
import {SchemaObject} from 'amis/lib/Schema';
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
|
||||||
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
|
||||||
import {
|
import {
|
||||||
BUTTON_DEFAULT_ACTION,
|
BasePlugin,
|
||||||
formItemControl,
|
RegionConfig,
|
||||||
tipedLabel
|
BaseEventContext,
|
||||||
} from '../component/BaseControl';
|
tipedLabel,
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
defaultValue,
|
||||||
import {RegionWrapper as Region} from 'amis-editor-core';
|
getSchemaTpl,
|
||||||
|
registerEditorPlugin
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
import {BUTTON_DEFAULT_ACTION} from '../component/BaseControl';
|
||||||
|
|
||||||
export class ButtonGroupPlugin extends BasePlugin {
|
export class ButtonGroupPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
1681
packages/amis-editor/src/plugin/CRUD2.tsx
Normal file
1681
packages/amis-editor/src/plugin/CRUD2.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,10 +4,13 @@ import {registerEditorPlugin} from 'amis-editor-core';
|
|||||||
import {
|
import {
|
||||||
BaseEventContext,
|
BaseEventContext,
|
||||||
BasePlugin,
|
BasePlugin,
|
||||||
|
BasicRendererInfo,
|
||||||
InsertEventContext,
|
InsertEventContext,
|
||||||
PluginEvent,
|
PluginEvent,
|
||||||
|
PluginInterface,
|
||||||
RegionConfig,
|
RegionConfig,
|
||||||
RendererInfo,
|
RendererInfo,
|
||||||
|
RendererInfoResolveEventContext,
|
||||||
VRendererConfig
|
VRendererConfig
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
@ -204,6 +207,8 @@ export class CardPlugin extends BasePlugin {
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
fieldWrapperResolve = (dom: HTMLElement) => dom;
|
fieldWrapperResolve = (dom: HTMLElement) => dom;
|
||||||
|
|
||||||
|
|
||||||
overrides = {
|
overrides = {
|
||||||
renderFeild: function (
|
renderFeild: function (
|
||||||
this: any,
|
this: any,
|
||||||
|
104
packages/amis-editor/src/plugin/Card2.tsx
Normal file
104
packages/amis-editor/src/plugin/Card2.tsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import {
|
||||||
|
BaseEventContext,
|
||||||
|
BasePlugin,
|
||||||
|
RegionConfig,
|
||||||
|
defaultValue,
|
||||||
|
getSchemaTpl,
|
||||||
|
tipedLabel,
|
||||||
|
registerEditorPlugin
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
|
||||||
|
export class Card2Plugin extends BasePlugin {
|
||||||
|
// 关联渲染器名字
|
||||||
|
rendererName = 'card2';
|
||||||
|
$schema = '/schemas/Card2Schema.json';
|
||||||
|
|
||||||
|
// 组件名称
|
||||||
|
name = '卡片';
|
||||||
|
isBaseComponent = true;
|
||||||
|
description = '展示单个卡片。';
|
||||||
|
tags = ['展示'];
|
||||||
|
icon = '';
|
||||||
|
scaffold = {
|
||||||
|
type: 'card2',
|
||||||
|
body: '内容'
|
||||||
|
};
|
||||||
|
previewSchema = {
|
||||||
|
...this.scaffold
|
||||||
|
};
|
||||||
|
|
||||||
|
regions: Array<RegionConfig> = [
|
||||||
|
{
|
||||||
|
key: 'body',
|
||||||
|
label: '内容区',
|
||||||
|
renderMethod: 'renderBody',
|
||||||
|
preferTag: '展示'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
panelTitle = '卡片';
|
||||||
|
|
||||||
|
panelJustify = true;
|
||||||
|
|
||||||
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
|
return [
|
||||||
|
getSchemaTpl('tabs', [
|
||||||
|
{
|
||||||
|
title: '属性',
|
||||||
|
body: getSchemaTpl('collapseGroup', [
|
||||||
|
{
|
||||||
|
title: '基本',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'button-group-select',
|
||||||
|
label: tipedLabel(
|
||||||
|
'选择区域',
|
||||||
|
'点击触发选中或取消选中的区域'
|
||||||
|
),
|
||||||
|
name: 'checkOnItemClick',
|
||||||
|
options: [
|
||||||
|
{label: '整个', value: true},
|
||||||
|
{label: '选框', value: false}
|
||||||
|
],
|
||||||
|
pipeIn: defaultValue(false)
|
||||||
|
},
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
label: tipedLabel(
|
||||||
|
'隐藏选框',
|
||||||
|
'不再显示选择框,可以通过自定义选中态外观实现选中样式'
|
||||||
|
),
|
||||||
|
name: 'hideCheckToggler',
|
||||||
|
visibleOn: 'this.checkOnItemClick'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
getSchemaTpl('status', {isFormItem: false})
|
||||||
|
])
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '外观',
|
||||||
|
body: getSchemaTpl('collapseGroup', [
|
||||||
|
getSchemaTpl('style:classNames', {
|
||||||
|
isFormItem: false,
|
||||||
|
schema: [
|
||||||
|
getSchemaTpl('className', {
|
||||||
|
name: 'bodyClassName',
|
||||||
|
label: '内容区',
|
||||||
|
visibleOn: 'this.icon'
|
||||||
|
}),
|
||||||
|
// TODO
|
||||||
|
getSchemaTpl('className', {
|
||||||
|
name: 'selectedClassName',
|
||||||
|
label: '选中态',
|
||||||
|
visibleOn: 'this.icon'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
|
])
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEditorPlugin(Card2Plugin);
|
@ -4,18 +4,17 @@ import {registerEditorPlugin} from 'amis-editor-core';
|
|||||||
import {
|
import {
|
||||||
BaseEventContext,
|
BaseEventContext,
|
||||||
BasePlugin,
|
BasePlugin,
|
||||||
BasicPanelItem,
|
|
||||||
BasicRendererInfo,
|
BasicRendererInfo,
|
||||||
BasicToolbarItem,
|
BasicToolbarItem,
|
||||||
ContextMenuEventContext,
|
ContextMenuEventContext,
|
||||||
ContextMenuItem,
|
ContextMenuItem,
|
||||||
PluginInterface,
|
PluginInterface,
|
||||||
RegionConfig,
|
RendererInfoResolveEventContext,
|
||||||
RendererInfo,
|
tipedLabel
|
||||||
RendererInfoResolveEventContext
|
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {diff, JSONPipeOut, repeatArray} from 'amis-editor-core';
|
import {diff, JSONPipeOut, repeatArray} from 'amis-editor-core';
|
||||||
|
import {getEventControlConfig} from '../util';
|
||||||
|
|
||||||
export class CardsPlugin extends BasePlugin {
|
export class CardsPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -41,26 +40,17 @@ export class CardsPlugin extends BasePlugin {
|
|||||||
},
|
},
|
||||||
columnsCount: 2,
|
columnsCount: 2,
|
||||||
card: {
|
card: {
|
||||||
type: 'card',
|
type: 'card2',
|
||||||
className: 'm-b-none',
|
className: 'm-b-none',
|
||||||
header: {
|
|
||||||
title: '标题',
|
|
||||||
subTitle: '副标题'
|
|
||||||
},
|
|
||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
name: 'a',
|
type: 'container',
|
||||||
label: 'A'
|
body: [
|
||||||
},
|
{
|
||||||
{
|
type: 'tpl',
|
||||||
name: 'b',
|
tpl: '这是一个模板'
|
||||||
label: 'B'
|
}
|
||||||
}
|
]
|
||||||
],
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
label: '详情',
|
|
||||||
type: 'button'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -71,116 +61,119 @@ export class CardsPlugin extends BasePlugin {
|
|||||||
};
|
};
|
||||||
|
|
||||||
panelTitle = '卡片集';
|
panelTitle = '卡片集';
|
||||||
|
|
||||||
|
panelJustify = true;
|
||||||
|
|
||||||
panelBodyCreator = (context: BaseEventContext) => {
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
const isCRUDBody = context.schema.type === 'crud';
|
const isCRUDBody = ['crud', 'crud2'].includes(context.schema.type);
|
||||||
return [
|
|
||||||
getSchemaTpl('tabs', [
|
return getSchemaTpl('tabs', [
|
||||||
{
|
{
|
||||||
title: '常规',
|
title: '属性',
|
||||||
body: [
|
body: getSchemaTpl('collapseGroup', [
|
||||||
{
|
{
|
||||||
children: (
|
title: '基本',
|
||||||
<div className="m-b">
|
body: [
|
||||||
<Button
|
getSchemaTpl('switch', {
|
||||||
level="success"
|
label: '可多选',
|
||||||
size="sm"
|
name: 'multiple',
|
||||||
block
|
visibleOn: `data.selectable`
|
||||||
onClick={this.editDetail.bind(this, context.id)}
|
}),
|
||||||
>
|
// getSchemaTpl('switch', {
|
||||||
配置单项信息
|
// label: '可全选',
|
||||||
</Button>
|
// name: 'checkAll',
|
||||||
</div>
|
// pipeIn: defaultValue(true),
|
||||||
)
|
// visibleOn: `data.selectable && data.multiple`
|
||||||
},
|
// }),
|
||||||
|
{
|
||||||
{
|
name: 'placeholder',
|
||||||
type: 'divider'
|
value: '暂无数据',
|
||||||
},
|
type: 'input-text',
|
||||||
{
|
label: '占位内容'
|
||||||
name: 'title',
|
}
|
||||||
type: 'input-text',
|
]
|
||||||
label: '标题'
|
},
|
||||||
},
|
{
|
||||||
{
|
title: '数据',
|
||||||
name: 'href',
|
hidden: isCRUDBody,
|
||||||
type: 'input-text',
|
body: [
|
||||||
label: '打开外部链接'
|
{
|
||||||
},
|
name: 'source',
|
||||||
isCRUDBody
|
type: 'input-text',
|
||||||
? null
|
label: tipedLabel('数据', '可绑定当前页面数据'),
|
||||||
: {
|
pipeIn: defaultValue('${items}'),
|
||||||
name: 'source',
|
// visible: !isCRUDBody
|
||||||
type: 'input-text',
|
},
|
||||||
label: '数据源',
|
{
|
||||||
pipeIn: defaultValue('${items}'),
|
name: 'valueField',
|
||||||
description: '绑定当前环境变量',
|
type: 'input-text',
|
||||||
test: !isCRUDBody
|
label: '值字段',
|
||||||
},
|
// visible: isInForm && !isCRUDBody
|
||||||
{
|
},
|
||||||
name: 'placeholder',
|
]
|
||||||
value: '暂无数据',
|
},
|
||||||
type: 'input-text',
|
getSchemaTpl('status', {
|
||||||
label: '无数据提示'
|
isFormItem: false
|
||||||
}
|
})
|
||||||
]
|
])
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '外观',
|
title: '外观',
|
||||||
body: [
|
body: getSchemaTpl('collapseGroup', [
|
||||||
getSchemaTpl('switch', {
|
{
|
||||||
name: 'showHeader',
|
title: '布局',
|
||||||
label: '是否显示头部',
|
body: [
|
||||||
pipeIn: defaultValue(true)
|
{
|
||||||
}),
|
type: 'button-group-select',
|
||||||
|
name: 'masonryLayout',
|
||||||
getSchemaTpl('switch', {
|
label: '模式',
|
||||||
name: 'showFooter',
|
pipeIn: defaultValue(false),
|
||||||
label: '是否显示底部',
|
options: [
|
||||||
pipeIn: defaultValue(true)
|
{label: '瀑布', value: true},
|
||||||
}),
|
{label: '流式', value: false}
|
||||||
|
]
|
||||||
getSchemaTpl('className', {
|
},
|
||||||
label: 'CSS 类名'
|
{
|
||||||
}),
|
name: 'columnsCount',
|
||||||
getSchemaTpl('className', {
|
type: 'input-range',
|
||||||
name: 'headerClassName',
|
pipeIn: defaultValue(4),
|
||||||
label: '头部 CSS 类名'
|
min: 0,
|
||||||
}),
|
max: 12,
|
||||||
getSchemaTpl('className', {
|
step: 1,
|
||||||
name: 'footerClassName',
|
label: tipedLabel(
|
||||||
label: '底部 CSS 类名'
|
'每行显示个数',
|
||||||
}),
|
'不设置时,由卡片 CSS 类名决定'
|
||||||
getSchemaTpl('className', {
|
)
|
||||||
name: 'itemsClassName',
|
}
|
||||||
label: '内容 CSS 类名'
|
]
|
||||||
}),
|
},
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('style:classNames', {
|
||||||
pipeIn: defaultValue('Grid-col--sm6 Grid-col--md4 Grid-col--lg3'),
|
isFormItem: false,
|
||||||
name: 'itemClassName',
|
schema: [
|
||||||
label: '卡片 CSS 类名'
|
getSchemaTpl('className', {
|
||||||
}),
|
name: 'itemsClassName',
|
||||||
{
|
label: '内容'
|
||||||
name: 'columnsCount',
|
}),
|
||||||
type: 'input-range',
|
getSchemaTpl('className', {
|
||||||
visibleOn: '!this.leftFixed',
|
pipeIn: defaultValue('Grid-col--sm6 Grid-col--md4 Grid-col--lg3'),
|
||||||
min: 0,
|
name: 'itemClassName',
|
||||||
max: 12,
|
label: '卡片'
|
||||||
step: 1,
|
}),
|
||||||
label: '每行显示个数',
|
]
|
||||||
description: '不设置时,由卡片 CSS 类名决定'
|
})
|
||||||
},
|
])
|
||||||
getSchemaTpl('switch', {
|
},
|
||||||
name: 'masonryLayout',
|
{
|
||||||
label: '启用瀑布流'
|
title: '事件',
|
||||||
})
|
className: 'p-none',
|
||||||
]
|
body: [
|
||||||
},
|
getSchemaTpl('eventControl', {
|
||||||
{
|
name: 'onEvent',
|
||||||
title: '显隐',
|
...getEventControlConfig(this.manager, context)
|
||||||
body: [getSchemaTpl('ref'), getSchemaTpl('visible')]
|
})
|
||||||
}
|
]
|
||||||
])
|
}
|
||||||
];
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
editDetail(id: string) {
|
editDetail(id: string) {
|
||||||
@ -253,14 +246,16 @@ export class CardsPlugin extends BasePlugin {
|
|||||||
...props.defaultData,
|
...props.defaultData,
|
||||||
...props.data
|
...props.data
|
||||||
};
|
};
|
||||||
const arr = Array.isArray(props.value)
|
let value = Array.isArray(props.value)
|
||||||
? props.value
|
? props.value
|
||||||
: typeof props.source === 'string'
|
: typeof props.source === 'string'
|
||||||
? resolveVariable(props.source, data)
|
? resolveVariable(props.source, data)
|
||||||
: resolveVariable('items', data);
|
: resolveVariable('items', data);
|
||||||
|
|
||||||
if (!Array.isArray(arr) || !arr.length) {
|
value = !Array.isArray(value) ? [] : value;
|
||||||
const mockedData: any = {
|
|
||||||
|
if (value.length < 5) {
|
||||||
|
const mockedData: any = value.length ? value[0] : {
|
||||||
id: 666,
|
id: 666,
|
||||||
title: '假数据',
|
title: '假数据',
|
||||||
description: '假数据',
|
description: '假数据',
|
||||||
@ -268,20 +263,36 @@ export class CardsPlugin extends BasePlugin {
|
|||||||
b: '假数据'
|
b: '假数据'
|
||||||
};
|
};
|
||||||
|
|
||||||
props.value = repeatArray(mockedData, 1).map((item, index) => ({
|
value = value.concat(repeatArray(mockedData, 3).map((item, index) => ({
|
||||||
...item,
|
...item,
|
||||||
id: index + 1
|
id: index + 1
|
||||||
}));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
const {$schema, ...rest} = props;
|
value = value.slice(0, 4);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...JSONPipeOut(rest),
|
...props,
|
||||||
$schema
|
value
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overrides = {
|
||||||
|
renderCard(
|
||||||
|
this: any,
|
||||||
|
index: number,
|
||||||
|
card: any,
|
||||||
|
...rest: any[]
|
||||||
|
) {
|
||||||
|
return this.super(
|
||||||
|
index,
|
||||||
|
// 使第一个卡片元素可以选择并编辑schema
|
||||||
|
index > 0 ? JSONPipeOut(card) : card,
|
||||||
|
...rest
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getRendererInfo(
|
getRendererInfo(
|
||||||
context: RendererInfoResolveEventContext
|
context: RendererInfoResolveEventContext
|
||||||
): BasicRendererInfo | void {
|
): BasicRendererInfo | void {
|
||||||
@ -289,7 +300,7 @@ export class CardsPlugin extends BasePlugin {
|
|||||||
const {renderer, schema} = context;
|
const {renderer, schema} = context;
|
||||||
if (
|
if (
|
||||||
!schema.$$id &&
|
!schema.$$id &&
|
||||||
schema.$$editor?.renderer.name === 'crud' &&
|
['crud', 'crud2'].includes(schema.$$editor?.renderer.name) &&
|
||||||
renderer.name === 'cards'
|
renderer.name === 'cards'
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
export class CollapsePlugin extends BasePlugin {
|
export class CollapsePlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
@ -2,7 +2,7 @@ import {registerEditorPlugin} from 'amis-editor-core';
|
|||||||
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
|
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
import {isObject} from 'amis-editor-core';
|
import {isObject} from 'amis-editor-core';
|
||||||
|
|
||||||
export class CollapseGroupPlugin extends BasePlugin {
|
export class CollapseGroupPlugin extends BasePlugin {
|
||||||
|
129
packages/amis-editor/src/plugin/ColumnToggler.tsx
Normal file
129
packages/amis-editor/src/plugin/ColumnToggler.tsx
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import {
|
||||||
|
BaseEventContext,
|
||||||
|
BasePlugin,
|
||||||
|
BasicRendererInfo,
|
||||||
|
PluginInterface,
|
||||||
|
RendererInfoResolveEventContext,
|
||||||
|
getSchemaTpl,
|
||||||
|
registerEditorPlugin
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
|
||||||
|
export class ColumnToggler extends BasePlugin {
|
||||||
|
// 关联渲染器名字
|
||||||
|
rendererName = 'column-toggler';
|
||||||
|
$schema = '/schemas/ColumnToggler.json';
|
||||||
|
|
||||||
|
// 组件名称
|
||||||
|
name = '自定义显示列';
|
||||||
|
isBaseComponent = true;
|
||||||
|
description =
|
||||||
|
'用来展示表格的自定义显示列按钮,你可以配置不同的展示样式。';
|
||||||
|
|
||||||
|
tags = ['自定义显示列'];
|
||||||
|
icon = 'fa fa-square';
|
||||||
|
|
||||||
|
panelTitle = '自定义显示列';
|
||||||
|
|
||||||
|
panelJustify = true;
|
||||||
|
|
||||||
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
|
return getSchemaTpl('tabs', [
|
||||||
|
{
|
||||||
|
title: '属性',
|
||||||
|
body: getSchemaTpl('collapseGroup', [
|
||||||
|
{
|
||||||
|
title: '基本',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
label: '按钮文字',
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'label'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '按钮提示',
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'tooltip'
|
||||||
|
},
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'defaultIsOpened',
|
||||||
|
label: '是否默认展开'
|
||||||
|
}),
|
||||||
|
getSchemaTpl('icon', {
|
||||||
|
label: '按钮图标'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '外观',
|
||||||
|
body: getSchemaTpl('collapseGroup', [
|
||||||
|
{
|
||||||
|
title: '基本',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('size', {
|
||||||
|
label: '按钮尺寸'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'CSS 类名',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('className', {
|
||||||
|
name: 'className',
|
||||||
|
label: '显示列样式'
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('className', {
|
||||||
|
name: 'btnClassName',
|
||||||
|
label: '按钮样式'
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果禁用了没办法编辑
|
||||||
|
*/
|
||||||
|
filterProps(props: any) {
|
||||||
|
props.disabled = false;
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果配置里面有 rendererName 自动返回渲染器信息。
|
||||||
|
* @param renderer
|
||||||
|
*/
|
||||||
|
getRendererInfo({
|
||||||
|
renderer,
|
||||||
|
schema
|
||||||
|
}: RendererInfoResolveEventContext): BasicRendererInfo | void {
|
||||||
|
const plugin: PluginInterface = this;
|
||||||
|
|
||||||
|
if (
|
||||||
|
schema.$$id &&
|
||||||
|
plugin.name &&
|
||||||
|
plugin.rendererName &&
|
||||||
|
plugin.rendererName === renderer.name
|
||||||
|
) {
|
||||||
|
// 复制部分信息出去
|
||||||
|
return {
|
||||||
|
name: schema.label ? schema.label : plugin.name,
|
||||||
|
regions: plugin.regions,
|
||||||
|
patchContainers: plugin.patchContainers,
|
||||||
|
// wrapper: plugin.wrapper,
|
||||||
|
vRendererConfig: plugin.vRendererConfig,
|
||||||
|
wrapperProps: plugin.wrapperProps,
|
||||||
|
wrapperResolve: plugin.wrapperResolve,
|
||||||
|
filterProps: plugin.filterProps,
|
||||||
|
$schema: plugin.$schema,
|
||||||
|
renderRenderer: plugin.renderRenderer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEditorPlugin(ColumnToggler);
|
@ -12,11 +12,17 @@ export class ContainerPlugin extends BasePlugin {
|
|||||||
isBaseComponent = true;
|
isBaseComponent = true;
|
||||||
description = '一个简单的容器,可以将多个渲染器放置在一起。';
|
description = '一个简单的容器,可以将多个渲染器放置在一起。';
|
||||||
tags = ['容器'];
|
tags = ['容器'];
|
||||||
|
withDataSource = false;
|
||||||
icon = 'fa fa-square-o';
|
icon = 'fa fa-square-o';
|
||||||
pluginIcon = 'container-plugin';
|
pluginIcon = 'container-plugin';
|
||||||
scaffold = {
|
scaffold = {
|
||||||
type: 'container',
|
type: 'container',
|
||||||
body: '内容'
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '内容'
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
previewSchema = {
|
previewSchema = {
|
||||||
...this.scaffold
|
...this.scaffold
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
import {Button} from 'amis';
|
import {Button} from 'amis';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
|
||||||
import {
|
import {
|
||||||
BaseEventContext,
|
BaseEventContext,
|
||||||
BasePlugin,
|
BasePlugin,
|
||||||
BasicToolbarItem,
|
BasicToolbarItem,
|
||||||
ContextMenuEventContext,
|
ContextMenuEventContext,
|
||||||
ContextMenuItem
|
ContextMenuItem,
|
||||||
|
registerEditorPlugin,
|
||||||
|
tipedLabel,
|
||||||
|
defaultValue,
|
||||||
|
getSchemaTpl,
|
||||||
|
diff
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {BUTTON_DEFAULT_ACTION} from '../component/BaseControl';
|
||||||
import {diff} from 'amis-editor-core';
|
|
||||||
import {
|
|
||||||
BUTTON_DEFAULT_ACTION,
|
|
||||||
formItemControl,
|
|
||||||
tipedLabel
|
|
||||||
} from '../component/BaseControl';
|
|
||||||
export class DropDownButtonPlugin extends BasePlugin {
|
export class DropDownButtonPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
rendererName = 'dropdown-button';
|
rendererName = 'dropdown-button';
|
||||||
|
@ -3,10 +3,10 @@ import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
RendererPluginAction,
|
RendererPluginAction,
|
||||||
RendererPluginEvent
|
RendererPluginEvent,
|
||||||
|
tipedLabel
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {getSchemaTpl, defaultValue} from 'amis-editor-core';
|
import {getSchemaTpl, defaultValue} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
|
|
||||||
export class ButtonGroupControlPlugin extends BasePlugin {
|
export class ButtonGroupControlPlugin extends BasePlugin {
|
||||||
@ -118,17 +118,15 @@ export class ButtonGroupControlPlugin extends BasePlugin {
|
|||||||
rendererSchema: context?.schema,
|
rendererSchema: context?.schema,
|
||||||
useSelectMode: true, // 改用 Select 设置模式
|
useSelectMode: true, // 改用 Select 设置模式
|
||||||
visibleOn: 'this.options && this.options.length > 0'
|
visibleOn: 'this.options && this.options.length > 0'
|
||||||
}),
|
})
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '按钮管理',
|
title: '按钮管理',
|
||||||
body: [
|
body: [getSchemaTpl('optionControlV2')]
|
||||||
getSchemaTpl('optionControlV2'),
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
getSchemaTpl('status', {
|
getSchemaTpl('status', {
|
||||||
isFormItem: true,
|
isFormItem: true
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
@ -172,10 +170,10 @@ export class ButtonGroupControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('className', {
|
getSchemaTpl('className', {
|
||||||
label: '按钮',
|
label: '按钮',
|
||||||
name: 'btnClassName'
|
name: 'btnClassName'
|
||||||
}),
|
})
|
||||||
]
|
]
|
||||||
}),
|
})
|
||||||
]),
|
])
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4,16 +4,15 @@ import {
|
|||||||
BaseEventContext,
|
BaseEventContext,
|
||||||
BasicSubRenderInfo,
|
BasicSubRenderInfo,
|
||||||
RendererEventContext,
|
RendererEventContext,
|
||||||
SubRendererInfo
|
SubRendererInfo,
|
||||||
} from 'amis-editor-core';
|
|
||||||
import {getSchemaTpl, defaultValue} from 'amis-editor-core';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {getEventControlConfig} from '../../util';
|
|
||||||
import {
|
|
||||||
RendererPluginAction,
|
RendererPluginAction,
|
||||||
RendererPluginEvent
|
RendererPluginEvent,
|
||||||
|
tipedLabel,
|
||||||
|
getSchemaTpl,
|
||||||
|
defaultValue
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
|
import {ValidatorTag} from '../../validator';
|
||||||
|
import {getEventControlConfig} from '../../util';
|
||||||
|
|
||||||
export class ChainedSelectControlPlugin extends BasePlugin {
|
export class ChainedSelectControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -135,7 +134,8 @@ export class ChainedSelectControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('placeholder'),
|
getSchemaTpl('placeholder'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -10,14 +10,12 @@ import {
|
|||||||
BasicSubRenderInfo,
|
BasicSubRenderInfo,
|
||||||
RendererEventContext,
|
RendererEventContext,
|
||||||
SubRendererInfo,
|
SubRendererInfo,
|
||||||
BaseEventContext
|
BaseEventContext,
|
||||||
|
tipedLabel
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
|
|
||||||
setSchemaTpl('option', {
|
setSchemaTpl('option', {
|
||||||
@ -110,7 +108,7 @@ export class CheckboxControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('label'),
|
getSchemaTpl('label'),
|
||||||
getSchemaTpl('option'),
|
getSchemaTpl('option'),
|
||||||
{
|
{
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
hiddenOnDefault: false,
|
hiddenOnDefault: false,
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
label: '值格式',
|
label: '值格式',
|
||||||
@ -152,7 +150,8 @@ export class CheckboxControlPlugin extends BasePlugin {
|
|||||||
}),
|
}),
|
||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
getSchemaTpl('status', {isFormItem: true}),
|
getSchemaTpl('status', {isFormItem: true}),
|
||||||
|
@ -168,7 +168,8 @@ export class CheckboxesControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('extractValue'),
|
getSchemaTpl('extractValue'),
|
||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -140,7 +140,8 @@ export class CodeEditorControlPlugin extends BasePlugin {
|
|||||||
}),
|
}),
|
||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
getSchemaTpl('status', {isFormItem: true}),
|
getSchemaTpl('status', {isFormItem: true}),
|
||||||
|
@ -149,7 +149,8 @@ export class DiffEditorControlPlugin extends BasePlugin {
|
|||||||
},
|
},
|
||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
getSchemaTpl('status', {isFormItem: true}),
|
getSchemaTpl('status', {isFormItem: true}),
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,10 +9,7 @@ import {
|
|||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
|
|
||||||
import {formItemControl} from '../../component/BaseControl';
|
import {formItemControl} from '../../component/BaseControl';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class CityControlPlugin extends BasePlugin {
|
export class CityControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin, tipedLabel} from 'amis-editor-core';
|
||||||
import {getSchemaTpl} from 'amis-editor-core';
|
import {getSchemaTpl} from 'amis-editor-core';
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import tinyColor from 'tinycolor2';
|
import tinyColor from 'tinycolor2';
|
||||||
|
|
||||||
function convertColor(value: string[], format: string): string[];
|
function convertColor(value: string[], format: string): string[];
|
||||||
@ -171,124 +170,133 @@ export class ColorControlPlugin extends BasePlugin {
|
|||||||
return getSchemaTpl('tabs', [
|
return getSchemaTpl('tabs', [
|
||||||
{
|
{
|
||||||
title: '属性',
|
title: '属性',
|
||||||
body: getSchemaTpl('collapseGroup', [
|
body: getSchemaTpl(
|
||||||
{
|
'collapseGroup',
|
||||||
title: '基本',
|
[
|
||||||
body: [
|
{
|
||||||
getSchemaTpl('formItemName', {
|
title: '基本',
|
||||||
required: true
|
body: [
|
||||||
}),
|
getSchemaTpl('formItemName', {
|
||||||
getSchemaTpl('label'),
|
required: true
|
||||||
{
|
}),
|
||||||
type: 'select',
|
getSchemaTpl('label'),
|
||||||
label: '值格式',
|
{
|
||||||
name: 'format',
|
type: 'select',
|
||||||
value: 'hex',
|
label: '值格式',
|
||||||
options: formatOptions,
|
name: 'format',
|
||||||
onChange: (
|
value: 'hex',
|
||||||
format: any,
|
options: formatOptions,
|
||||||
oldFormat: any,
|
onChange: (
|
||||||
model: any,
|
format: any,
|
||||||
form: any
|
oldFormat: any,
|
||||||
) => {
|
model: any,
|
||||||
const {value, presetColors} = form.data;
|
form: any
|
||||||
if (value) {
|
) => {
|
||||||
form.setValueByName('value', convertColor(value, format));
|
const {value, presetColors} = form.data;
|
||||||
|
if (value) {
|
||||||
|
form.setValueByName('value', convertColor(value, format));
|
||||||
|
}
|
||||||
|
if (Array.isArray(presetColors)) {
|
||||||
|
form.setValueByName(
|
||||||
|
'presetColors',
|
||||||
|
convertColor(presetColors, format)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (Array.isArray(presetColors)) {
|
|
||||||
form.setValueByName(
|
|
||||||
'presetColors',
|
|
||||||
convertColor(presetColors, format)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// todo: 待优化
|
|
||||||
[
|
|
||||||
...formatOptions.map(({value}) =>
|
|
||||||
this.getConditionalColorPanel(value)
|
|
||||||
)
|
|
||||||
],
|
|
||||||
// {
|
|
||||||
// label: '默认值',
|
|
||||||
// name: 'value',
|
|
||||||
// type: 'input-color',
|
|
||||||
// format: '${format}'
|
|
||||||
// },
|
|
||||||
getSchemaTpl('clearable'),
|
|
||||||
getSchemaTpl('labelRemark'),
|
|
||||||
getSchemaTpl('remark'),
|
|
||||||
getSchemaTpl('placeholder'),
|
|
||||||
getSchemaTpl('description')
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '拾色器',
|
|
||||||
body: [
|
|
||||||
getSchemaTpl('switch', {
|
|
||||||
label: tipedLabel(
|
|
||||||
'隐藏调色盘',
|
|
||||||
'开启时,禁止手动输入颜色,只能从备选颜色中选择'
|
|
||||||
),
|
|
||||||
name: 'allowCustomColor',
|
|
||||||
disabledOn:
|
|
||||||
'Array.isArray(presetColors) && presetColors.length === 0',
|
|
||||||
pipeIn: (value: any) =>
|
|
||||||
typeof value === 'undefined' ? false : !value,
|
|
||||||
pipeOut: (value: boolean) => !value
|
|
||||||
}),
|
|
||||||
getSchemaTpl('switch', {
|
|
||||||
label: tipedLabel('备选色', '拾色器底部的备选颜色'),
|
|
||||||
name: 'presetColors',
|
|
||||||
onText: '自定义',
|
|
||||||
offText: '默认',
|
|
||||||
pipeIn: (value: any) =>
|
|
||||||
typeof value === 'undefined' ? false : true,
|
|
||||||
pipeOut: (
|
|
||||||
value: any,
|
|
||||||
originValue: any,
|
|
||||||
{format = 'hex'}: any
|
|
||||||
) => {
|
|
||||||
return !value ? undefined : presetColorsByFormat[format];
|
|
||||||
},
|
},
|
||||||
onChange: (
|
// todo: 待优化
|
||||||
colors: any,
|
[
|
||||||
oldValue: any,
|
...formatOptions.map(({value}) =>
|
||||||
model: any,
|
this.getConditionalColorPanel(value)
|
||||||
form: any
|
)
|
||||||
) => {
|
],
|
||||||
if (Array.isArray(colors) && colors.length === 0) {
|
// {
|
||||||
form.setValueByName('allowCustomColor', true);
|
// label: '默认值',
|
||||||
|
// name: 'value',
|
||||||
|
// type: 'input-color',
|
||||||
|
// format: '${format}'
|
||||||
|
// },
|
||||||
|
getSchemaTpl('clearable'),
|
||||||
|
getSchemaTpl('labelRemark'),
|
||||||
|
getSchemaTpl('remark'),
|
||||||
|
getSchemaTpl('placeholder'),
|
||||||
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '拾色器',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
label: tipedLabel(
|
||||||
|
'隐藏调色盘',
|
||||||
|
'开启时,禁止手动输入颜色,只能从备选颜色中选择'
|
||||||
|
),
|
||||||
|
name: 'allowCustomColor',
|
||||||
|
disabledOn:
|
||||||
|
'Array.isArray(presetColors) && presetColors.length === 0',
|
||||||
|
pipeIn: (value: any) =>
|
||||||
|
typeof value === 'undefined' ? false : !value,
|
||||||
|
pipeOut: (value: boolean) => !value
|
||||||
|
}),
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
label: tipedLabel('备选色', '拾色器底部的备选颜色'),
|
||||||
|
name: 'presetColors',
|
||||||
|
onText: '自定义',
|
||||||
|
offText: '默认',
|
||||||
|
pipeIn: (value: any) =>
|
||||||
|
typeof value === 'undefined' ? false : true,
|
||||||
|
pipeOut: (
|
||||||
|
value: any,
|
||||||
|
originValue: any,
|
||||||
|
{format = 'hex'}: any
|
||||||
|
) => {
|
||||||
|
return !value ? undefined : presetColorsByFormat[format];
|
||||||
|
},
|
||||||
|
onChange: (
|
||||||
|
colors: any,
|
||||||
|
oldValue: any,
|
||||||
|
model: any,
|
||||||
|
form: any
|
||||||
|
) => {
|
||||||
|
if (Array.isArray(colors) && colors.length === 0) {
|
||||||
|
form.setValueByName('allowCustomColor', true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}),
|
||||||
}),
|
...formatOptions.map(({value}) =>
|
||||||
...formatOptions.map(({value}) =>
|
this.getConditionalColorComb(value)
|
||||||
this.getConditionalColorComb(value)
|
)
|
||||||
)
|
]
|
||||||
]
|
},
|
||||||
},
|
getSchemaTpl('status', {
|
||||||
getSchemaTpl('status', {
|
isFormItem: true
|
||||||
isFormItem: true
|
}),
|
||||||
}),
|
getSchemaTpl('validation', {
|
||||||
getSchemaTpl('validation', {
|
tag: ValidatorTag.MultiSelect
|
||||||
tag: ValidatorTag.MultiSelect
|
})
|
||||||
})
|
],
|
||||||
], {...context?.schema, configTitle: 'props'})
|
{...context?.schema, configTitle: 'props'}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '外观',
|
title: '外观',
|
||||||
body: getSchemaTpl('collapseGroup', [
|
body: getSchemaTpl(
|
||||||
getSchemaTpl('style:formItem', {renderer}),
|
'collapseGroup',
|
||||||
getSchemaTpl('style:classNames', {
|
[
|
||||||
schema: [
|
getSchemaTpl('style:formItem', {renderer}),
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('style:classNames', {
|
||||||
label: '描述',
|
schema: [
|
||||||
name: 'descriptionClassName',
|
getSchemaTpl('className', {
|
||||||
visibleOn: 'this.description'
|
label: '描述',
|
||||||
})
|
name: 'descriptionClassName',
|
||||||
]
|
visibleOn: 'this.description'
|
||||||
})
|
})
|
||||||
], {...context?.schema, configTitle: 'style'})
|
]
|
||||||
|
})
|
||||||
|
],
|
||||||
|
{...context?.schema, configTitle: 'style'}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '事件',
|
title: '事件',
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext, tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
const formatX = [
|
const formatX = [
|
||||||
{
|
{
|
||||||
@ -237,157 +233,166 @@ export class DateControlPlugin extends BasePlugin {
|
|||||||
return getSchemaTpl('tabs', [
|
return getSchemaTpl('tabs', [
|
||||||
{
|
{
|
||||||
title: '属性',
|
title: '属性',
|
||||||
body: getSchemaTpl('collapseGroup', [
|
body: getSchemaTpl(
|
||||||
{
|
'collapseGroup',
|
||||||
title: '基本',
|
[
|
||||||
body: [
|
{
|
||||||
getSchemaTpl('formItemName', {
|
title: '基本',
|
||||||
required: true
|
body: [
|
||||||
}),
|
getSchemaTpl('formItemName', {
|
||||||
getSchemaTpl('label'),
|
required: true
|
||||||
getSchemaTpl('selectDateType', {
|
}),
|
||||||
value: this.scaffold.type,
|
getSchemaTpl('label'),
|
||||||
onChange: (
|
getSchemaTpl('selectDateType', {
|
||||||
value: string,
|
value: this.scaffold.type,
|
||||||
oldValue: any,
|
onChange: (
|
||||||
model: any,
|
value: string,
|
||||||
form: any
|
oldValue: any,
|
||||||
) => {
|
model: any,
|
||||||
let type: string = value.split('-')[1];
|
form: any
|
||||||
|
) => {
|
||||||
|
let type: string = value.split('-')[1];
|
||||||
|
|
||||||
form.setValues({
|
|
||||||
inputFormat: DateType[type]?.format,
|
|
||||||
placeholder: DateType[type]?.placeholder,
|
|
||||||
format: type === 'time' ? 'HH:mm' : 'X',
|
|
||||||
minDate: '',
|
|
||||||
maxDate: '',
|
|
||||||
value: ''
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'format',
|
|
||||||
label: tipedLabel(
|
|
||||||
'值格式',
|
|
||||||
'提交数据前将根据设定格式化数据,请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
|
||||||
),
|
|
||||||
pipeIn: defaultValue('X')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'inputFormat',
|
|
||||||
label: tipedLabel(
|
|
||||||
'显示格式',
|
|
||||||
'请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
|
||||||
),
|
|
||||||
pipeIn: defaultValue('YYYY-MM-DD'),
|
|
||||||
clearable: true,
|
|
||||||
onChange: (
|
|
||||||
value: string,
|
|
||||||
oldValue: any,
|
|
||||||
model: any,
|
|
||||||
form: any
|
|
||||||
) => {
|
|
||||||
const type = form.data.type.split('-')[1];
|
|
||||||
model.setOptions(DateType[type].formatOptions);
|
|
||||||
// 时间日期类组件 input-time 需要更加关注 timeFormat 和 inputFormat 属性区别
|
|
||||||
// inputFormat 表示输入框内的显示格式; timeFormat表示选择下拉弹窗中展示"HH、mm、ss"的组合
|
|
||||||
if (type === 'time') {
|
|
||||||
const timeFormatObj = DateType[type].formatOptions.find(
|
|
||||||
item => item.value === value
|
|
||||||
);
|
|
||||||
const timeFormat = timeFormatObj
|
|
||||||
? (timeFormatObj as any).timeFormat
|
|
||||||
: 'HH:mm:ss';
|
|
||||||
form.setValues({
|
form.setValues({
|
||||||
timeFormat: timeFormat
|
inputFormat: DateType[type]?.format,
|
||||||
|
placeholder: DateType[type]?.placeholder,
|
||||||
|
format: type === 'time' ? 'HH:mm' : 'X',
|
||||||
|
minDate: '',
|
||||||
|
maxDate: '',
|
||||||
|
value: ''
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'format',
|
||||||
|
label: tipedLabel(
|
||||||
|
'值格式',
|
||||||
|
'提交数据前将根据设定格式化数据,请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
||||||
|
),
|
||||||
|
pipeIn: defaultValue('X')
|
||||||
},
|
},
|
||||||
options:
|
{
|
||||||
DateType[this.scaffold.type.split('-')[1]].formatOptions
|
type: 'input-text',
|
||||||
},
|
name: 'inputFormat',
|
||||||
getSchemaTpl('utc'),
|
label: tipedLabel(
|
||||||
getSchemaTpl('clearable', {
|
'显示格式',
|
||||||
pipeIn: defaultValue(true)
|
'请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
||||||
}),
|
),
|
||||||
getSchemaTpl('valueFormula', {
|
pipeIn: defaultValue('YYYY-MM-DD'),
|
||||||
rendererSchema: context?.schema,
|
clearable: true,
|
||||||
label: tipedLabel(
|
onChange: (
|
||||||
'默认值',
|
value: string,
|
||||||
'支持 <code>now、+1day、-2weeks、+1hours、+2years</code>等这种相对值用法'
|
oldValue: any,
|
||||||
)
|
model: any,
|
||||||
}),
|
form: any
|
||||||
getSchemaTpl('valueFormula', {
|
) => {
|
||||||
name: 'minDate',
|
const type = form.data.type.split('-')[1];
|
||||||
rendererSchema: {
|
model.setOptions(DateType[type].formatOptions);
|
||||||
...context?.schema,
|
// 时间日期类组件 input-time 需要更加关注 timeFormat 和 inputFormat 属性区别
|
||||||
value: context?.schema.minDate
|
// inputFormat 表示输入框内的显示格式; timeFormat表示选择下拉弹窗中展示"HH、mm、ss"的组合
|
||||||
|
if (type === 'time') {
|
||||||
|
const timeFormatObj = DateType[type].formatOptions.find(
|
||||||
|
item => item.value === value
|
||||||
|
);
|
||||||
|
const timeFormat = timeFormatObj
|
||||||
|
? (timeFormatObj as any).timeFormat
|
||||||
|
: 'HH:mm:ss';
|
||||||
|
form.setValues({
|
||||||
|
timeFormat: timeFormat
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options:
|
||||||
|
DateType[this.scaffold.type.split('-')[1]].formatOptions
|
||||||
},
|
},
|
||||||
needDeleteProps: ['minDate'], // 避免自我限制
|
getSchemaTpl('utc'),
|
||||||
label: tipedLabel('最小值', tipedLabelText)
|
getSchemaTpl('clearable', {
|
||||||
}),
|
pipeIn: defaultValue(true)
|
||||||
getSchemaTpl('valueFormula', {
|
}),
|
||||||
name: 'maxDate',
|
getSchemaTpl('valueFormula', {
|
||||||
rendererSchema: {
|
rendererSchema: context?.schema,
|
||||||
...context?.schema,
|
label: tipedLabel(
|
||||||
value: context?.schema.maxDate
|
'默认值',
|
||||||
},
|
'支持 <code>now、+1day、-2weeks、+1hours、+2years</code>等这种相对值用法'
|
||||||
needDeleteProps: ['maxDate'], // 避免自我限制
|
)
|
||||||
label: tipedLabel('最大值', tipedLabelText)
|
}),
|
||||||
}),
|
getSchemaTpl('valueFormula', {
|
||||||
getSchemaTpl('placeholder', {
|
name: 'minDate',
|
||||||
pipeIn: defaultValue('请选择日期')
|
rendererSchema: {
|
||||||
}),
|
...context?.schema,
|
||||||
// getSchemaTpl('remark'),
|
value: context?.schema.minDate
|
||||||
// getSchemaTpl('labelRemark'),
|
},
|
||||||
getSchemaTpl('description')
|
needDeleteProps: ['minDate'], // 避免自我限制
|
||||||
]
|
label: tipedLabel('最小值', tipedLabelText)
|
||||||
},
|
}),
|
||||||
getSchemaTpl('status', {isFormItem: true}),
|
getSchemaTpl('valueFormula', {
|
||||||
getSchemaTpl('validation', {
|
name: 'maxDate',
|
||||||
tag: ValidatorTag.Date
|
rendererSchema: {
|
||||||
})
|
...context?.schema,
|
||||||
], {...context?.schema, configTitle: 'props'})
|
value: context?.schema.maxDate
|
||||||
|
},
|
||||||
|
needDeleteProps: ['maxDate'], // 避免自我限制
|
||||||
|
label: tipedLabel('最大值', tipedLabelText)
|
||||||
|
}),
|
||||||
|
getSchemaTpl('placeholder', {
|
||||||
|
pipeIn: defaultValue('请选择日期')
|
||||||
|
}),
|
||||||
|
// getSchemaTpl('remark'),
|
||||||
|
// getSchemaTpl('labelRemark'),
|
||||||
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
getSchemaTpl('status', {isFormItem: true}),
|
||||||
|
getSchemaTpl('validation', {
|
||||||
|
tag: ValidatorTag.Date
|
||||||
|
})
|
||||||
|
],
|
||||||
|
{...context?.schema, configTitle: 'props'}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '外观',
|
title: '外观',
|
||||||
body: getSchemaTpl('collapseGroup', [
|
body: getSchemaTpl(
|
||||||
getSchemaTpl('style:formItem', renderer),
|
'collapseGroup',
|
||||||
getSchemaTpl('style:classNames', [
|
[
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('style:formItem', renderer),
|
||||||
label: '描述',
|
getSchemaTpl('style:classNames', [
|
||||||
name: 'descriptionClassName',
|
getSchemaTpl('className', {
|
||||||
visibleOn: 'this.description'
|
label: '描述',
|
||||||
}),
|
name: 'descriptionClassName',
|
||||||
getSchemaTpl('className', {
|
visibleOn: 'this.description'
|
||||||
name: 'addOn.className',
|
}),
|
||||||
label: 'AddOn',
|
getSchemaTpl('className', {
|
||||||
visibleOn: 'this.addOn && this.addOn.type === "text"'
|
name: 'addOn.className',
|
||||||
})
|
label: 'AddOn',
|
||||||
]),
|
visibleOn: 'this.addOn && this.addOn.type === "text"'
|
||||||
getSchemaTpl('style:others', [
|
})
|
||||||
{
|
]),
|
||||||
name: 'embed',
|
getSchemaTpl('style:others', [
|
||||||
type: 'button-group-select',
|
{
|
||||||
size: 'md',
|
name: 'embed',
|
||||||
label: '模式',
|
type: 'button-group-select',
|
||||||
mode: 'row',
|
size: 'md',
|
||||||
value: false,
|
label: '模式',
|
||||||
options: [
|
mode: 'row',
|
||||||
{
|
value: false,
|
||||||
label: '浮层',
|
options: [
|
||||||
value: false
|
{
|
||||||
},
|
label: '浮层',
|
||||||
{
|
value: false
|
||||||
label: '内嵌',
|
},
|
||||||
value: true
|
{
|
||||||
}
|
label: '内嵌',
|
||||||
]
|
value: true
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
], {...context?.schema, configTitle: 'style'})
|
}
|
||||||
|
])
|
||||||
|
],
|
||||||
|
{...context?.schema, configTitle: 'style'}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '事件',
|
title: '事件',
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||||
|
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
const DateType: {
|
const DateType: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
@ -184,72 +180,74 @@ export class DateRangeControlPlugin extends BasePlugin {
|
|||||||
return getSchemaTpl('tabs', [
|
return getSchemaTpl('tabs', [
|
||||||
{
|
{
|
||||||
title: '属性',
|
title: '属性',
|
||||||
body: getSchemaTpl('collapseGroup', [
|
body: getSchemaTpl(
|
||||||
{
|
'collapseGroup',
|
||||||
title: '基本',
|
[
|
||||||
body: [
|
{
|
||||||
getSchemaTpl('formItemName', {
|
title: '基本',
|
||||||
required: true
|
body: [
|
||||||
}),
|
getSchemaTpl('formItemName', {
|
||||||
getSchemaTpl('label'),
|
required: true
|
||||||
getSchemaTpl('selectDateRangeType', {
|
}),
|
||||||
value: this.scaffold.type,
|
getSchemaTpl('label'),
|
||||||
onChange: (
|
getSchemaTpl('selectDateRangeType', {
|
||||||
value: string,
|
value: this.scaffold.type,
|
||||||
oldValue: any,
|
onChange: (
|
||||||
model: any,
|
value: string,
|
||||||
form: any
|
oldValue: any,
|
||||||
) => {
|
model: any,
|
||||||
const type: string = value.split('-')[1];
|
form: any
|
||||||
form.setValues({
|
) => {
|
||||||
inputFormat: DateType[type]?.format,
|
const type: string = value.split('-')[1];
|
||||||
placeholder: DateType[type]?.placeholder,
|
form.setValues({
|
||||||
format: type === 'time' ? 'HH:mm' : 'X',
|
inputFormat: DateType[type]?.format,
|
||||||
minDate: '',
|
placeholder: DateType[type]?.placeholder,
|
||||||
maxDate: '',
|
format: type === 'time' ? 'HH:mm' : 'X',
|
||||||
value: '',
|
minDate: '',
|
||||||
ranges: DateType[type]?.ranges
|
maxDate: '',
|
||||||
});
|
value: '',
|
||||||
}
|
ranges: DateType[type]?.ranges
|
||||||
}),
|
});
|
||||||
{
|
}
|
||||||
type: 'input-text',
|
}),
|
||||||
name: 'format',
|
{
|
||||||
label: tipedLabel(
|
type: 'input-text',
|
||||||
'值格式',
|
name: 'format',
|
||||||
'提交数据前将根据设定格式化数据,请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
label: tipedLabel(
|
||||||
),
|
'值格式',
|
||||||
pipeIn: defaultValue('X')
|
'提交数据前将根据设定格式化数据,请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
||||||
},
|
),
|
||||||
{
|
pipeIn: defaultValue('X')
|
||||||
type: 'input-text',
|
},
|
||||||
name: 'inputFormat',
|
{
|
||||||
label: tipedLabel(
|
type: 'input-text',
|
||||||
'显示格式',
|
name: 'inputFormat',
|
||||||
'请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
label: tipedLabel(
|
||||||
),
|
'显示格式',
|
||||||
pipeIn: defaultValue('YYYY-MM-DD'),
|
'请参考 <a href="https://momentjs.com/" target="_blank">moment</a> 中的格式用法。'
|
||||||
clearable: true
|
),
|
||||||
// onChange: (
|
pipeIn: defaultValue('YYYY-MM-DD'),
|
||||||
// value: string,
|
clearable: true
|
||||||
// oldValue: any,
|
// onChange: (
|
||||||
// model: any,
|
// value: string,
|
||||||
// form: any
|
// oldValue: any,
|
||||||
// ) => {
|
// model: any,
|
||||||
// model.setOptions(
|
// form: any
|
||||||
// DateType[form.data.type.split('-')[1]].formatOptions
|
// ) => {
|
||||||
// );
|
// model.setOptions(
|
||||||
// },
|
// DateType[form.data.type.split('-')[1]].formatOptions
|
||||||
// options:
|
// );
|
||||||
// DateType[this.scaffold.type.split('-')[1]].formatOptions
|
// },
|
||||||
},
|
// options:
|
||||||
getSchemaTpl('utc'),
|
// DateType[this.scaffold.type.split('-')[1]].formatOptions
|
||||||
getSchemaTpl('clearable', {
|
},
|
||||||
pipeIn: defaultValue(true)
|
getSchemaTpl('utc'),
|
||||||
}),
|
getSchemaTpl('clearable', {
|
||||||
|
pipeIn: defaultValue(true)
|
||||||
|
}),
|
||||||
|
|
||||||
getSchemaTpl('valueFormula', {
|
getSchemaTpl('valueFormula', {
|
||||||
/* 备注: 待 amis 日期组件优化
|
/* 备注: 待 amis 日期组件优化
|
||||||
rendererSchema: {
|
rendererSchema: {
|
||||||
...context?.schema,
|
...context?.schema,
|
||||||
size: 'full', // 备注:目前样式还有问题,需要在amis端进行优化
|
size: 'full', // 备注:目前样式还有问题,需要在amis端进行优化
|
||||||
@ -257,120 +255,127 @@ export class DateRangeControlPlugin extends BasePlugin {
|
|||||||
},
|
},
|
||||||
mode: 'vertical',
|
mode: 'vertical',
|
||||||
*/
|
*/
|
||||||
rendererSchema: {
|
rendererSchema: {
|
||||||
type: 'input-date'
|
type: 'input-date'
|
||||||
},
|
},
|
||||||
label: tipedLabel(
|
label: tipedLabel(
|
||||||
'默认值',
|
'默认值',
|
||||||
'支持 <code>now、+1day、-2weeks、+1hours、+2years</code>等这种相对值用法'
|
'支持 <code>now、+1day、-2weeks、+1hours、+2years</code>等这种相对值用法'
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('valueFormula', {
|
getSchemaTpl('valueFormula', {
|
||||||
name: 'minDate',
|
name: 'minDate',
|
||||||
rendererSchema: {
|
rendererSchema: {
|
||||||
...context?.schema,
|
...context?.schema,
|
||||||
value: context?.schema.minDate,
|
value: context?.schema.minDate,
|
||||||
type: 'input-date'
|
type: 'input-date'
|
||||||
},
|
},
|
||||||
needDeleteProps: ['minDate'], // 避免自我限制
|
needDeleteProps: ['minDate'], // 避免自我限制
|
||||||
label: tipedLabel('最小值', tipedLabelText)
|
label: tipedLabel('最小值', tipedLabelText)
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('valueFormula', {
|
getSchemaTpl('valueFormula', {
|
||||||
name: 'maxDate',
|
name: 'maxDate',
|
||||||
rendererSchema: {
|
rendererSchema: {
|
||||||
...context?.schema,
|
...context?.schema,
|
||||||
value: context?.schema.maxDate,
|
value: context?.schema.maxDate,
|
||||||
type: 'input-date'
|
type: 'input-date'
|
||||||
},
|
},
|
||||||
needDeleteProps: ['maxDate'], // 避免自我限制
|
needDeleteProps: ['maxDate'], // 避免自我限制
|
||||||
label: tipedLabel('最大值', tipedLabelText)
|
label: tipedLabel('最大值', tipedLabelText)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('formulaControl', {
|
getSchemaTpl('formulaControl', {
|
||||||
name: 'minDuration',
|
name: 'minDuration',
|
||||||
label: tipedLabel('最小跨度', '例如 2days'),
|
label: tipedLabel('最小跨度', '例如 2days'),
|
||||||
placeholder: '请输入最小跨度',
|
placeholder: '请输入最小跨度',
|
||||||
inputClassName: 'is-inline'
|
inputClassName: 'is-inline'
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('formulaControl', {
|
getSchemaTpl('formulaControl', {
|
||||||
name: 'maxDuration',
|
name: 'maxDuration',
|
||||||
label: tipedLabel('最大跨度', '例如 1year'),
|
label: tipedLabel('最大跨度', '例如 1year'),
|
||||||
placeholder: '请输入最大跨度',
|
placeholder: '请输入最大跨度',
|
||||||
inputClassName: 'is-inline'
|
inputClassName: 'is-inline'
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('dateShortCutControl', {
|
getSchemaTpl('dateShortCutControl', {
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
dropDownOption: {
|
dropDownOption: {
|
||||||
'yesterday': '昨天',
|
'yesterday': '昨天',
|
||||||
'thisweek': '这个周',
|
'thisweek': '这个周',
|
||||||
'prevweek': '上周',
|
'prevweek': '上周',
|
||||||
'7daysago': '最近7天',
|
'7daysago': '最近7天',
|
||||||
'thismonth': '这个月',
|
'thismonth': '这个月',
|
||||||
'prevmonth': '上个月',
|
'prevmonth': '上个月',
|
||||||
'thisquarter': '这个季度',
|
'thisquarter': '这个季度',
|
||||||
'prevquarter': '上个季度',
|
'prevquarter': '上个季度',
|
||||||
'thisyear': '今年'
|
'thisyear': '今年'
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
// getSchemaTpl('remark'),
|
// getSchemaTpl('remark'),
|
||||||
// getSchemaTpl('labelRemark'),
|
// getSchemaTpl('labelRemark'),
|
||||||
{
|
{
|
||||||
type: 'input-text',
|
type: 'input-text',
|
||||||
name: 'startPlaceholder',
|
name: 'startPlaceholder',
|
||||||
label: '前占位提示',
|
label: '前占位提示',
|
||||||
pipeIn: defaultValue('开始时间')
|
pipeIn: defaultValue('开始时间')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'input-text',
|
type: 'input-text',
|
||||||
name: 'endPlaceholder',
|
name: 'endPlaceholder',
|
||||||
label: '后占位提示',
|
label: '后占位提示',
|
||||||
pipeIn: defaultValue('结束时间')
|
pipeIn: defaultValue('选择结束时间')
|
||||||
}
|
},
|
||||||
]
|
getSchemaTpl('autoFillApi')
|
||||||
},
|
]
|
||||||
getSchemaTpl('status', {isFormItem: true}),
|
},
|
||||||
getSchemaTpl('validation', {
|
getSchemaTpl('status', {isFormItem: true}),
|
||||||
tag: ValidatorTag.Date
|
getSchemaTpl('validation', {
|
||||||
})
|
tag: ValidatorTag.Date
|
||||||
], {...context?.schema, configTitle: 'props'})
|
})
|
||||||
|
],
|
||||||
|
{...context?.schema, configTitle: 'props'}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '外观',
|
title: '外观',
|
||||||
body: getSchemaTpl('collapseGroup', [
|
body: getSchemaTpl(
|
||||||
getSchemaTpl('style:formItem', renderer),
|
'collapseGroup',
|
||||||
getSchemaTpl('style:classNames', [
|
[
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('style:formItem', renderer),
|
||||||
label: '描述',
|
getSchemaTpl('style:classNames', [
|
||||||
name: 'descriptionClassName',
|
getSchemaTpl('className', {
|
||||||
visibleOn: 'this.description'
|
label: '描述',
|
||||||
}),
|
name: 'descriptionClassName',
|
||||||
getSchemaTpl('className', {
|
visibleOn: 'this.description'
|
||||||
name: 'addOn.className',
|
}),
|
||||||
label: 'AddOn',
|
getSchemaTpl('className', {
|
||||||
visibleOn: 'this.addOn && this.addOn.type === "text"'
|
name: 'addOn.className',
|
||||||
})
|
label: 'AddOn',
|
||||||
]),
|
visibleOn: 'this.addOn && this.addOn.type === "text"'
|
||||||
getSchemaTpl('style:others', [
|
})
|
||||||
{
|
]),
|
||||||
name: 'embed',
|
getSchemaTpl('style:others', [
|
||||||
type: 'button-group-select',
|
{
|
||||||
size: 'md',
|
name: 'embed',
|
||||||
label: '模式',
|
type: 'button-group-select',
|
||||||
mode: 'row',
|
size: 'md',
|
||||||
value: false,
|
label: '模式',
|
||||||
options: [
|
mode: 'row',
|
||||||
{
|
value: false,
|
||||||
label: '浮层',
|
options: [
|
||||||
value: false
|
{
|
||||||
},
|
label: '浮层',
|
||||||
{
|
value: false
|
||||||
label: '内嵌',
|
},
|
||||||
value: true
|
{
|
||||||
}
|
label: '内嵌',
|
||||||
]
|
value: true
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
], {...context?.schema, configTitle: 'style'})
|
}
|
||||||
|
])
|
||||||
|
],
|
||||||
|
{...context?.schema, configTitle: 'style'}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '事件',
|
title: '事件',
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin, tipedLabel} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class FileControlPlugin extends BasePlugin {
|
export class FileControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -348,7 +344,8 @@ export class FileControlPlugin extends BasePlugin {
|
|||||||
}),
|
}),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
// getSchemaTpl('autoFill')
|
// getSchemaTpl('autoFill')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -2,10 +2,8 @@ import {getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||||
import {formItemControl} from '../../component/BaseControl';
|
import {formItemControl} from '../../component/BaseControl';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
export class ImageControlPlugin extends BasePlugin {
|
export class ImageControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
rendererName = 'input-image';
|
rendererName = 'input-image';
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
import flatten from 'lodash/flatten';
|
import flatten from 'lodash/flatten';
|
||||||
import {ContainerWrapper} from 'amis-editor-core';
|
import {ContainerWrapper} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
@ -13,8 +10,7 @@ import {
|
|||||||
SubRendererInfo,
|
SubRendererInfo,
|
||||||
BaseEventContext
|
BaseEventContext
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
|
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
|
|
||||||
@ -278,7 +274,8 @@ export class RangeControlPlugin extends BasePlugin {
|
|||||||
label: '可重置',
|
label: '可重置',
|
||||||
value: false,
|
value: false,
|
||||||
visibleOn: '!!data.showInput'
|
visibleOn: '!!data.showInput'
|
||||||
})
|
}),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -5,14 +5,10 @@ import {
|
|||||||
undefinedPipeOut
|
undefinedPipeOut
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext, tipedLabel} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class RateControlPlugin extends BasePlugin {
|
export class RateControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -234,7 +230,8 @@ export class RateControlPlugin extends BasePlugin {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
getSchemaTpl('status', {isFormItem: true, readonly: true}),
|
getSchemaTpl('status', {isFormItem: true, readonly: true}),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {Button} from 'amis';
|
import {Button} from 'amis';
|
||||||
|
import { SchemaCollection } from 'amis/lib/Schema';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {
|
import {
|
||||||
@ -94,7 +95,7 @@ export class SubFormControlPlugin extends BasePlugin {
|
|||||||
label: '允许最多个数',
|
label: '允许最多个数',
|
||||||
type: 'input-number'
|
type: 'input-number'
|
||||||
}
|
}
|
||||||
];
|
] as SchemaCollection;
|
||||||
};
|
};
|
||||||
|
|
||||||
filterProps(props: any) {
|
filterProps(props: any) {
|
||||||
|
@ -9,10 +9,7 @@ import {
|
|||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
|
|
||||||
import {formItemControl} from '../../component/BaseControl';
|
import {formItemControl} from '../../component/BaseControl';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class TagControlPlugin extends BasePlugin {
|
export class TagControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
@ -6,8 +6,7 @@ import {
|
|||||||
SubRendererInfo,
|
SubRendererInfo,
|
||||||
BaseEventContext
|
BaseEventContext
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl, setSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
|
|
||||||
@ -222,7 +221,7 @@ export class TextControlPlugin extends BasePlugin {
|
|||||||
{
|
{
|
||||||
name: 'addOn',
|
name: 'addOn',
|
||||||
label: tipedLabel('AddOn', '输入框左侧或右侧的附加挂件'),
|
label: tipedLabel('AddOn', '输入框左侧或右侧的附加挂件'),
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
formType: 'extend',
|
formType: 'extend',
|
||||||
title: 'AddOn',
|
title: 'AddOn',
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import { getArgsWrapper } from '../../renderer/event-control/helper';
|
import {getArgsWrapper} from '../../renderer/event-control/helper';
|
||||||
|
|
||||||
export class TreeControlPlugin extends BasePlugin {
|
export class TreeControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
@ -112,9 +112,15 @@ export class ItemPlugin extends BasePlugin {
|
|||||||
ignoreValidator ? null : getSchemaTpl('required'),
|
ignoreValidator ? null : getSchemaTpl('required'),
|
||||||
getSchemaTpl('description'),
|
getSchemaTpl('description'),
|
||||||
getSchemaTpl('placeholder'),
|
getSchemaTpl('placeholder'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark', {
|
||||||
renderer.renderLabel !== false ? getSchemaTpl('labelRemark') : null,
|
mode: 'row'
|
||||||
autoFillApi ? getSchemaTpl('autoFillApi') : null
|
}),
|
||||||
|
renderer.renderLabel !== false
|
||||||
|
? getSchemaTpl('labelRemark', {
|
||||||
|
mode: 'row'
|
||||||
|
})
|
||||||
|
: null,
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -111,6 +111,8 @@ export class ListControlPlugin extends BasePlugin {
|
|||||||
}),
|
}),
|
||||||
getSchemaTpl('label'),
|
getSchemaTpl('label'),
|
||||||
getSchemaTpl('multiple'),
|
getSchemaTpl('multiple'),
|
||||||
|
getSchemaTpl('extractValue'),
|
||||||
|
|
||||||
getSchemaTpl('valueFormula', {
|
getSchemaTpl('valueFormula', {
|
||||||
rendererSchema: context?.schema,
|
rendererSchema: context?.schema,
|
||||||
useSelectMode: true, // 改用 Select 设置模式
|
useSelectMode: true, // 改用 Select 设置模式
|
||||||
|
@ -5,15 +5,12 @@ import {
|
|||||||
BasicSubRenderInfo,
|
BasicSubRenderInfo,
|
||||||
RendererEventContext,
|
RendererEventContext,
|
||||||
SubRendererInfo,
|
SubRendererInfo,
|
||||||
BaseEventContext
|
BaseEventContext,
|
||||||
|
tipedLabel
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class MatrixControlPlugin extends BasePlugin {
|
export class MatrixControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -151,7 +148,8 @@ export class MatrixControlPlugin extends BasePlugin {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
pipeIn: defaultValue('column')
|
pipeIn: defaultValue('column')
|
||||||
}
|
},
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import {relativeValueRe} from 'amis';
|
import {relativeValueRe} from 'amis';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
import {availableLanguages} from 'amis/lib/renderers/Form/Editor';
|
import {availableLanguages} from 'amis/lib/renderers/Form/Editor';
|
||||||
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
@ -11,9 +8,9 @@ import {
|
|||||||
BasicSubRenderInfo,
|
BasicSubRenderInfo,
|
||||||
RendererEventContext,
|
RendererEventContext,
|
||||||
SubRendererInfo,
|
SubRendererInfo,
|
||||||
BaseEventContext
|
BaseEventContext,
|
||||||
|
tipedLabel
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
|
|
||||||
@ -285,7 +282,8 @@ export class NestedSelectControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('placeholder'),
|
getSchemaTpl('placeholder'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4,10 +4,7 @@ import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
|||||||
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class RadiosControlPlugin extends BasePlugin {
|
export class RadiosControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -122,7 +119,8 @@ export class RadiosControlPlugin extends BasePlugin {
|
|||||||
}),
|
}),
|
||||||
// getSchemaTpl('autoFill')
|
// getSchemaTpl('autoFill')
|
||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark')
|
getSchemaTpl('remark'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
import {getSchemaTpl} from 'amis-editor-core';
|
import {getSchemaTpl} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||||
import isArray from 'lodash/isArray';
|
|
||||||
|
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class SelectControlPlugin extends BasePlugin {
|
export class SelectControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -225,7 +220,8 @@ export class SelectControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('placeholder'),
|
getSchemaTpl('placeholder'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -263,7 +259,7 @@ export class SelectControlPlugin extends BasePlugin {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('editable', {
|
getSchemaTpl('editable', {
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
formType: 'extend',
|
formType: 'extend',
|
||||||
hiddenOnDefault: true,
|
hiddenOnDefault: true,
|
||||||
form: {
|
form: {
|
||||||
@ -271,7 +267,7 @@ export class SelectControlPlugin extends BasePlugin {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('removable', {
|
getSchemaTpl('removable', {
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
formType: 'extend',
|
formType: 'extend',
|
||||||
hiddenOnDefault: true,
|
hiddenOnDefault: true,
|
||||||
form: {
|
form: {
|
||||||
|
@ -4,10 +4,7 @@ import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||||
import {EditorNodeType} from 'amis-editor-core';
|
import {EditorNodeType} from 'amis-editor-core';
|
||||||
import {mockValue} from 'amis-editor-core';
|
import {mockValue, tipedLabel} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
|
||||||
import {getEventControlConfig} from '../../util';
|
|
||||||
|
|
||||||
export class StaticControlPlugin extends BasePlugin {
|
export class StaticControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -64,7 +61,7 @@ export class StaticControlPlugin extends BasePlugin {
|
|||||||
rendererSchema: {
|
rendererSchema: {
|
||||||
...context?.schema,
|
...context?.schema,
|
||||||
type: 'textarea', // 改用多行文本编辑
|
type: 'textarea', // 改用多行文本编辑
|
||||||
value: context?.schema.tpl, // 避免默认值丢失
|
value: context?.schema.tpl // 避免默认值丢失
|
||||||
},
|
},
|
||||||
mode: 'vertical', // 改成上下展示模式
|
mode: 'vertical', // 改成上下展示模式
|
||||||
name: 'tpl'
|
name: 'tpl'
|
||||||
@ -294,7 +291,8 @@ export class StaticControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('placeholder'),
|
getSchemaTpl('placeholder'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
/*{
|
/*{
|
||||||
children: (
|
children: (
|
||||||
<Button
|
<Button
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
import {getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
import {getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin, tipedLabel} from 'amis-editor-core';
|
||||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import type {
|
import type {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class SwitchControlPlugin extends BasePlugin {
|
export class SwitchControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -97,7 +93,7 @@ export class SwitchControlPlugin extends BasePlugin {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
bulk: true,
|
bulk: true,
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
label: '填充文本',
|
label: '填充文本',
|
||||||
@ -120,7 +116,7 @@ export class SwitchControlPlugin extends BasePlugin {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
bulk: true,
|
bulk: true,
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
label: tipedLabel(
|
label: tipedLabel(
|
||||||
@ -199,7 +195,8 @@ export class SwitchControlPlugin extends BasePlugin {
|
|||||||
}),
|
}),
|
||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
getSchemaTpl('status', {isFormItem: true}),
|
getSchemaTpl('status', {isFormItem: true}),
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin} from 'amis-editor-core';
|
import {BasePlugin, tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
import type {BaseEventContext} from 'amis-editor-core';
|
import type {BaseEventContext} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../../validator';
|
import {ValidatorTag} from '../../validator';
|
||||||
import {getEventControlConfig} from '../../util';
|
import {getEventControlConfig} from '../../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class TextareaControlPlugin extends BasePlugin {
|
export class TextareaControlPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -142,7 +138,8 @@ export class TextareaControlPlugin extends BasePlugin {
|
|||||||
getSchemaTpl('labelRemark'),
|
getSchemaTpl('labelRemark'),
|
||||||
getSchemaTpl('remark'),
|
getSchemaTpl('remark'),
|
||||||
getSchemaTpl('placeholder'),
|
getSchemaTpl('placeholder'),
|
||||||
getSchemaTpl('description')
|
getSchemaTpl('description'),
|
||||||
|
getSchemaTpl('autoFillApi')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
getSchemaTpl('status', {
|
getSchemaTpl('status', {
|
||||||
|
@ -3,10 +3,10 @@ import {
|
|||||||
BasePlugin,
|
BasePlugin,
|
||||||
RegionConfig,
|
RegionConfig,
|
||||||
RendererInfo,
|
RendererInfo,
|
||||||
BaseEventContext
|
BaseEventContext,
|
||||||
|
tipedLabel
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl, valuePipeOut} from 'amis-editor-core';
|
||||||
import {formItemControl, tipedLabel} from '../component/BaseControl';
|
|
||||||
|
|
||||||
export class IFramePlugin extends BasePlugin {
|
export class IFramePlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, RegionConfig, RendererInfo} from 'amis-editor-core';
|
import {BasePlugin, RegionConfig, RendererInfo} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
import {ValidatorTag} from '../validator';
|
import {ValidatorTag} from '../validator';
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
import {
|
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||||
RendererPluginAction,
|
|
||||||
RendererPluginEvent
|
|
||||||
} from 'amis-editor-core';
|
|
||||||
|
|
||||||
export class LinkPlugin extends BasePlugin {
|
export class LinkPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
@ -13,6 +13,8 @@ import {
|
|||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {diff, JSONPipeOut, repeatArray} from 'amis-editor-core';
|
import {diff, JSONPipeOut, repeatArray} from 'amis-editor-core';
|
||||||
|
import {getEventControlConfig} from '../util';
|
||||||
|
import {ListItemSchema} from 'amis/lib/renderers/List';
|
||||||
|
|
||||||
export class ListPlugin extends BasePlugin {
|
export class ListPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -55,118 +57,148 @@ export class ListPlugin extends BasePlugin {
|
|||||||
};
|
};
|
||||||
|
|
||||||
panelTitle = '列表';
|
panelTitle = '列表';
|
||||||
|
panelJustify = true;
|
||||||
panelBodyCreator = (context: BaseEventContext) => {
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
const isCRUDBody = context.schema.type === 'crud';
|
const isCRUDBody = ['crud', 'crud2'].includes(context.schema.type);
|
||||||
|
|
||||||
return getSchemaTpl('tabs', [
|
return getSchemaTpl('tabs', [
|
||||||
{
|
{
|
||||||
title: '常规',
|
title: '属性',
|
||||||
body: [
|
body: getSchemaTpl('collapseGroup', [
|
||||||
{
|
{
|
||||||
children: (
|
title: '基本',
|
||||||
<Button
|
body: [
|
||||||
level="danger"
|
{
|
||||||
size="sm"
|
name: 'title',
|
||||||
block
|
|
||||||
onClick={this.editDetail.bind(this, context.id)}
|
|
||||||
>
|
|
||||||
配置成员详情
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'divider'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'title',
|
|
||||||
type: 'input-text',
|
|
||||||
label: '标题'
|
|
||||||
},
|
|
||||||
isCRUDBody
|
|
||||||
? null
|
|
||||||
: {
|
|
||||||
name: 'source',
|
|
||||||
type: 'input-text',
|
type: 'input-text',
|
||||||
label: '数据源',
|
label: '标题'
|
||||||
pipeIn: defaultValue('${items}'),
|
|
||||||
description: '绑定当前环境变量'
|
|
||||||
},
|
},
|
||||||
{
|
isCRUDBody
|
||||||
name: 'placeholder',
|
? null
|
||||||
pipeIn: defaultValue('没有数据'),
|
: {
|
||||||
type: 'input-text',
|
name: 'source',
|
||||||
label: '无数据提示'
|
type: 'input-text',
|
||||||
}
|
label: '数据源',
|
||||||
]
|
pipeIn: defaultValue('${items}'),
|
||||||
|
description: '绑定当前环境变量'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'placeholder',
|
||||||
|
pipeIn: defaultValue('没有数据'),
|
||||||
|
type: 'input-text',
|
||||||
|
label: '无数据提示'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
getSchemaTpl('status', {
|
||||||
|
isFormItem: false
|
||||||
|
})
|
||||||
|
])
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '外观',
|
title: '外观',
|
||||||
body: [
|
body: getSchemaTpl('collapseGroup', [
|
||||||
getSchemaTpl('switch', {
|
{
|
||||||
name: 'showHeader',
|
title: '基本',
|
||||||
label: '是否显示头部',
|
body: [
|
||||||
pipeIn: defaultValue(true)
|
getSchemaTpl('switch', {
|
||||||
}),
|
name: 'showHeader',
|
||||||
|
label: '显示头部',
|
||||||
|
pipeIn: defaultValue(true)
|
||||||
|
}),
|
||||||
|
|
||||||
getSchemaTpl('switch', {
|
getSchemaTpl('switch', {
|
||||||
name: 'showFooter',
|
name: 'showFooter',
|
||||||
label: '是否显示底部',
|
label: '显示底部',
|
||||||
pipeIn: defaultValue(true)
|
pipeIn: defaultValue(true)
|
||||||
}),
|
})
|
||||||
|
]
|
||||||
getSchemaTpl('className', {
|
},
|
||||||
label: 'CSS 类名'
|
getSchemaTpl('style:classNames', {
|
||||||
}),
|
isFormItem: false,
|
||||||
getSchemaTpl('className', {
|
schema: [
|
||||||
name: 'listClassName',
|
getSchemaTpl('className', {
|
||||||
label: 'List div CSS 类名'
|
name: 'listClassName',
|
||||||
}),
|
label: '列表项'
|
||||||
getSchemaTpl('className', {
|
}),
|
||||||
name: 'headerClassName',
|
getSchemaTpl('className', {
|
||||||
label: '头部 CSS 类名'
|
name: 'headerClassName',
|
||||||
}),
|
label: '头部'
|
||||||
getSchemaTpl('className', {
|
}),
|
||||||
name: 'footerClassName',
|
getSchemaTpl('className', {
|
||||||
label: '底部 CSS 类名'
|
name: 'footerClassName',
|
||||||
|
label: '底部'
|
||||||
|
})
|
||||||
|
]
|
||||||
})
|
})
|
||||||
]
|
])
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '显隐',
|
title: '事件',
|
||||||
body: [getSchemaTpl('ref'), getSchemaTpl('visible')]
|
className: 'p-none',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('eventControl', {
|
||||||
|
name: 'onEvent',
|
||||||
|
...getEventControlConfig(this.manager, context)
|
||||||
|
})
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
filterProps(props: any) {
|
overrides = {
|
||||||
if (props.isSlot) {
|
renderListItem(
|
||||||
props.value = [props.data];
|
this: any,
|
||||||
return props;
|
index: number,
|
||||||
|
itemTemplace: ListItemSchema | undefined,
|
||||||
|
...rest: any[]
|
||||||
|
) {
|
||||||
|
return this.super(
|
||||||
|
index,
|
||||||
|
// 使第一个卡片元素可以选择并编辑schema
|
||||||
|
index > 0 ? JSONPipeOut(itemTemplace) : itemTemplace,
|
||||||
|
...rest
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
filterProps(props: any) {
|
||||||
const data = {
|
const data = {
|
||||||
...props.defaultData,
|
...props.defaultData,
|
||||||
...props.data
|
...props.data
|
||||||
};
|
};
|
||||||
let arr = Array.isArray(props.value)
|
let value = Array.isArray(props.value)
|
||||||
? props.value
|
? props.value
|
||||||
: typeof props.source === 'string'
|
: typeof props.source === 'string'
|
||||||
? resolveVariable(props.source, data)
|
? resolveVariable(props.source, data)
|
||||||
: resolveVariable('items', data);
|
: resolveVariable('items', data);
|
||||||
|
|
||||||
if (!Array.isArray(arr) || !arr.length) {
|
value = !Array.isArray(value) ? [] : value;
|
||||||
const mockedData: any = this.buildMockData();
|
|
||||||
props.value = repeatArray(mockedData, 1).map((item, index) => ({
|
if (value.length < 5) {
|
||||||
...item,
|
const mockedData = value.length
|
||||||
id: index + 1
|
? value[0]
|
||||||
}));
|
: {
|
||||||
|
id: 666,
|
||||||
|
title: '假数据',
|
||||||
|
description: '假数据',
|
||||||
|
a: '假数据',
|
||||||
|
b: '假数据'
|
||||||
|
};
|
||||||
|
|
||||||
|
value = value.concat(
|
||||||
|
repeatArray(mockedData, 3).map((item, index) => ({
|
||||||
|
...item,
|
||||||
|
id: index + 1
|
||||||
|
}))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {$schema, ...rest} = props;
|
value = value.slice(0, 4);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...JSONPipeOut(rest),
|
...props,
|
||||||
$schema
|
value
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +283,7 @@ export class ListPlugin extends BasePlugin {
|
|||||||
const {renderer, schema} = context;
|
const {renderer, schema} = context;
|
||||||
if (
|
if (
|
||||||
!schema.$$id &&
|
!schema.$$id &&
|
||||||
schema.$$editor?.renderer.name === 'crud' &&
|
['crud', 'crud2'].includes(schema.$$editor?.renderer.name) &&
|
||||||
renderer.name === 'list'
|
renderer.name === 'list'
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {VRenderer} from 'amis-editor-core';
|
import {VRenderer} from 'amis-editor-core';
|
||||||
|
import { getEventControlConfig } from '../util';
|
||||||
|
|
||||||
export class ListItemPlugin extends BasePlugin {
|
export class ListItemPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -37,83 +38,78 @@ export class ListItemPlugin extends BasePlugin {
|
|||||||
];
|
];
|
||||||
|
|
||||||
panelTitle = '列表项';
|
panelTitle = '列表项';
|
||||||
panelBody = getSchemaTpl('tabs', [
|
panelJustify = true;
|
||||||
{
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
title: '基本',
|
const isCRUDBody = ['crud', 'crud2'].includes(context.schema.type);
|
||||||
body: [
|
|
||||||
// {
|
return getSchemaTpl('tabs', [
|
||||||
// children: (
|
{
|
||||||
// <Button
|
title: '属性',
|
||||||
// size="sm"
|
body: getSchemaTpl('collapseGroup', [
|
||||||
// className="m-b-sm"
|
{
|
||||||
// level="info"
|
title: '基本',
|
||||||
// block
|
body: [
|
||||||
// onClick={() => {
|
{
|
||||||
// this.pickChild('actions', 'actions', undefined, ['button']);
|
name: 'title',
|
||||||
// }}
|
type: 'input-text',
|
||||||
// >
|
label: '标题',
|
||||||
// 新增按钮
|
descrition: '支持模板语法如: ${xxx}'
|
||||||
// </Button>
|
},
|
||||||
// )
|
{
|
||||||
// },
|
name: 'subTitle',
|
||||||
// {
|
type: 'input-text',
|
||||||
// children: (
|
label: '副标题',
|
||||||
// <div>
|
descrition: '支持模板语法如: ${xxx}'
|
||||||
// <Button
|
},
|
||||||
// level="primary"
|
{
|
||||||
// size="sm"
|
name: 'avatar',
|
||||||
// block
|
type: 'input-text',
|
||||||
// onClick={this.handleAdd}
|
label: '图片地址',
|
||||||
// >
|
descrition: '支持模板语法如: ${xxx}'
|
||||||
// 新增内容
|
},
|
||||||
// </Button>
|
{
|
||||||
// </div>
|
name: 'desc',
|
||||||
// )
|
type: 'textarea',
|
||||||
// },
|
label: '描述',
|
||||||
// {
|
descrition: '支持模板语法如: ${xxx}'
|
||||||
// type: 'divider'
|
}
|
||||||
// },
|
]
|
||||||
{
|
},
|
||||||
name: 'title',
|
getSchemaTpl('status', {
|
||||||
type: 'input-text',
|
isFormItem: false
|
||||||
label: '标题',
|
})
|
||||||
descrition: '支持模板语法如: ${xxx}'
|
])
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'subTitle',
|
title: '外观',
|
||||||
type: 'input-text',
|
body: getSchemaTpl('collapseGroup', [
|
||||||
label: '副标题',
|
getSchemaTpl('style:classNames', {
|
||||||
descrition: '支持模板语法如: ${xxx}'
|
isFormItem: false,
|
||||||
},
|
schema: [
|
||||||
{
|
getSchemaTpl('className', {
|
||||||
name: 'avatar',
|
name: 'avatarClassName',
|
||||||
type: 'input-text',
|
label: '图片'
|
||||||
label: '图片地址',
|
}),
|
||||||
descrition: '支持模板语法如: ${xxx}'
|
getSchemaTpl('className', {
|
||||||
},
|
name: 'titleClassName',
|
||||||
{
|
label: '标题'
|
||||||
name: 'desc',
|
})
|
||||||
type: 'textarea',
|
]
|
||||||
label: '描述',
|
})
|
||||||
descrition: '支持模板语法如: ${xxx}'
|
])
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
},
|
title: '事件',
|
||||||
{
|
className: 'p-none',
|
||||||
title: '外观',
|
body: [
|
||||||
body: [
|
getSchemaTpl('eventControl', {
|
||||||
getSchemaTpl('className', {
|
name: 'onEvent',
|
||||||
name: 'avatarClassName',
|
...getEventControlConfig(this.manager, context)
|
||||||
label: '图片 CSS 类名',
|
})
|
||||||
pipeIn: defaultValue('thumb-sm avatar m-r')
|
]
|
||||||
}),
|
}
|
||||||
getSchemaTpl('className', {
|
]);
|
||||||
name: 'titleClassName',
|
};
|
||||||
label: '标题 CSS 类名'
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
getRendererInfo({
|
getRendererInfo({
|
||||||
renderer,
|
renderer,
|
||||||
|
@ -6,10 +6,11 @@ import {
|
|||||||
BasePlugin,
|
BasePlugin,
|
||||||
BasicPanelItem,
|
BasicPanelItem,
|
||||||
BasicToolbarItem,
|
BasicToolbarItem,
|
||||||
BuildPanelEventContext,
|
BuildPanelEventContext
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {diff} from 'amis-editor-core';
|
import {diff} from 'amis-editor-core';
|
||||||
|
import {SchemaCollection} from 'amis/lib/Schema';
|
||||||
|
|
||||||
export class ActionPlugin extends BasePlugin {
|
export class ActionPlugin extends BasePlugin {
|
||||||
panelTitle = '按钮';
|
panelTitle = '按钮';
|
||||||
@ -350,7 +351,7 @@ export class ActionPlugin extends BasePlugin {
|
|||||||
className: 'p-3',
|
className: 'p-3',
|
||||||
body: schema
|
body: schema
|
||||||
}
|
}
|
||||||
];
|
] as SchemaCollection;
|
||||||
};
|
};
|
||||||
|
|
||||||
buildEditorPanel(
|
buildEditorPanel(
|
||||||
|
@ -40,11 +40,9 @@ export class TableCellPlugin extends BasePlugin {
|
|||||||
type: 'input-text'
|
type: 'input-text'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
getSchemaTpl('formItemName', {
|
||||||
name: 'name',
|
|
||||||
type: 'input-text',
|
|
||||||
label: '绑定字段名'
|
label: '绑定字段名'
|
||||||
},
|
}),
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'remark',
|
name: 'remark',
|
||||||
|
@ -177,15 +177,15 @@ export class PagePlugin extends BasePlugin {
|
|||||||
label: '数据初始化接口',
|
label: '数据初始化接口',
|
||||||
name: 'initApi',
|
name: 'initApi',
|
||||||
sampleBuilder: (schema: any) => `{
|
sampleBuilder: (schema: any) => `{
|
||||||
"status": 0,
|
"status": 0,
|
||||||
"msg": "",
|
"msg": "",
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
// 示例数据
|
// 示例数据
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"a": "sample"
|
"a": "sample"
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('initFetch'),
|
getSchemaTpl('initFetch'),
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
|
||||||
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
|
||||||
import {ValidatorTag} from '../validator';
|
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
import {RendererPluginEvent} from 'amis-editor-core';
|
import {
|
||||||
|
getSchemaTpl,
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
defaultValue,
|
||||||
|
tipedLabel,
|
||||||
|
BasePlugin,
|
||||||
|
RendererPluginEvent,
|
||||||
|
RegionConfig,
|
||||||
|
BaseEventContext,
|
||||||
|
registerEditorPlugin
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
|
||||||
export class PaginationPlugin extends BasePlugin {
|
export class PaginationPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -14,17 +17,16 @@ export class PaginationPlugin extends BasePlugin {
|
|||||||
|
|
||||||
// 组件名称
|
// 组件名称
|
||||||
name = '分页组件';
|
name = '分页组件';
|
||||||
isBaseComponent = true;
|
isBaseComponent = false;
|
||||||
disabledRendererPlugin = true;
|
|
||||||
description = '分页组件,可以对列表进行分页展示,提高页面性能';
|
description = '分页组件,可以对列表进行分页展示,提高页面性能';
|
||||||
tags = ['容器'];
|
tags = ['容器'];
|
||||||
icon = 'fa fa-window-minimize';
|
icon = 'fa fa-window-minimize';
|
||||||
// pluginIcon = 'pagination-plugin'; // 暂无新icon
|
lastLayoutSetting = ['pager'];
|
||||||
baseLayoutLIst = [
|
layoutOptions = [
|
||||||
{text: '总数', value: 'total', checked: false},
|
{text: '总数', value: 'total', checked: false},
|
||||||
{text: '每页条数', value: 'perPage', checked: false},
|
{text: '每页条数', value: 'perPage', checked: false},
|
||||||
{text: '分页', value: 'pager', checked: true},
|
{text: '分页', value: 'pager', checked: true},
|
||||||
{text: '跳转', value: 'go', checked: false}
|
{text: '跳转页', value: 'go', checked: false}
|
||||||
];
|
];
|
||||||
scaffold = {
|
scaffold = {
|
||||||
type: 'pagination',
|
type: 'pagination',
|
||||||
@ -66,27 +68,52 @@ export class PaginationPlugin extends BasePlugin {
|
|||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
name: 'mode',
|
name: 'mode',
|
||||||
label: '分页类型',
|
label: '模式',
|
||||||
type: 'button-group-select',
|
type: 'button-group-select',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
pipeIn: defaultValue('normal'),
|
pipeIn: defaultValue('normal'),
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
label: '普通',
|
label: '默认',
|
||||||
value: 'normal'
|
value: 'normal'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '简易',
|
label: '简约',
|
||||||
value: 'simple'
|
value: 'simple'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// name: 'hasNext',
|
||||||
|
// label: '是否有下一页',
|
||||||
|
// mode: 'row',
|
||||||
|
// inputClassName: 'inline-flex justify-between flex-row-reverse',
|
||||||
|
// type: 'switch',
|
||||||
|
// visibleOn: 'data.mode === "simple"'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'activePage',
|
||||||
|
// label: tipedLabel('当前页', '支持使用 \\${xxx} 来获取变量'),
|
||||||
|
// type: 'input-text'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'lastPage',
|
||||||
|
// label: tipedLabel('最后页码', '支持使用 \\${xxx} 来获取变量'),
|
||||||
|
// type: 'input-text',
|
||||||
|
// visibleOn: 'data.mode === "normal"'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'total',
|
||||||
|
// label: tipedLabel('总条数', '支持使用 \\${xxx} 来获取变量'),
|
||||||
|
// type: 'input-text',
|
||||||
|
// visibleOn: 'data.mode === "normal"'
|
||||||
|
// },
|
||||||
getSchemaTpl('combo-container', {
|
getSchemaTpl('combo-container', {
|
||||||
name: 'layout',
|
name: 'layout',
|
||||||
type: 'combo',
|
type: 'combo',
|
||||||
label: tipedLabel(
|
label: tipedLabel(
|
||||||
'分页布局展示',
|
'启用功能',
|
||||||
'选中表示渲染该项,可以拖拽排序调整显示的顺序'
|
'选中表示启用该项,可以拖拽排序调整功能的顺序'
|
||||||
),
|
),
|
||||||
visibleOn: 'data.mode === "normal"',
|
visibleOn: 'data.mode === "normal"',
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
@ -112,52 +139,37 @@ export class PaginationPlugin extends BasePlugin {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
pipeIn: (value: any) => {
|
pipeIn: (value: any) => {
|
||||||
let layoutList: string[] = [];
|
if (!value) {
|
||||||
if (Array.isArray(value)) {
|
value = this.lastLayoutSetting;
|
||||||
layoutList = value;
|
|
||||||
} else if (typeof value === 'string') {
|
} else if (typeof value === 'string') {
|
||||||
layoutList = (value as string).split(',');
|
value = (value as string).split(',');
|
||||||
}
|
}
|
||||||
const layout = this.baseLayoutLIst.map(v => ({
|
return this.layoutOptions.map(v => ({
|
||||||
...v,
|
...v,
|
||||||
checked: layoutList.includes(v.value)
|
checked: value.includes(v.value)
|
||||||
}));
|
}));
|
||||||
return layout;
|
|
||||||
},
|
},
|
||||||
pipeOut: (value: any[]) => {
|
pipeOut: (value: any[]) => {
|
||||||
this.baseLayoutLIst = [...value];
|
this.lastLayoutSetting = value
|
||||||
return value.filter(v => v.checked).map(v => v.value);
|
.filter(v => v.checked)
|
||||||
|
.map(v => v.value);
|
||||||
|
return this.lastLayoutSetting.concat();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{
|
// {
|
||||||
type: 'ae-formulaControl',
|
// name: 'showPerPage',
|
||||||
label: '是否有下一页',
|
// label: '显示每页条数',
|
||||||
name: 'hasNext',
|
// mode: 'row',
|
||||||
visibleOn: 'data.mode === "simple"'
|
// inputClassName: 'inline-flex justify-between flex-row-reverse',
|
||||||
},
|
// type: 'switch',
|
||||||
{
|
// visibleOn: 'data.mode === "normal"'
|
||||||
type: 'ae-formulaControl',
|
// },
|
||||||
label: '当前页',
|
|
||||||
name: 'activePage'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'ae-formulaControl',
|
|
||||||
label: '最后页码',
|
|
||||||
name: 'lastPage',
|
|
||||||
visibleOn: 'data.mode === "normal"'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'ae-formulaControl',
|
|
||||||
label: '总条数',
|
|
||||||
name: 'total',
|
|
||||||
visibleOn: 'data.mode === "normal"'
|
|
||||||
},
|
|
||||||
getSchemaTpl('combo-container', {
|
getSchemaTpl('combo-container', {
|
||||||
name: 'perPageAvailable',
|
name: 'perPageAvailable',
|
||||||
type: 'combo',
|
type: 'combo',
|
||||||
label: '每页条数选项',
|
label: '每页条数选项',
|
||||||
visibleOn:
|
visibleOn:
|
||||||
'data.mode === "normal" && data.layout?.includes("perPage")',
|
'data.mode === "normal" && data.layout && data.layout.includes("perPage")',
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
multiple: true,
|
multiple: true,
|
||||||
multiLine: false,
|
multiLine: false,
|
||||||
@ -167,6 +179,7 @@ export class PaginationPlugin extends BasePlugin {
|
|||||||
editable: true,
|
editable: true,
|
||||||
minLength: 1,
|
minLength: 1,
|
||||||
tabsStyle: 'inline',
|
tabsStyle: 'inline',
|
||||||
|
addButtonClassName: 'm-b-sm',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
type: 'input-number',
|
type: 'input-number',
|
||||||
@ -175,31 +188,35 @@ export class PaginationPlugin extends BasePlugin {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
pipeIn: (value: any[]) => {
|
pipeIn: (value: any[]) => {
|
||||||
return value.map(v => ({value: v}));
|
return value?.map(v => ({value: v})) || [10];
|
||||||
},
|
},
|
||||||
pipeOut: (value: any[]) => {
|
pipeOut: (value: any[]) => {
|
||||||
return value.map(v => v.value);
|
return value.map(v => v.value);
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
{
|
// {
|
||||||
name: 'perPage',
|
// name: 'perPage',
|
||||||
type: 'input-text',
|
// type: 'input-text',
|
||||||
label: '默认每页条数',
|
// label: '默认每页条数',
|
||||||
visibleOn:
|
// visibleOn: 'data.mode === "normal"'
|
||||||
'data.mode === "normal" && data.layout?.includes("perPage")'
|
// },
|
||||||
},
|
// {
|
||||||
{
|
// name: 'maxButton',
|
||||||
name: 'maxButton',
|
// label: tipedLabel('分页按钮数量', '超过此数量,将会隐藏多余按钮'),
|
||||||
label: tipedLabel(
|
// type: 'input-number',
|
||||||
'最多按钮数',
|
// min: 5,
|
||||||
'最多显示多少个分页按钮,最小为5,最大值为20'
|
// max: 20,
|
||||||
),
|
// pipeIn: defaultValue(5),
|
||||||
type: 'input-number',
|
// visibleOn: 'data.mode === "normal"'
|
||||||
min: 5,
|
// }
|
||||||
max: 20,
|
// {
|
||||||
pipeOut: (value: any) => value || 5,
|
// name: 'showPageInput',
|
||||||
visibleOn: 'data.mode === "normal"'
|
// label: '显示页面跳转',
|
||||||
}
|
// mode: 'row',
|
||||||
|
// inputClassName: 'inline-flex justify-between flex-row-reverse',
|
||||||
|
// type: 'switch',
|
||||||
|
// visibleOn: 'data.mode === "normal"'
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,8 @@ export class PanelPlugin extends BasePlugin {
|
|||||||
panelJustify = true;
|
panelJustify = true;
|
||||||
|
|
||||||
panelBodyCreator = (context: BaseEventContext) => {
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
const isForm = /(?:^|\/)form$/.test(context.path) || context?.schema?.type === 'form';
|
const isForm =
|
||||||
|
/(?:^|\/)form$/.test(context.path) || context?.schema?.type === 'form';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
getSchemaTpl('tabs', [
|
getSchemaTpl('tabs', [
|
||||||
@ -102,7 +103,7 @@ export class PanelPlugin extends BasePlugin {
|
|||||||
name: 'title',
|
name: 'title',
|
||||||
type: 'input-text'
|
type: 'input-text'
|
||||||
},
|
},
|
||||||
|
|
||||||
isForm
|
isForm
|
||||||
? null
|
? null
|
||||||
: {
|
: {
|
||||||
@ -124,7 +125,7 @@ export class PanelPlugin extends BasePlugin {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
getSchemaTpl('status')
|
getSchemaTpl('status')
|
||||||
]),
|
])
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -140,7 +141,7 @@ export class PanelPlugin extends BasePlugin {
|
|||||||
label: '固定底部',
|
label: '固定底部',
|
||||||
value: false
|
value: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('horizontal', {
|
getSchemaTpl('horizontal', {
|
||||||
visibleOn:
|
visibleOn:
|
||||||
'(data.mode || data.$$formMode) == "horizontal" && data.$$mode == "form"'
|
'(data.mode || data.$$formMode) == "horizontal" && data.$$mode == "form"'
|
||||||
@ -152,7 +153,9 @@ export class PanelPlugin extends BasePlugin {
|
|||||||
title: '内容区域展示',
|
title: '内容区域展示',
|
||||||
body: [
|
body: [
|
||||||
getSchemaTpl('subFormItemMode', {label: '表单展示模式'}),
|
getSchemaTpl('subFormItemMode', {label: '表单展示模式'}),
|
||||||
getSchemaTpl('subFormHorizontalMode', {label: '表单水平占比'}),
|
getSchemaTpl('subFormHorizontalMode', {
|
||||||
|
label: '表单水平占比'
|
||||||
|
}),
|
||||||
getSchemaTpl('subFormHorizontal')
|
getSchemaTpl('subFormHorizontal')
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -211,28 +214,28 @@ export class PanelPlugin extends BasePlugin {
|
|||||||
name: isForm ? 'panelClassName' : 'className',
|
name: isForm ? 'panelClassName' : 'className',
|
||||||
pipeIn: defaultValue('Panel--default')
|
pipeIn: defaultValue('Panel--default')
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('className', {
|
||||||
name: 'headerClassName',
|
name: 'headerClassName',
|
||||||
label: '头部区域'
|
label: '头部区域'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('className', {
|
||||||
name: 'bodyClassName',
|
name: 'bodyClassName',
|
||||||
label: '内容区域'
|
label: '内容区域'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('className', {
|
||||||
name: 'footerClassName',
|
name: 'footerClassName',
|
||||||
label: '底部区域'
|
label: '底部区域'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('className', {
|
getSchemaTpl('className', {
|
||||||
name: 'actionsClassName',
|
name: 'actionsClassName',
|
||||||
label: '按钮外层'
|
label: '按钮外层'
|
||||||
})
|
})
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -251,9 +254,10 @@ export class PanelPlugin extends BasePlugin {
|
|||||||
if (
|
if (
|
||||||
context.info.renderer.name === 'form' &&
|
context.info.renderer.name === 'form' &&
|
||||||
schema.wrapWithPanel !== false &&
|
schema.wrapWithPanel !== false &&
|
||||||
!context.selections.length
|
!context.selections.length &&
|
||||||
|
false
|
||||||
) {
|
) {
|
||||||
|
/** Panel相关的配置融合到From中了 */
|
||||||
panels.push({
|
panels.push({
|
||||||
key: 'panel',
|
key: 'panel',
|
||||||
icon: 'fa fa-list-alt',
|
icon: 'fa fa-list-alt',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
import {ValidatorTag} from '../validator';
|
import {ValidatorTag} from '../validator';
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
|
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
import {Button} from 'amis';
|
import {Button} from 'amis';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
|
||||||
import {BaseEventContext, BasePlugin, RegionConfig} from 'amis-editor-core';
|
|
||||||
import {getSchemaTpl} from 'amis-editor-core';
|
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
|
|
||||||
import type {
|
import {
|
||||||
|
getSchemaTpl,
|
||||||
|
EditorManager,
|
||||||
RendererPluginAction,
|
RendererPluginAction,
|
||||||
RendererPluginEvent
|
RendererPluginEvent,
|
||||||
|
registerEditorPlugin,
|
||||||
|
BaseEventContext,
|
||||||
|
BasePlugin,
|
||||||
|
RegionConfig,
|
||||||
|
DSBuilderManager
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
|
import {flattenDeep} from 'lodash';
|
||||||
|
|
||||||
export class ServicePlugin extends BasePlugin {
|
export class ServicePlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
@ -21,28 +26,30 @@ export class ServicePlugin extends BasePlugin {
|
|||||||
description =
|
description =
|
||||||
'功能性容器,可以用来加载数据或者加载渲染器配置。加载到的数据在容器可以使用。';
|
'功能性容器,可以用来加载数据或者加载渲染器配置。加载到的数据在容器可以使用。';
|
||||||
docLink = '/amis/zh-CN/components/service';
|
docLink = '/amis/zh-CN/components/service';
|
||||||
tags = ['功能'];
|
tags = ['功能', '数据容器'];
|
||||||
icon = 'fa fa-server';
|
icon = 'fa fa-server';
|
||||||
pluginIcon = 'service-plugin';
|
pluginIcon = 'service-plugin';
|
||||||
scaffold = {
|
scaffold = {
|
||||||
|
type: 'service',
|
||||||
|
body: []
|
||||||
|
};
|
||||||
|
previewSchema = {
|
||||||
type: 'service',
|
type: 'service',
|
||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: '内容',
|
tpl: '内容区域',
|
||||||
inline: false
|
inline: false,
|
||||||
|
className: 'bg-light wrapper'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
previewSchema = {
|
|
||||||
type: 'tpl',
|
|
||||||
tpl: '功能性组件,用于数据拉取。'
|
|
||||||
};
|
|
||||||
|
|
||||||
regions: Array<RegionConfig> = [
|
regions: Array<RegionConfig> = [
|
||||||
{
|
{
|
||||||
key: 'body',
|
key: 'body',
|
||||||
label: '内容区'
|
label: '内容区域',
|
||||||
|
placeholder: '内容区域'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -79,7 +86,30 @@ export class ServicePlugin extends BasePlugin {
|
|||||||
|
|
||||||
panelTitle = '服务';
|
panelTitle = '服务';
|
||||||
|
|
||||||
|
dsBuilderMgr: DSBuilderManager;
|
||||||
|
|
||||||
|
constructor(manager: EditorManager) {
|
||||||
|
super(manager);
|
||||||
|
this.dsBuilderMgr = new DSBuilderManager('service', 'api');
|
||||||
|
}
|
||||||
|
|
||||||
panelBodyCreator = (context: BaseEventContext) => {
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
|
const dsTypeSelect = () =>
|
||||||
|
this.dsBuilderMgr.getDSSwitch({
|
||||||
|
onChange: (value: any, oldValue: any, model: any, form: any) => {
|
||||||
|
if (value !== oldValue) {
|
||||||
|
const data = form.data;
|
||||||
|
Object.keys(data).forEach(key => {
|
||||||
|
if (key.endsWith('Fields') || key.toLowerCase().endsWith('api')) {
|
||||||
|
form.deleteValueByName(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
form.deleteValueByName('__fields');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return getSchemaTpl('tabs', [
|
return getSchemaTpl('tabs', [
|
||||||
{
|
{
|
||||||
title: '属性',
|
title: '属性',
|
||||||
@ -89,87 +119,57 @@ export class ServicePlugin extends BasePlugin {
|
|||||||
{
|
{
|
||||||
title: '基本',
|
title: '基本',
|
||||||
body: [
|
body: [
|
||||||
getSchemaTpl('name'),
|
dsTypeSelect(),
|
||||||
{
|
...this.dsBuilderMgr.collectFromBuilders(
|
||||||
children: (
|
(builder, builderFlag) => {
|
||||||
<Button
|
return {
|
||||||
level="info"
|
type: 'container',
|
||||||
size="sm"
|
visibleOn: `this.dsType == null || this.dsType === '${builderFlag}'`,
|
||||||
className="m-b-sm"
|
body: flattenDeep([
|
||||||
block
|
builder.makeSourceSettingForm({
|
||||||
onClick={() => {
|
name: 'api',
|
||||||
// this.manager.showInsertPanel('body', context.id);
|
label: '数据源',
|
||||||
this.manager.showRendererPanel('');
|
feat: 'View',
|
||||||
}}
|
inScaffold: false,
|
||||||
>
|
inCrud: false
|
||||||
添加内容
|
})
|
||||||
</Button>
|
])
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
]
|
),
|
||||||
},
|
getSchemaTpl('initFetch', {
|
||||||
{
|
|
||||||
title: '数据接口',
|
|
||||||
body: [
|
|
||||||
getSchemaTpl('apiControl', {
|
|
||||||
name: 'api',
|
|
||||||
label: '数据接口',
|
|
||||||
messageDesc:
|
|
||||||
'设置 service 默认提示信息,当 service 没有返回 msg 信息时有用,如果 service 返回携带了 msg 值,则还是以 service 返回为主'
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
name: 'ws',
|
|
||||||
type: 'input-text',
|
|
||||||
label: 'WebSocket 实时更新接口'
|
|
||||||
},
|
|
||||||
/** initFetchOn可以通过api的sendOn属性控制 */
|
|
||||||
getSchemaTpl('switch', {
|
|
||||||
name: 'initFetch',
|
|
||||||
label: '数据接口初始加载',
|
|
||||||
visibleOn: 'this.api'
|
visibleOn: 'this.api'
|
||||||
}),
|
}),
|
||||||
{
|
getSchemaTpl('interval', {
|
||||||
name: 'interval',
|
visibleOn: 'this.api'
|
||||||
label: '定时刷新间隔',
|
|
||||||
visibleOn: 'this.api',
|
|
||||||
type: 'input-number',
|
|
||||||
step: 500,
|
|
||||||
description: '设置后将自动定时刷新,单位 ms'
|
|
||||||
},
|
|
||||||
getSchemaTpl('switch', {
|
|
||||||
name: 'silentPolling',
|
|
||||||
label: '静默加载',
|
|
||||||
visibleOn: '!!data.interval',
|
|
||||||
description: '设置自动定时刷新是否显示加载动画'
|
|
||||||
}),
|
}),
|
||||||
{
|
getSchemaTpl('silentPolling'),
|
||||||
name: 'stopAutoRefreshWhen',
|
getSchemaTpl('stopAutoRefreshWhen')
|
||||||
label: '停止定时刷新检测',
|
|
||||||
type: 'input-text',
|
|
||||||
visibleOn: '!!data.interval',
|
|
||||||
description:
|
|
||||||
'定时刷新一旦设置会一直刷新,除非给出表达式,条件满足后则不刷新了。'
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Schema接口',
|
title: '状态',
|
||||||
|
body: [getSchemaTpl('visible')]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '高级',
|
||||||
body: [
|
body: [
|
||||||
getSchemaTpl('apiControl', {
|
getSchemaTpl('apiControl', {
|
||||||
name: 'schemaApi',
|
name: 'schemaApi',
|
||||||
label: '内容 Schema 接口'
|
label: 'Schema数据源'
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('switch', {
|
getSchemaTpl('initFetch', {
|
||||||
name: 'initFetchSchema',
|
name: 'initFetchSchema',
|
||||||
label: 'Schema接口初始加载',
|
label: '是否Schema初始加载',
|
||||||
visibleOn: 'this.schemaApi'
|
visibleOn: 'this.schemaApi'
|
||||||
})
|
}),
|
||||||
]
|
{
|
||||||
},
|
type: 'divider'
|
||||||
{
|
},
|
||||||
title: '全局配置',
|
|
||||||
body: [
|
|
||||||
getSchemaTpl('data'),
|
getSchemaTpl('data'),
|
||||||
|
{
|
||||||
|
type: 'divider'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'js-editor',
|
type: 'js-editor',
|
||||||
allowFullscreen: true,
|
allowFullscreen: true,
|
||||||
@ -178,30 +178,14 @@ export class ServicePlugin extends BasePlugin {
|
|||||||
description: '将会传递 data 和 setData 两个参数'
|
description: '将会传递 data 和 setData 两个参数'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '默认消息信息',
|
type: 'divider'
|
||||||
type: 'combo',
|
},
|
||||||
name: 'messages',
|
{
|
||||||
multiLine: true,
|
name: 'ws',
|
||||||
description:
|
type: 'input-text',
|
||||||
'设置 service 默认提示信息,当 service 没有返回 msg 信息时有用,如果 service 返回携带了 msg 值,则还是以 service 返回为主',
|
label: 'WebSocket 实时更新接口'
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: '获取成功',
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'fetchSuccess'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '获取失败',
|
|
||||||
type: 'input-text',
|
|
||||||
name: 'fetchFailed'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '状态',
|
|
||||||
body: [getSchemaTpl('ref'), getSchemaTpl('visible')]
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
907
packages/amis-editor/src/plugin/Table-v2.tsx
Normal file
907
packages/amis-editor/src/plugin/Table-v2.tsx
Normal file
@ -0,0 +1,907 @@
|
|||||||
|
import {resolveVariable} from 'amis';
|
||||||
|
|
||||||
|
import {setVariable} from 'amis-core';
|
||||||
|
import {
|
||||||
|
BasePlugin,
|
||||||
|
BaseEventContext,
|
||||||
|
PluginEvent,
|
||||||
|
RegionConfig,
|
||||||
|
RendererInfoResolveEventContext,
|
||||||
|
BasicRendererInfo,
|
||||||
|
PluginInterface,
|
||||||
|
InsertEventContext,
|
||||||
|
ScaffoldForm,
|
||||||
|
registerEditorPlugin,
|
||||||
|
defaultValue,
|
||||||
|
getSchemaTpl,
|
||||||
|
tipedLabel,
|
||||||
|
repeatArray,
|
||||||
|
mockValue,
|
||||||
|
EditorNodeType,
|
||||||
|
RendererPluginAction,
|
||||||
|
RendererPluginEvent
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
import {getEventControlConfig} from '../util';
|
||||||
|
import {SchemaObject} from 'amis/lib/Schema';
|
||||||
|
import {getArgsWrapper} from '../renderer/event-control/helper';
|
||||||
|
|
||||||
|
export class TableV2Plugin extends BasePlugin {
|
||||||
|
// 关联渲染器名字
|
||||||
|
rendererName = 'table-v2';
|
||||||
|
$schema = '/schemas/TableSchema.json';
|
||||||
|
|
||||||
|
// 组件名称
|
||||||
|
name = '表格V2';
|
||||||
|
isBaseComponent = true;
|
||||||
|
panelJustify = true;
|
||||||
|
description =
|
||||||
|
'用来展示表格数据,可以配置列信息,然后关联数据便能完成展示。支持嵌套、超级表头、列固定、表头固顶、合并单元格等等。当前组件需要配置数据源,不自带数据拉取,请优先使用 「CRUD」 组件。';
|
||||||
|
docLink = '/amis/zh-CN/components/table-v2';
|
||||||
|
icon = 'fa fa-table';
|
||||||
|
|
||||||
|
scaffold: SchemaObject = {
|
||||||
|
type: 'table-v2',
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '列信息',
|
||||||
|
key: 'a'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
source: '$item'
|
||||||
|
};
|
||||||
|
|
||||||
|
regions: Array<RegionConfig> = [
|
||||||
|
{
|
||||||
|
key: 'columns',
|
||||||
|
label: '列集合',
|
||||||
|
renderMethod: 'renderTable',
|
||||||
|
preferTag: '展示',
|
||||||
|
dndMode: 'position-h'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
previewSchema: any = {
|
||||||
|
type: 'table-v2',
|
||||||
|
className: 'text-left m-b-none',
|
||||||
|
items: [
|
||||||
|
{a: 1, b: 2, c: 9},
|
||||||
|
{a: 3, b: 4, c: 8},
|
||||||
|
{a: 5, b: 6, c: 7}
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: 'A',
|
||||||
|
key: 'a'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'B',
|
||||||
|
key: 'b'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
scaffoldForm: ScaffoldForm = {
|
||||||
|
title: '快速构建表格',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'columns',
|
||||||
|
type: 'combo',
|
||||||
|
multiple: true,
|
||||||
|
label: false,
|
||||||
|
addButtonText: '新增一列',
|
||||||
|
draggable: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'title',
|
||||||
|
placeholder: '标题'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: 'key',
|
||||||
|
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: 'container',
|
||||||
|
label: '容器'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'operation',
|
||||||
|
label: '操作栏'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
canRebuild: true
|
||||||
|
};
|
||||||
|
|
||||||
|
panelTitle = '表格';
|
||||||
|
|
||||||
|
events: RendererPluginEvent[] = [
|
||||||
|
{
|
||||||
|
eventName: 'selectedChange',
|
||||||
|
eventLabel: '选择表格项',
|
||||||
|
description: '手动选择表格项事件',
|
||||||
|
dataSchema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'event.data.selectedItems': {
|
||||||
|
type: 'array',
|
||||||
|
title: '已选择行'
|
||||||
|
},
|
||||||
|
'event.data.unSelectedItems': {
|
||||||
|
type: 'array',
|
||||||
|
title: '未选择行'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
eventName: 'columnSort',
|
||||||
|
eventLabel: '列排序',
|
||||||
|
description: '点击列排序事件',
|
||||||
|
dataSchema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'event.data.orderBy': {
|
||||||
|
type: 'string',
|
||||||
|
title: '列排序列名'
|
||||||
|
},
|
||||||
|
'event.data.orderDir': {
|
||||||
|
type: 'string',
|
||||||
|
title: '列排序值'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
eventName: 'columnFilter',
|
||||||
|
eventLabel: '列筛选',
|
||||||
|
description: '点击列筛选事件',
|
||||||
|
dataSchema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'event.data.filterName': {
|
||||||
|
type: 'string',
|
||||||
|
title: '列筛选列名'
|
||||||
|
},
|
||||||
|
'event.data.filterValue': {
|
||||||
|
type: 'string',
|
||||||
|
title: '列筛选值'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
eventName: 'columnSearch',
|
||||||
|
eventLabel: '列搜索',
|
||||||
|
description: '点击列搜索事件',
|
||||||
|
dataSchema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'event.data.searchName': {
|
||||||
|
type: 'string',
|
||||||
|
title: '列搜索列名'
|
||||||
|
},
|
||||||
|
'event.data.searchValue': {
|
||||||
|
type: 'object',
|
||||||
|
title: '列搜索数据'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
eventName: 'orderChange',
|
||||||
|
eventLabel: '行排序',
|
||||||
|
description: '手动拖拽行排序事件',
|
||||||
|
dataSchema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'event.data.movedItems': {
|
||||||
|
type: 'array',
|
||||||
|
title: '已排序数据'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
eventName: 'columnToggled',
|
||||||
|
eventLabel: '列显示变化',
|
||||||
|
description: '点击自定义列事件',
|
||||||
|
dataSchema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'event.data.columns': {
|
||||||
|
type: 'array',
|
||||||
|
title: '当前显示的列配置数据'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
eventName: 'rowClick',
|
||||||
|
eventLabel: '行单击',
|
||||||
|
description: '点击整行事件',
|
||||||
|
dataSchema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'event.data.rowItem': {
|
||||||
|
type: 'object',
|
||||||
|
title: '行点击数据'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
actions: RendererPluginAction[] = [
|
||||||
|
{
|
||||||
|
actionType: 'select',
|
||||||
|
actionLabel: '设置选中项',
|
||||||
|
description: '设置表格的选中项',
|
||||||
|
schema: getArgsWrapper([
|
||||||
|
{
|
||||||
|
type: 'input-formula',
|
||||||
|
variables: '${variables}',
|
||||||
|
evalMode: false,
|
||||||
|
variableMode: 'tabs',
|
||||||
|
label: '选中项',
|
||||||
|
size: 'lg',
|
||||||
|
name: 'selected',
|
||||||
|
mode: 'horizontal'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
},
|
||||||
|
{
|
||||||
|
actionType: 'selectAll',
|
||||||
|
actionLabel: '设置全部选中',
|
||||||
|
description: '设置表格全部项选中'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
actionType: 'clearAll',
|
||||||
|
actionLabel: '清空选中项',
|
||||||
|
description: '清空表格所有选中项'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
async buildDataSchemas(node: EditorNodeType, region?: EditorNodeType) {
|
||||||
|
const itemsSchema: any = {
|
||||||
|
$id: 'tableRow',
|
||||||
|
type: 'object',
|
||||||
|
properties: {}
|
||||||
|
};
|
||||||
|
const columns: EditorNodeType = node.children.find(
|
||||||
|
item => item.isRegion && item.region === 'columns'
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let current of columns.children) {
|
||||||
|
const schema = current.schema;
|
||||||
|
if (schema && schema.key) {
|
||||||
|
itemsSchema.properties[schema.key] = current.info?.plugin
|
||||||
|
?.buildDataSchemas
|
||||||
|
? await current.info.plugin.buildDataSchemas(current, region)
|
||||||
|
: {
|
||||||
|
type: 'string',
|
||||||
|
title: schema.label || schema.title,
|
||||||
|
description: schema.description
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: any = {
|
||||||
|
$id: 'table-v2',
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
items: {
|
||||||
|
type: 'array',
|
||||||
|
title: '表格数据',
|
||||||
|
items: itemsSchema
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (region?.region === 'columns') {
|
||||||
|
result.properties = {
|
||||||
|
...itemsSchema.properties,
|
||||||
|
...result.properties
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAvailableContextFields(
|
||||||
|
scopeNode: EditorNodeType,
|
||||||
|
node: EditorNodeType,
|
||||||
|
region?: EditorNodeType
|
||||||
|
) {
|
||||||
|
// // 只有表单项组件可以使用表单组件的数据域
|
||||||
|
// if (
|
||||||
|
// scopeNode.parent?.type === 'crud2'
|
||||||
|
// ) {
|
||||||
|
// return scopeNode.parent.info.plugin.getAvailableContextFields?.(
|
||||||
|
// scopeNode.parent,
|
||||||
|
// node,
|
||||||
|
// region
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
panelBodyCreator = (context: BaseEventContext) => {
|
||||||
|
const isCRUDBody = ['crud', 'crud2'].includes(context.schema.type);
|
||||||
|
|
||||||
|
return getSchemaTpl('tabs', [
|
||||||
|
{
|
||||||
|
title: '属性',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('collapseGroup', [
|
||||||
|
{
|
||||||
|
title: '基本',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'source',
|
||||||
|
type: 'input-text',
|
||||||
|
label: tipedLabel('数据源', '绑定当前环境变量。'),
|
||||||
|
hidden: isCRUDBody,
|
||||||
|
pipeIn: defaultValue('${items}')
|
||||||
|
},
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'title',
|
||||||
|
label: '显示标题',
|
||||||
|
pipeIn: (value: any) => !!value,
|
||||||
|
pipeOut: (value: any) => {
|
||||||
|
if (value) {
|
||||||
|
return {
|
||||||
|
type: 'container',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '表格标题',
|
||||||
|
inline: false,
|
||||||
|
style: {
|
||||||
|
fontSize: 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'showHeader',
|
||||||
|
label: '显示表头',
|
||||||
|
value: true,
|
||||||
|
pipeIn: (value: any) => !!value,
|
||||||
|
pipeOut: (value: any) => !!value
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
visibleOn: 'this.showHeader !== false',
|
||||||
|
name: 'sticky',
|
||||||
|
label: '冻结表头',
|
||||||
|
pipeIn: defaultValue(false)
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'footer',
|
||||||
|
label: '显示表尾',
|
||||||
|
pipeIn: (value: any) => !!value,
|
||||||
|
pipeOut: (value: any) => {
|
||||||
|
if (value) {
|
||||||
|
return {
|
||||||
|
type: 'container',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '表格尾部',
|
||||||
|
inline: false,
|
||||||
|
style: {
|
||||||
|
fontSize: 14
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'scroll.y',
|
||||||
|
label: '内容高度',
|
||||||
|
type: 'button-group-select',
|
||||||
|
pipeIn: (v: any) => v != null,
|
||||||
|
pipeOut: (v: any) => (v ? '' : null),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '适配内容',
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '固定',
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'input-group',
|
||||||
|
visibleOn: 'data.scroll && data.scroll.y !== null',
|
||||||
|
label: '高度值',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-number',
|
||||||
|
name: 'scroll.y'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
addOnclassName: 'border-0 bg-none',
|
||||||
|
tpl: 'px'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'scroll.x',
|
||||||
|
label: tipedLabel(
|
||||||
|
'内容宽度',
|
||||||
|
'当列内容过多,超出宽度时,可使用横向滚动方式查看数据。'
|
||||||
|
),
|
||||||
|
type: 'button-group-select',
|
||||||
|
pipeIn: (v: any) => v != null,
|
||||||
|
pipeOut: (v: any) => (v ? '' : null),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '适配内容',
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '固定',
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'input-group',
|
||||||
|
visibleOn: 'data.scroll && data.scroll.x !== null',
|
||||||
|
name: 'scroll.x',
|
||||||
|
label: '宽度值',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-number',
|
||||||
|
name: 'scroll.x'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
addOnclassName: 'border-0 bg-none',
|
||||||
|
tpl: 'px'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'placeholder',
|
||||||
|
pipeIn: defaultValue('暂无数据'),
|
||||||
|
type: 'input-text',
|
||||||
|
label: '占位内容'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '列设置',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'resizable',
|
||||||
|
label: tipedLabel('可调整列宽', '用户可通过拖拽调整列宽度'),
|
||||||
|
pipeIn: (value: any) => !!value,
|
||||||
|
pipeOut: (value: any) => value
|
||||||
|
}),
|
||||||
|
isCRUDBody
|
||||||
|
? null
|
||||||
|
: {
|
||||||
|
type: 'ae-Switch-More',
|
||||||
|
mode: 'normal',
|
||||||
|
name: 'columnsTogglable',
|
||||||
|
hiddenOnDefault: true,
|
||||||
|
formType: 'extend',
|
||||||
|
label: tipedLabel(
|
||||||
|
'自定义显示列',
|
||||||
|
'自动即列数量大于10自动开启。'
|
||||||
|
),
|
||||||
|
pipeOut: (value: any) => {
|
||||||
|
if (value && value.columnsTogglable) {
|
||||||
|
return {columnsTogglable: {type: 'column-toggler'}};
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
mode: 'normal',
|
||||||
|
type: 'ae-columnControl'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '行设置',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'lineHeight',
|
||||||
|
label: '行高度',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择高度',
|
||||||
|
options: [
|
||||||
|
{label: '跟随内容', value: ''},
|
||||||
|
{label: '高', value: 'large'},
|
||||||
|
{label: '中', value: 'middle'}
|
||||||
|
],
|
||||||
|
clearable: false,
|
||||||
|
value: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
isCRUDBody
|
||||||
|
? {
|
||||||
|
type: 'ae-Switch-More',
|
||||||
|
mode: 'normal',
|
||||||
|
name: 'rowSelection',
|
||||||
|
label: '可多选',
|
||||||
|
visibleOn: 'data.selectable',
|
||||||
|
hiddenOnDefault: true,
|
||||||
|
formType: 'extend',
|
||||||
|
form: {
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
label: '可选区域',
|
||||||
|
name: 'rowSelection.rowClick',
|
||||||
|
type: 'button-group-select',
|
||||||
|
value: false,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'CheckBox',
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '整行',
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rowSelection.disableOn',
|
||||||
|
type: 'ae-formulaControl',
|
||||||
|
label: '行禁用条件'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rowSelection.selections',
|
||||||
|
label: '选择菜单项',
|
||||||
|
type: 'checkboxes',
|
||||||
|
joinValues: false,
|
||||||
|
inline: false,
|
||||||
|
itemClassName: 'text-sm',
|
||||||
|
options: [
|
||||||
|
{label: '全选', value: 'all'},
|
||||||
|
{label: '反选', value: 'invert'},
|
||||||
|
{label: '取消选择', value: 'none'},
|
||||||
|
{label: '选择奇数项', value: 'odd'},
|
||||||
|
{label: '选择偶数项', value: 'even'}
|
||||||
|
],
|
||||||
|
pipeIn(v: any) {
|
||||||
|
if (!v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return v.map((item: any) => ({
|
||||||
|
label: item.text,
|
||||||
|
value: item.key
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
pipeOut(v: any) {
|
||||||
|
if (!v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return v.map((item: any) => ({
|
||||||
|
key: item.value,
|
||||||
|
text: item.label
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'ae-Switch-More',
|
||||||
|
mode: 'normal',
|
||||||
|
name: 'expandable',
|
||||||
|
label: '可展开',
|
||||||
|
hiddenOnDefault: true,
|
||||||
|
formType: 'extend',
|
||||||
|
form: {
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'expandable.expandableOn',
|
||||||
|
visibleOn: 'data.expandable',
|
||||||
|
type: 'ae-formulaControl',
|
||||||
|
label: '行展开条件'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'childrenColumnName',
|
||||||
|
label: '可嵌套',
|
||||||
|
pipeIn: (value: any) => !!value,
|
||||||
|
pipeOut: (value: any) => (value ? 'children' : '')
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'draggable',
|
||||||
|
label: '可拖拽',
|
||||||
|
pipeIn: (value: any) => !!value,
|
||||||
|
pipeOut: (value: any) => value
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('hidden', {
|
||||||
|
label: '隐藏'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '高级',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('apiControl', {
|
||||||
|
label: '快速保存',
|
||||||
|
name: 'quickSaveApi'
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('apiControl', {
|
||||||
|
label: '快速保存单条',
|
||||||
|
name: 'quickSaveItemApi'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '外观',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('collapseGroup', [
|
||||||
|
{
|
||||||
|
title: '基本',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'bordered',
|
||||||
|
label: '边框',
|
||||||
|
pipeIn: defaultValue(false)
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'scroll.x',
|
||||||
|
type: 'input-number',
|
||||||
|
label: '横向滚动'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'indentSize',
|
||||||
|
visibleOn: 'data.childrenColumnName',
|
||||||
|
type: 'input-number',
|
||||||
|
unitOptions: [{label: 'px', value: 'px'}],
|
||||||
|
label: '嵌套缩进'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'rowSelection.columnWidth',
|
||||||
|
visibleOn: 'data.rowSelection',
|
||||||
|
type: 'input-number',
|
||||||
|
label: '选择列宽度',
|
||||||
|
description: '固定选择列的宽度'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'expandable.columnWidth',
|
||||||
|
visibleOn: 'data.expandable',
|
||||||
|
type: 'input-number',
|
||||||
|
label: '展开列宽度',
|
||||||
|
description: '固定展开列的宽度'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
getSchemaTpl('style:classNames', {
|
||||||
|
isFormItem: true,
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
name: 'rowClassNameExpr',
|
||||||
|
type: 'ae-formulaControl',
|
||||||
|
label: '自定义行样式'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'expandable.expandedRowClassNameExpr',
|
||||||
|
visibleOn: 'data.expandable',
|
||||||
|
type: 'ae-formulaControl',
|
||||||
|
label: '展开行样式'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
])
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '事件',
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('eventControl', {
|
||||||
|
name: 'onEvent',
|
||||||
|
...getEventControlConfig(this.manager, context)
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
filterProps(props: any) {
|
||||||
|
const arr = Array.isArray(props.value)
|
||||||
|
? props.value
|
||||||
|
: typeof props.source === 'string'
|
||||||
|
? resolveVariable(props.source, props.data)
|
||||||
|
: resolveVariable('items', props.data);
|
||||||
|
|
||||||
|
if (!Array.isArray(arr) || !arr.length) {
|
||||||
|
const mockedData: any = {};
|
||||||
|
|
||||||
|
if (Array.isArray(props.columns)) {
|
||||||
|
props.columns.forEach((column: any) => {
|
||||||
|
if (column.key) {
|
||||||
|
setVariable(mockedData, column.key, mockValue(column));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
props.value = repeatArray(mockedData, 10).map((item, index) => ({
|
||||||
|
...item,
|
||||||
|
id: index + 1
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
// 只取10条预览,否则太多卡顿
|
||||||
|
props.value = arr.slice(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果设置了可展开 默认把第一行展开
|
||||||
|
if (props.expandable) {
|
||||||
|
if (typeof props.expandable === 'boolean') {
|
||||||
|
props.expandable = {};
|
||||||
|
}
|
||||||
|
if (!props.expandable.type) {
|
||||||
|
props.expandable.type = 'container';
|
||||||
|
props.expandable.body = [
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
tpl: '展开行内容',
|
||||||
|
inline: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
props.expandable.keyField = 'id';
|
||||||
|
props.expandable.expandedRowKeys = [1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为了能够自动注入数据。
|
||||||
|
getRendererInfo(
|
||||||
|
context: RendererInfoResolveEventContext
|
||||||
|
): BasicRendererInfo | void {
|
||||||
|
const plugin: PluginInterface = this;
|
||||||
|
const {schema, renderer} = context;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!schema.$$id &&
|
||||||
|
['crud', 'crud2'].includes(schema.$$editor?.renderer.name) &&
|
||||||
|
renderer.name === 'table-v2'
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
...({id: schema.$$editor.id} as any),
|
||||||
|
name: plugin.name!,
|
||||||
|
regions: plugin.regions,
|
||||||
|
patchContainers: plugin.patchContainers,
|
||||||
|
vRendererConfig: plugin.vRendererConfig,
|
||||||
|
wrapperProps: plugin.wrapperProps,
|
||||||
|
wrapperResolve: plugin.wrapperResolve,
|
||||||
|
filterProps: plugin.filterProps,
|
||||||
|
$schema: plugin.$schema,
|
||||||
|
renderRenderer: plugin.renderRenderer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return super.getRendererInfo(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动插入 label
|
||||||
|
beforeInsert(event: PluginEvent<InsertEventContext>) {
|
||||||
|
const context = event.context;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(context.info.plugin === this ||
|
||||||
|
context.node.sameIdChild?.info.plugin === this) &&
|
||||||
|
context.region === 'columns'
|
||||||
|
) {
|
||||||
|
context.data = {
|
||||||
|
...context.data,
|
||||||
|
title: context.data.label ?? context.subRenderer?.name ?? '列名称'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEditorPlugin(TableV2Plugin);
|
588
packages/amis-editor/src/plugin/TableCell-v2.tsx
Normal file
588
packages/amis-editor/src/plugin/TableCell-v2.tsx
Normal file
@ -0,0 +1,588 @@
|
|||||||
|
import {Button, Icon} from 'amis';
|
||||||
|
import React from 'react';
|
||||||
|
import {FormItemProps, getVariable} from 'amis-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
BasePlugin,
|
||||||
|
BasicRendererInfo,
|
||||||
|
registerEditorPlugin,
|
||||||
|
RendererInfoResolveEventContext,
|
||||||
|
ReplaceEventContext,
|
||||||
|
PluginEvent,
|
||||||
|
AfterBuildPanelBody,
|
||||||
|
defaultValue,
|
||||||
|
getSchemaTpl,
|
||||||
|
tipedLabel,
|
||||||
|
DSField
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
import {fromPairs} from 'lodash';
|
||||||
|
import {TabsSchema} from 'amis/lib/renderers/Tabs';
|
||||||
|
import {SchemaObject} from 'amis/lib/Schema';
|
||||||
|
import {remarkTpl} from '../component/BaseControl';
|
||||||
|
|
||||||
|
export class TableCellV2Plugin extends BasePlugin {
|
||||||
|
panelTitle = '列配置';
|
||||||
|
panelIcon = 'fa fa-columns';
|
||||||
|
|
||||||
|
afterBuildPanelBody(event: PluginEvent<AfterBuildPanelBody>) {
|
||||||
|
const {context, data} = event.context;
|
||||||
|
if (
|
||||||
|
!context.node.parent?.parent?.type ||
|
||||||
|
context.node.parent.parent.type !== 'table-v2'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const base: Array<{
|
||||||
|
sameName?: string;
|
||||||
|
[propName: string]: any;
|
||||||
|
}> = [
|
||||||
|
context.node.info.plugin.withDataSource === false
|
||||||
|
? false
|
||||||
|
: {
|
||||||
|
sameName: context.info.renderer.isFormItem ? 'name' : undefined,
|
||||||
|
name: 'key',
|
||||||
|
type: 'ae-DataBindingControl',
|
||||||
|
label: '列字段',
|
||||||
|
onBindingChange(
|
||||||
|
field: DSField,
|
||||||
|
onBulkChange: (value: any) => void
|
||||||
|
) {
|
||||||
|
const schema = field?.resolveColumnSchema?.('List') || {
|
||||||
|
title: field.label
|
||||||
|
};
|
||||||
|
onBulkChange(schema);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
sameName: context.info.renderer.isFormItem ? 'label' : undefined,
|
||||||
|
name: 'title',
|
||||||
|
label: '列标题',
|
||||||
|
type: 'input-text'
|
||||||
|
},
|
||||||
|
|
||||||
|
remarkTpl({
|
||||||
|
name: 'remark',
|
||||||
|
label: '标题提示',
|
||||||
|
labelRemark: '在标题旁展示提示'
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'placeholder',
|
||||||
|
type: 'input-text',
|
||||||
|
label: tipedLabel('占位提示', '当没有值时用这个来替代展示。'),
|
||||||
|
value: '-'
|
||||||
|
}
|
||||||
|
].filter(Boolean);
|
||||||
|
const advanced = [
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'sorter',
|
||||||
|
label: tipedLabel(
|
||||||
|
'可排序',
|
||||||
|
'开启后可以根据当前列排序,接口类型将增加排序参数。'
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'searchable',
|
||||||
|
label: '可搜索',
|
||||||
|
pipeIn: (value: any) => !!value
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
visibleOn: 'data.searchable',
|
||||||
|
name: 'searchable',
|
||||||
|
asFormItem: true,
|
||||||
|
label: false,
|
||||||
|
children: ({value, onChange, data}: any) => {
|
||||||
|
if (value === true) {
|
||||||
|
value = {};
|
||||||
|
} else if (typeof value === 'undefined') {
|
||||||
|
value = getVariable(data, 'searchable');
|
||||||
|
}
|
||||||
|
|
||||||
|
const originMode = value.mode;
|
||||||
|
|
||||||
|
value = {
|
||||||
|
...value,
|
||||||
|
type: 'form',
|
||||||
|
mode: 'normal',
|
||||||
|
wrapWithPanel: false,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: data.key
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
delete value.mode;
|
||||||
|
// todo 多个快速编辑表单模式看来只能代码模式编辑了。
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="w-full flex flex-col items-center"
|
||||||
|
onClick={() => {
|
||||||
|
this.manager.openSubEditor({
|
||||||
|
title: '配置列搜索类型',
|
||||||
|
value: value,
|
||||||
|
onChange: value =>
|
||||||
|
onChange(
|
||||||
|
{
|
||||||
|
...value,
|
||||||
|
mode: originMode
|
||||||
|
},
|
||||||
|
'searchable'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="inline-flex items-center">
|
||||||
|
<Icon icon="edit" className="mr-1 w-3" />
|
||||||
|
配置列搜索类型
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'quickEdit',
|
||||||
|
label: tipedLabel('快速编辑', '输入框左侧或右侧的附加挂件'),
|
||||||
|
type: 'ae-switch-more',
|
||||||
|
mode: 'normal',
|
||||||
|
formType: 'extend',
|
||||||
|
bulk: true,
|
||||||
|
defaultData: {
|
||||||
|
mode: 'popOver'
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'quickEdit.mode',
|
||||||
|
type: 'button-group-select',
|
||||||
|
label: '模式',
|
||||||
|
value: 'popOver',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '下拉',
|
||||||
|
value: 'popOver'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '内嵌',
|
||||||
|
value: 'inline'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'quickEdit.saveImmediately',
|
||||||
|
label: tipedLabel(
|
||||||
|
'修改立即保存',
|
||||||
|
'开启后修改即提交,而不是批量提交。'
|
||||||
|
),
|
||||||
|
pipeIn: (value: any) => !!value
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'quickEdit',
|
||||||
|
asFormItem: true,
|
||||||
|
label: false,
|
||||||
|
children: ({value, onBulkChange, name, data}: any) => {
|
||||||
|
if (value === true) {
|
||||||
|
value = {};
|
||||||
|
} else if (typeof value === 'undefined') {
|
||||||
|
value = getVariable(data, 'quickEdit');
|
||||||
|
}
|
||||||
|
|
||||||
|
const originMode = value?.mode || 'popOver';
|
||||||
|
|
||||||
|
value = {
|
||||||
|
...value,
|
||||||
|
type: 'form',
|
||||||
|
mode: 'normal',
|
||||||
|
wrapWithPanel: false,
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'input-text',
|
||||||
|
name: data.key
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (value.mode) {
|
||||||
|
delete value.mode;
|
||||||
|
}
|
||||||
|
// todo 多个快速编辑表单模式看来只能代码模式编辑了。
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="w-full flex flex-col items-center"
|
||||||
|
onClick={() => {
|
||||||
|
this.manager.openSubEditor({
|
||||||
|
title: '配置快速编辑类型',
|
||||||
|
value: value,
|
||||||
|
onChange: value =>
|
||||||
|
onBulkChange({
|
||||||
|
[name]: {
|
||||||
|
...value,
|
||||||
|
mode: originMode
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="inline-flex items-center">
|
||||||
|
<Icon icon="edit" className="mr-1 w-3" />
|
||||||
|
配置编辑表单
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'popOver',
|
||||||
|
label: '查看更多',
|
||||||
|
type: 'ae-switch-more',
|
||||||
|
mode: 'normal',
|
||||||
|
formType: 'extend',
|
||||||
|
bulk: true,
|
||||||
|
form: {
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'popOver.mode',
|
||||||
|
label: '模式',
|
||||||
|
type: 'button-group-select',
|
||||||
|
pipeIn: defaultValue('popOver'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '浮窗',
|
||||||
|
value: 'popOver'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '弹框',
|
||||||
|
value: 'dialog'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '抽屉',
|
||||||
|
value: 'drawer'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'popOver.position',
|
||||||
|
label: '浮窗位置',
|
||||||
|
type: 'select',
|
||||||
|
visibleOn: 'data.popOver.mode === "popOver"',
|
||||||
|
pipeIn: defaultValue('center'),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '目标中部',
|
||||||
|
value: 'center'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '目标左上角',
|
||||||
|
value: 'left-top'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '目标右上角',
|
||||||
|
value: 'right-top'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '目标左下角',
|
||||||
|
value: 'left-bottom'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '目标右下角',
|
||||||
|
value: 'right-bottom'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '页面左上角',
|
||||||
|
value: 'fixed-left-top'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '页面右上角',
|
||||||
|
value: 'fixed-right-top'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '页面左下角',
|
||||||
|
value: 'fixed-left-bottom'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '页面右下角',
|
||||||
|
value: 'fixed-right-bottom'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'popOver',
|
||||||
|
asFormItem: true,
|
||||||
|
label: false,
|
||||||
|
children: ({value, onBulkChange, name}: any) => {
|
||||||
|
value = {
|
||||||
|
type: 'panel',
|
||||||
|
title: '查看详情',
|
||||||
|
body: '内容详情',
|
||||||
|
...value
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="w-full flex flex-col items-center"
|
||||||
|
onClick={() => {
|
||||||
|
this.manager.openSubEditor({
|
||||||
|
title: '配置查看更多展示内容',
|
||||||
|
value: value,
|
||||||
|
onChange: value =>
|
||||||
|
onBulkChange({
|
||||||
|
[name]: value
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="inline-flex items-center">
|
||||||
|
<Icon icon="edit" className="mr-1 w-3" />
|
||||||
|
配置内容
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'copyable',
|
||||||
|
label: tipedLabel('复制内容', '默认为当前字段值,可定制。'),
|
||||||
|
type: 'ae-switch-more',
|
||||||
|
mode: 'normal',
|
||||||
|
formType: 'extend',
|
||||||
|
bulk: true,
|
||||||
|
defaultData: {},
|
||||||
|
form: {
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: 'copyable.content',
|
||||||
|
type: 'textarea',
|
||||||
|
placehoder: '默认为当前字段的值',
|
||||||
|
label: '内容模板'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'rowSpanExpr',
|
||||||
|
type: 'ae-formulaControl',
|
||||||
|
label: '合并行'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'colSpanExpr',
|
||||||
|
type: 'ae-formulaControl',
|
||||||
|
label: '合并列'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const baseStyle = [
|
||||||
|
getSchemaTpl('withUnit', {
|
||||||
|
name: 'width',
|
||||||
|
label: tipedLabel('列宽', '固定列的宽度,不推荐设置。'),
|
||||||
|
control: {
|
||||||
|
name: 'width',
|
||||||
|
type: 'input-number'
|
||||||
|
},
|
||||||
|
unit: 'px'
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'fixed',
|
||||||
|
type: 'button-group-select',
|
||||||
|
label: '固定位置',
|
||||||
|
pipeIn: defaultValue(''),
|
||||||
|
pipeOut(value: any) {
|
||||||
|
if (!value) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: '',
|
||||||
|
label: '不固定'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
value: 'left',
|
||||||
|
label: '左侧'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
value: 'right',
|
||||||
|
label: '右侧'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'toggled',
|
||||||
|
label: '自定义列时默认展示',
|
||||||
|
pipeIn: defaultValue(true)
|
||||||
|
}),
|
||||||
|
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
name: 'className',
|
||||||
|
label: '内容超出换行',
|
||||||
|
pipeIn: (value: any) =>
|
||||||
|
typeof value === 'string' && /\word\-break\b/.test(value),
|
||||||
|
pipeOut: (value: any, originValue: any) =>
|
||||||
|
(value ? 'word-break ' : '') +
|
||||||
|
(originValue || '').replace(/\bword\-break\b/g, '').trim()
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
// 之前的面板,不是新的组件面板,需要添加新的tab,不能合并
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
if ((data[0] as SchemaObject).type === 'tabs') {
|
||||||
|
const body = data[0] as TabsSchema;
|
||||||
|
body.tabs.forEach((tab: any) => {
|
||||||
|
if (tab.title === '常规') {
|
||||||
|
tab.body.unshift(...base.concat(advanced));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tab.title === '外观') {
|
||||||
|
tab.body.unshift(...baseStyle);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error('错误的组件合并对象,面板过老无法处理,除非增加新面板');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(data as TabsSchema).tabs?.forEach((tab: any) => {
|
||||||
|
if (tab.title === '属性') {
|
||||||
|
tab.body[0].body.forEach((collapse: any) => {
|
||||||
|
if (collapse.title === '基本') {
|
||||||
|
const appendItems = fromPairs(
|
||||||
|
base.map(item => [item.sameName ?? item.name, item])
|
||||||
|
);
|
||||||
|
|
||||||
|
const removeIndex: number[] = [];
|
||||||
|
collapse.body.forEach((item: any, index: number) => {
|
||||||
|
const key = item.name;
|
||||||
|
|
||||||
|
// 重复意义的配置用现在的表达文案替换一下
|
||||||
|
if (appendItems.hasOwnProperty(key)) {
|
||||||
|
removeIndex.push(index);
|
||||||
|
appendItems[key] = {
|
||||||
|
...item,
|
||||||
|
...appendItems[key]
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.name === 'labelRemark') {
|
||||||
|
removeIndex.push(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
removeIndex.reverse();
|
||||||
|
removeIndex.forEach(index => {
|
||||||
|
collapse.body.splice(index, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
collapse.body.unshift(...Object.values(appendItems));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const moreCollapse = getSchemaTpl('collapseGroup', [
|
||||||
|
{
|
||||||
|
title: '列',
|
||||||
|
body: advanced
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
tab.body[0].body.splice(1, 0, ...moreCollapse.body);
|
||||||
|
// 让折叠器默认都展开
|
||||||
|
tab.body[0].activeKey.push(...moreCollapse.activeKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tab.title === '外观') {
|
||||||
|
const moreCollapse = getSchemaTpl('collapseGroup', [
|
||||||
|
{
|
||||||
|
title: '列',
|
||||||
|
body: baseStyle
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
tab.body[0].body.splice(1, 0, ...moreCollapse.body);
|
||||||
|
// 让折叠器默认都展开
|
||||||
|
tab.body[0].activeKey.push(...moreCollapse.activeKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// filterProps(props: any) {
|
||||||
|
// props = JSONPipeOut(props, true);
|
||||||
|
// return props;
|
||||||
|
// }
|
||||||
|
|
||||||
|
getRendererInfo(
|
||||||
|
context: RendererInfoResolveEventContext
|
||||||
|
): BasicRendererInfo | void {
|
||||||
|
const {renderer, schema} = context;
|
||||||
|
|
||||||
|
if (renderer.name === 'cell-field') {
|
||||||
|
return {
|
||||||
|
name: schema.title ? `<${schema.title}>列` : '匿名列',
|
||||||
|
$schema: '/schemas/TableColumn.json',
|
||||||
|
multifactor: true,
|
||||||
|
wrapperResolve: (dom: HTMLDivElement) => {
|
||||||
|
// 固定这种结构 amis里改了 这里也得改
|
||||||
|
const parent = dom.parentElement?.parentElement;
|
||||||
|
const groupId = parent?.getAttribute('data-group-id');
|
||||||
|
const wrapper = dom.closest('table')!.parentElement?.parentElement;
|
||||||
|
|
||||||
|
return [].slice.call(
|
||||||
|
wrapper?.querySelectorAll(
|
||||||
|
`th[data-group-id="${groupId}"],
|
||||||
|
td[data-group-id="${groupId}"]`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// filterProps: this.filterProps
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*exchangeRenderer(id: string) {
|
||||||
|
this.manager.showReplacePanel(id, '展示');
|
||||||
|
}*/
|
||||||
|
|
||||||
|
beforeReplace(event: PluginEvent<ReplaceEventContext>) {
|
||||||
|
const context = event.context;
|
||||||
|
|
||||||
|
// 替换字段的时候保留 label 和 name 值。
|
||||||
|
if (context.info.plugin === this && context.data) {
|
||||||
|
context.data.title = context.data.title || context.schema.title;
|
||||||
|
context.data.key = context.data.key || context.schema.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEditorPlugin(TableCellV2Plugin);
|
@ -16,10 +16,10 @@ import {VRenderer} from 'amis-editor-core';
|
|||||||
import findIndex from 'lodash/findIndex';
|
import findIndex from 'lodash/findIndex';
|
||||||
import {RegionWrapper as Region} from 'amis-editor-core';
|
import {RegionWrapper as Region} from 'amis-editor-core';
|
||||||
import {Tab} from 'amis';
|
import {Tab} from 'amis';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
import {ValidatorTag} from '../validator';
|
import {ValidatorTag} from '../validator';
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
import { getArgsWrapper } from '../renderer/event-control/helper';
|
import {getArgsWrapper} from '../renderer/event-control/helper';
|
||||||
|
|
||||||
export class TabsPlugin extends BasePlugin {
|
export class TabsPlugin extends BasePlugin {
|
||||||
// 关联渲染器名字
|
// 关联渲染器名字
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
import {BasePlugin, RegionConfig, BaseEventContext} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
export class TooltipWrapperPlugin extends BasePlugin {
|
export class TooltipWrapperPlugin extends BasePlugin {
|
||||||
rendererName = 'tooltip-wrapper';
|
rendererName = 'tooltip-wrapper';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {registerEditorPlugin} from 'amis-editor-core';
|
import {registerEditorPlugin} from 'amis-editor-core';
|
||||||
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
import {BaseEventContext, BasePlugin} from 'amis-editor-core';
|
||||||
import {defaultValue, getSchemaTpl, setSchemaTpl} from 'amis-editor-core';
|
import {defaultValue, getSchemaTpl, setSchemaTpl} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
import {ValidatorTag} from '../validator';
|
import {ValidatorTag} from '../validator';
|
||||||
import {getEventControlConfig} from '../util';
|
import {getEventControlConfig} from '../util';
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ export class TplPlugin extends BasePlugin {
|
|||||||
),
|
),
|
||||||
name: 'inline',
|
name: 'inline',
|
||||||
pipeIn: defaultValue(true),
|
pipeIn: defaultValue(true),
|
||||||
hiddenOn:'data.wrapperComponent !== ""'
|
hiddenOn: 'data.wrapperComponent !== ""'
|
||||||
}),
|
}),
|
||||||
getSchemaTpl('tpl:content'),
|
getSchemaTpl('tpl:content'),
|
||||||
getSchemaTpl('tpl:rich-text')
|
getSchemaTpl('tpl:rich-text')
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
getSchemaTpl
|
getSchemaTpl
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter';
|
import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
// 需要一个示例,不然默认的没有高度都无法选中
|
// 需要一个示例,不然默认的没有高度都无法选中
|
||||||
class WebComponentDemo extends HTMLElement {
|
class WebComponentDemo extends HTMLElement {
|
||||||
@ -67,7 +67,7 @@ export class WebComponentPlugin extends BasePlugin {
|
|||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
name: 'props',
|
name: 'props',
|
||||||
label: '属性'
|
label: '属性'
|
||||||
}),
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -1,26 +1,43 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
|
import isEqual from 'lodash/isEqual';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
import cloneDeep from 'lodash/cloneDeep';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import {FormItem, InputBox, Icon} from 'amis';
|
import {FormItem, Icon} from 'amis';
|
||||||
import {} from 'amis-ui';
|
import {Input, PickerContainer, Spinner} from 'amis-ui';
|
||||||
import {PickerContainer} from 'amis';
|
|
||||||
|
|
||||||
import {getEnv} from 'mobx-state-tree';
|
import {getEnv} from 'mobx-state-tree';
|
||||||
import {normalizeApi, isEffectiveApi, isApiOutdated} from 'amis-core';
|
import {normalizeApi, isEffectiveApi, isApiOutdated} from 'amis-core';
|
||||||
|
|
||||||
import {isObject, autobind, createObject, anyChanged} from 'amis-editor-core';
|
import {isObject, autobind, createObject, tipedLabel} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
|
||||||
|
|
||||||
import type {SchemaObject, SchemaCollection, SchemaApi} from 'amis/lib/Schema';
|
import type {SchemaObject, SchemaCollection, SchemaApi} from 'amis/lib/Schema';
|
||||||
import type {Api} from 'amis/lib/types';
|
import type {Api} from 'amis/lib/types';
|
||||||
import type {FormControlProps} from 'amis-core';
|
import type {FormControlProps} from 'amis-core';
|
||||||
import type {ActionSchema} from 'amis/lib/renderers/Action';
|
import type {ActionSchema} from 'amis/lib/renderers/Action';
|
||||||
|
|
||||||
|
export type ApiObject = Api & {
|
||||||
|
messages?: Record<
|
||||||
|
| 'fetchSuccess'
|
||||||
|
| 'fetchFailed'
|
||||||
|
| 'saveOrderSuccess'
|
||||||
|
| 'saveOrderFailed'
|
||||||
|
| 'quickSaveSuccess'
|
||||||
|
| 'quickSaveFailed',
|
||||||
|
string
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
export interface APIControlProps extends FormControlProps {
|
export interface APIControlProps extends FormControlProps {
|
||||||
name?: string;
|
name?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
value?: any;
|
value?: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启debug模式
|
||||||
|
*/
|
||||||
|
debug?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口消息设置描述信息
|
* 接口消息设置描述信息
|
||||||
*/
|
*/
|
||||||
@ -76,6 +93,36 @@ export interface APIControlProps extends FormControlProps {
|
|||||||
*/
|
*/
|
||||||
pickerHeaderClassName?: string;
|
pickerHeaderClassName?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否只返回内部TabsPanel
|
||||||
|
*/
|
||||||
|
onlyTabs?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启高亮显示
|
||||||
|
*/
|
||||||
|
enableHighlight?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Picker选项的label字段
|
||||||
|
*/
|
||||||
|
labelField?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检索字段
|
||||||
|
*/
|
||||||
|
searchField?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检索字段类型
|
||||||
|
*/
|
||||||
|
searchType?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 底部区域CSS类名
|
||||||
|
*/
|
||||||
|
footerClassName?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Picker面板确认
|
* Picker面板确认
|
||||||
*/
|
*/
|
||||||
@ -103,38 +150,52 @@ export interface APIControlState {
|
|||||||
apiStr: string;
|
apiStr: string;
|
||||||
selectedItem?: any[];
|
selectedItem?: any[];
|
||||||
schema?: SchemaCollection;
|
schema?: SchemaCollection;
|
||||||
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class APIControl extends React.Component<
|
export default class APIControl extends React.Component<
|
||||||
APIControlProps,
|
APIControlProps,
|
||||||
APIControlState
|
APIControlState
|
||||||
> {
|
> {
|
||||||
static defaultProps: Pick<APIControlProps, 'pickerBtnSchema'> = {
|
input?: HTMLInputElement;
|
||||||
|
|
||||||
|
static defaultProps: Pick<
|
||||||
|
APIControlProps,
|
||||||
|
'pickerBtnSchema' | 'labelField' | 'searchType'
|
||||||
|
> = {
|
||||||
pickerBtnSchema: {
|
pickerBtnSchema: {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
level: 'link',
|
level: 'link',
|
||||||
size: 'sm',
|
size: 'sm'
|
||||||
label: '点击选择'
|
},
|
||||||
}
|
labelField: 'label',
|
||||||
|
searchType: 'key'
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: APIControlProps) {
|
constructor(props: APIControlProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
apiStr: this.transformApi2Str(props.value),
|
apiStr: this.transformApi2Str(props.value),
|
||||||
selectedItem: [],
|
selectedItem: [],
|
||||||
schema: props.pickerSchema
|
schema: props.pickerSchema,
|
||||||
|
loading: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.updatePickerOptions();
|
||||||
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps: APIControlProps) {
|
componentDidUpdate(prevProps: APIControlProps) {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
|
|
||||||
if (prevProps.value !== props.value) {
|
if (!isEqual(prevProps?.value, props?.value)) {
|
||||||
this.setState({apiStr: this.transformApi2Str(props.value)});
|
this.setState({apiStr: this.transformApi2Str(props.value)});
|
||||||
|
this.updatePickerOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyChanged(['enablePickerMode', 'pickerSchema'], prevProps, props)) {
|
if (!isEqual(prevProps?.enablePickerMode, props?.enablePickerMode)) {
|
||||||
this.setState({schema: props.pickerSchema});
|
this.setState({schema: props.pickerSchema});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,23 +211,52 @@ export default class APIControl extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已选API详情,因为list接口是分页的,所以需要单独调用一次
|
||||||
|
*/
|
||||||
|
async updatePickerOptions() {
|
||||||
|
const apiObj = normalizeApi(this.props.value);
|
||||||
|
|
||||||
|
if (apiObj?.url?.startsWith('api://')) {
|
||||||
|
this.setState({loading: true});
|
||||||
|
const keyword = apiObj.url.replace('api://', '');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.fetchOptions(keyword);
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
this.setState({loading: false});
|
||||||
|
}
|
||||||
|
|
||||||
transformApi2Str(value: any) {
|
transformApi2Str(value: any) {
|
||||||
const api = normalizeApi(value);
|
const api = normalizeApi(value);
|
||||||
|
|
||||||
return api.url ? `${api.method ? `${api.method}:` : ''}${api.url}` : '';
|
return api.url
|
||||||
|
? `${
|
||||||
|
api.method &&
|
||||||
|
api.method.toLowerCase() !==
|
||||||
|
'get' /** 默认为GET请求,直接隐藏掉前缀,为了呈现更多信息 */
|
||||||
|
? `${api.method}:`
|
||||||
|
: ''
|
||||||
|
}${api.url}`
|
||||||
|
: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchOptions() {
|
async fetchOptions(keyword?: string) {
|
||||||
const {value, data, env} = this.props;
|
const {value, data, env, searchField, searchType} = this.props;
|
||||||
let {pickerSource} = this.props;
|
let {pickerSource} = this.props;
|
||||||
const apiObj = normalizeApi(value);
|
const apiObj = normalizeApi(value);
|
||||||
const apiKey = apiObj?.url.split('api://')?.[1];
|
|
||||||
|
|
||||||
if (!pickerSource) {
|
if (!pickerSource || !apiObj?.url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ctx = createObject(data, {value, op: 'loadOptions'});
|
const apiKey = apiObj?.url?.split('api://')?.[1];
|
||||||
|
const ctx = createObject(data, {
|
||||||
|
value,
|
||||||
|
op: 'loadOptions',
|
||||||
|
...(keyword && searchField ? {[searchField]: keyword, searchType} : {})
|
||||||
|
});
|
||||||
const schemaFilter = getEnv((window as any).editorStore).schemaFilter;
|
const schemaFilter = getEnv((window as any).editorStore).schemaFilter;
|
||||||
|
|
||||||
// 基于爱速搭的规则转换一下
|
// 基于爱速搭的规则转换一下
|
||||||
@ -177,6 +267,7 @@ export default class APIControl extends React.Component<
|
|||||||
if (isEffectiveApi(pickerSource, ctx)) {
|
if (isEffectiveApi(pickerSource, ctx)) {
|
||||||
const res = await env.fetcher(pickerSource, ctx);
|
const res = await env.fetcher(pickerSource, ctx);
|
||||||
const items: any[] = res.data?.items || res?.data?.rows;
|
const items: any[] = res.data?.items || res?.data?.rows;
|
||||||
|
|
||||||
if (items.length) {
|
if (items.length) {
|
||||||
const selectedItem = items.find(item => item.key === apiKey);
|
const selectedItem = items.find(item => item.key === apiKey);
|
||||||
|
|
||||||
@ -186,7 +277,40 @@ export default class APIControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
handleSubmit(values: SchemaApi, action: any) {
|
inputRef(ref: any) {
|
||||||
|
this.input = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
focus() {
|
||||||
|
if (!this.input) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.input.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
clearPickerValue() {
|
||||||
|
const {onChange} = this.props;
|
||||||
|
|
||||||
|
this.setState(
|
||||||
|
{apiStr: this.transformApi2Str(undefined), selectedItem: []},
|
||||||
|
() => {
|
||||||
|
onChange?.(undefined);
|
||||||
|
this.focus();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleSimpleInputChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
const value = e.currentTarget.value;
|
||||||
|
|
||||||
|
this.handleSubmit(value, 'input');
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleSubmit(values: SchemaApi, action?: 'input' | 'picker-submit') {
|
||||||
const {onChange, value} = this.props;
|
const {onChange, value} = this.props;
|
||||||
let api: Api = values;
|
let api: Api = values;
|
||||||
|
|
||||||
@ -241,7 +365,7 @@ export default class APIControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
const {render, actions, enablePickerMode} = this.props;
|
const {render, actions} = this.props;
|
||||||
|
|
||||||
const actionsDom =
|
const actionsDom =
|
||||||
Array.isArray(actions) && actions.length > 0
|
Array.isArray(actions) && actions.length > 0
|
||||||
@ -253,9 +377,9 @@ export default class APIControl extends React.Component<
|
|||||||
})
|
})
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return actionsDom || enablePickerMode ? (
|
return actionsDom ? (
|
||||||
<header className="ae-ApiControl-header" key="header">
|
<header className="ae-ApiControl-header" key="header">
|
||||||
{enablePickerMode ? this.renderPickerSchema() : actionsDom}
|
{actionsDom}
|
||||||
</header>
|
</header>
|
||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
@ -280,14 +404,19 @@ export default class APIControl extends React.Component<
|
|||||||
return (
|
return (
|
||||||
<PickerContainer
|
<PickerContainer
|
||||||
title={pickerTitle}
|
title={pickerTitle}
|
||||||
value={selectedItem}
|
|
||||||
headerClassName={cx(pickerHeaderClassName, 'font-bold')}
|
headerClassName={cx(pickerHeaderClassName, 'font-bold')}
|
||||||
onConfirm={this.handlePickerConfirm}
|
onConfirm={this.handlePickerConfirm}
|
||||||
onCancel={this.handlePickerClose}
|
onCancel={this.handlePickerClose}
|
||||||
size={pickerSize}
|
size={pickerSize}
|
||||||
bodyRender={({value, onClose, onChange, setState, ...states}) => {
|
bodyRender={({
|
||||||
|
onChange,
|
||||||
|
setState
|
||||||
|
}: {
|
||||||
|
onChange: (value: any) => void;
|
||||||
|
setState: (state: any) => void;
|
||||||
|
}) => {
|
||||||
return render('api-control-picker', schema!, {
|
return render('api-control-picker', schema!, {
|
||||||
data: {[pickerName]: selectedItem},
|
value: selectedItem,
|
||||||
onSelect: (items: Array<any>) => {
|
onSelect: (items: Array<any>) => {
|
||||||
setState({selectedItem: items});
|
setState({selectedItem: items});
|
||||||
onChange(this.normalizeValue(items, onPickerSelect));
|
onChange(this.normalizeValue(items, onPickerSelect));
|
||||||
@ -295,32 +424,50 @@ export default class APIControl extends React.Component<
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({onClick, isOpened}) =>
|
{({
|
||||||
render('picker-action', pickerBtnSchema!, {
|
onClick,
|
||||||
onClick: async (e: React.MouseEvent<any>) => {
|
isOpened
|
||||||
if (!isOpened && enablePickerMode) {
|
}: {
|
||||||
try {
|
onClick: (e: React.MouseEvent) => void;
|
||||||
await this.fetchOptions();
|
isOpened: boolean;
|
||||||
} catch {}
|
}) =>
|
||||||
}
|
render(
|
||||||
|
'picker-action',
|
||||||
|
{
|
||||||
|
icon: (
|
||||||
|
<Icon icon="picker-icon" className="icon ae-ApiControl-icon" />
|
||||||
|
),
|
||||||
|
...pickerBtnSchema!,
|
||||||
|
className: cx(
|
||||||
|
'ae-ApiControl-PickerBtn',
|
||||||
|
pickerBtnSchema?.className
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onClick: async (e: React.MouseEvent<any>) => {
|
||||||
|
if (!isOpened && enablePickerMode) {
|
||||||
|
try {
|
||||||
|
await this.fetchOptions();
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
onClick(e);
|
onClick(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
</PickerContainer>
|
</PickerContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderApiDialog() {
|
renderApiDialog() {
|
||||||
const {messageDesc} = this.props;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: '',
|
label: '',
|
||||||
type: 'action',
|
type: 'action',
|
||||||
acitonType: 'dialog',
|
acitonType: 'dialog',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
icon: <Icon icon="api" />,
|
icon: <Icon icon="setting" className="icon ae-ApiControl-icon" />,
|
||||||
|
className: 'ae-ApiControl-setting-button',
|
||||||
actionType: 'dialog',
|
actionType: 'dialog',
|
||||||
dialog: {
|
dialog: {
|
||||||
title: '高级设置',
|
title: '高级设置',
|
||||||
@ -331,12 +478,14 @@ export default class APIControl extends React.Component<
|
|||||||
closeOnEsc: true,
|
closeOnEsc: true,
|
||||||
closeOnOutside: false,
|
closeOnOutside: false,
|
||||||
showCloseButton: true,
|
showCloseButton: true,
|
||||||
body: [this.renderApiConfigTabs(messageDesc)]
|
body: [this.renderApiConfigTabs()]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
renderApiConfigTabs(messageDesc?: string, submitOnChange: boolean = false) {
|
renderApiConfigTabs(submitOnChange: boolean = false) {
|
||||||
|
const {messageDesc, debug = false} = this.props;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'form',
|
type: 'form',
|
||||||
className: 'ae-ApiControl-form',
|
className: 'ae-ApiControl-form',
|
||||||
@ -344,6 +493,7 @@ export default class APIControl extends React.Component<
|
|||||||
submitOnChange,
|
submitOnChange,
|
||||||
wrapWithPanel: false,
|
wrapWithPanel: false,
|
||||||
onSubmit: this.handleSubmit,
|
onSubmit: this.handleSubmit,
|
||||||
|
debug,
|
||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'tabs',
|
type: 'tabs',
|
||||||
@ -462,75 +612,6 @@ export default class APIControl extends React.Component<
|
|||||||
mode: 'horizontal',
|
mode: 'horizontal',
|
||||||
description: '默认数据为追加方式,开启后完全替换当前数据'
|
description: '默认数据为追加方式,开启后完全替换当前数据'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: tipedLabel(
|
|
||||||
'初始加载',
|
|
||||||
'当配置初始化接口后,组件初始就会拉取接口数据,可以通过以下配置修改'
|
|
||||||
),
|
|
||||||
type: 'group',
|
|
||||||
visibleOn: 'this.initApi',
|
|
||||||
mode: 'horizontal',
|
|
||||||
direction: 'vertical',
|
|
||||||
// labelRemark: {
|
|
||||||
// trigger: 'hover',
|
|
||||||
// rootClose: true,
|
|
||||||
// content:
|
|
||||||
// '当配置初始化接口后,组件初始就会拉取接口数据,可以通过以下配置修改',
|
|
||||||
// placement: 'top'
|
|
||||||
// },
|
|
||||||
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
name: 'initFetch',
|
|
||||||
type: 'radios',
|
|
||||||
inline: true,
|
|
||||||
mode: 'normal',
|
|
||||||
renderLabel: false,
|
|
||||||
onChange: () => {
|
|
||||||
document.getElementsByClassName(
|
|
||||||
'ae-Settings-content'
|
|
||||||
)[0].scrollTop = 0;
|
|
||||||
},
|
|
||||||
// pipeIn: (value:any) => typeof value === 'boolean' ? value : '1'
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: '是',
|
|
||||||
value: true
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '否',
|
|
||||||
value: false
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '表达式',
|
|
||||||
value: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'initFetchOn',
|
|
||||||
autoComplete: false,
|
|
||||||
visibleOn: 'typeof this.initFetch !== "boolean"',
|
|
||||||
type: 'input-text',
|
|
||||||
mode: 'normal',
|
|
||||||
size: 'lg',
|
|
||||||
renderLabel: false,
|
|
||||||
placeholder: '如:this.id 表示有 id 值时初始加载',
|
|
||||||
className: 'm-t-n-sm'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '定时刷新',
|
|
||||||
name: 'interval',
|
|
||||||
type: 'switch',
|
|
||||||
mode: 'horizontal',
|
|
||||||
visibleOn: 'data.initApi',
|
|
||||||
pipeIn: (value: any) => !!value,
|
|
||||||
pipeOut: (value: any) => (value ? 3000 : undefined)
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '',
|
label: '',
|
||||||
name: 'interval',
|
name: 'interval',
|
||||||
@ -563,13 +644,6 @@ export default class APIControl extends React.Component<
|
|||||||
size: 'lg',
|
size: 'lg',
|
||||||
visibleOn: '!!data.interval',
|
visibleOn: '!!data.interval',
|
||||||
placeholder: '停止定时刷新检测表达式'
|
placeholder: '停止定时刷新检测表达式'
|
||||||
// labelRemark: {
|
|
||||||
// trigger: 'hover',
|
|
||||||
// rootClose: true,
|
|
||||||
// content:
|
|
||||||
// '定时刷新一旦设置会一直刷新,除非给出表达式,条件满足后则停止刷新',
|
|
||||||
// placement: 'top'
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -589,13 +663,6 @@ export default class APIControl extends React.Component<
|
|||||||
),
|
),
|
||||||
name: 'data',
|
name: 'data',
|
||||||
mode: 'row',
|
mode: 'row',
|
||||||
// labelRemark: {
|
|
||||||
// trigger: 'hover',
|
|
||||||
// rootClose: true,
|
|
||||||
// content:
|
|
||||||
// '当没开启数据映射时,发送 API 的时候会发送尽可能多的数据,如果你想自己控制发送的数据,或者需要额外的数据处理,请开启此选项',
|
|
||||||
// placement: 'top'
|
|
||||||
// },
|
|
||||||
pipeIn: (value: any) => !!value,
|
pipeIn: (value: any) => !!value,
|
||||||
pipeOut: (value: any) => (value ? {'&': '$$'} : null)
|
pipeOut: (value: any) => (value ? {'&': '$$'} : null)
|
||||||
},
|
},
|
||||||
@ -656,7 +723,7 @@ export default class APIControl extends React.Component<
|
|||||||
|
|
||||||
{
|
{
|
||||||
placeholder: 'Value',
|
placeholder: 'Value',
|
||||||
type: 'input-text',
|
type: 'ae-DataPickerControl',
|
||||||
name: 'value'
|
name: 'value'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -669,13 +736,6 @@ export default class APIControl extends React.Component<
|
|||||||
),
|
),
|
||||||
name: 'responseData',
|
name: 'responseData',
|
||||||
mode: 'row',
|
mode: 'row',
|
||||||
// labelRemark: {
|
|
||||||
// trigger: 'hover',
|
|
||||||
// rootClose: true,
|
|
||||||
// content:
|
|
||||||
// '如果需要对返回结果做额外的数据处理,请开启此选项',
|
|
||||||
// placement: 'top'
|
|
||||||
// },
|
|
||||||
pipeIn: (value: any) => !!value,
|
pipeIn: (value: any) => !!value,
|
||||||
pipeOut: (value: any) => (value ? {'&': '$$'} : null)
|
pipeOut: (value: any) => (value ? {'&': '$$'} : null)
|
||||||
},
|
},
|
||||||
@ -772,18 +832,11 @@ export default class APIControl extends React.Component<
|
|||||||
type: 'switch',
|
type: 'switch',
|
||||||
label: tipedLabel(
|
label: tipedLabel(
|
||||||
'请求头',
|
'请求头',
|
||||||
'可以配置headers对象,添加自定义请求头'
|
'可以配置<code>headers</code>对象,添加自定义请求头'
|
||||||
),
|
),
|
||||||
name: 'headers',
|
name: 'headers',
|
||||||
mode: 'row',
|
mode: 'row',
|
||||||
className: 'm-b-xs',
|
className: 'm-b-xs',
|
||||||
// labelRemark: {
|
|
||||||
// trigger: 'hover',
|
|
||||||
// rootClose: true,
|
|
||||||
// content:
|
|
||||||
// '可以配置<code>headers</code>对象,添加自定义请求头',
|
|
||||||
// placement: 'top'
|
|
||||||
// },
|
|
||||||
pipeIn: (value: any) => !!value,
|
pipeIn: (value: any) => !!value,
|
||||||
pipeOut: (value: any) => (value ? {'': ''} : null)
|
pipeOut: (value: any) => (value ? {'': ''} : null)
|
||||||
},
|
},
|
||||||
@ -915,42 +968,103 @@ export default class APIControl extends React.Component<
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
// return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
render,
|
render,
|
||||||
className,
|
className,
|
||||||
|
footerClassName,
|
||||||
|
classPrefix,
|
||||||
|
label,
|
||||||
|
labelRemark,
|
||||||
value,
|
value,
|
||||||
footer,
|
footer,
|
||||||
border = false,
|
border = false,
|
||||||
messageDesc
|
onlyTabs = false,
|
||||||
|
messageDesc,
|
||||||
|
enablePickerMode,
|
||||||
|
disabled,
|
||||||
|
mode,
|
||||||
|
enableHighlight,
|
||||||
|
labelField = 'label',
|
||||||
|
useMobileUI,
|
||||||
|
popOverContainer,
|
||||||
|
env
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
let {apiStr, selectedItem, loading} = this.state;
|
||||||
|
selectedItem =
|
||||||
|
Array.isArray(selectedItem) && selectedItem.length !== 0
|
||||||
|
? selectedItem
|
||||||
|
: [];
|
||||||
|
const highlightLabel = selectedItem?.[0]?.[labelField] ?? '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('ae-ApiControl', className, {border})}>
|
<>
|
||||||
{this.renderHeader()}
|
<div className={cx('ae-ApiControl', className, {border})}>
|
||||||
|
{onlyTabs ? (
|
||||||
|
render('api-control-tabs', this.renderApiConfigTabs(true), {
|
||||||
|
data: normalizeApi(value)
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{this.renderHeader()}
|
||||||
|
|
||||||
<div className="ae-ApiControl-content" key="content">
|
<div className="ae-ApiControl-content" key="content">
|
||||||
<InputBox
|
<div className={cx('ae-ApiControl-input')}>
|
||||||
className="ae-ApiControl-input m-b-none"
|
{enableHighlight && highlightLabel ? (
|
||||||
value={this.state.apiStr}
|
<div className={cx('ae-ApiControl-highlight')}>
|
||||||
clearable={false}
|
{loading ? (
|
||||||
placeholder="http://"
|
<Spinner
|
||||||
onChange={(value: string) => this.handleSubmit(value, 'input')}
|
show
|
||||||
/>
|
icon="reload"
|
||||||
{render('api-control-dialog', this.renderApiDialog(), {
|
size="sm"
|
||||||
data: normalizeApi(value)
|
spinnerClassName={cx('Select-spinner')}
|
||||||
})}
|
/>
|
||||||
|
) : (
|
||||||
|
<span className={cx('ae-ApiControl-highlight-tag')}>
|
||||||
|
<span>{highlightLabel}</span>
|
||||||
|
<a
|
||||||
|
onClick={this.clearPickerValue}
|
||||||
|
className={cx('Modal-close')}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon="close"
|
||||||
|
className={cx(
|
||||||
|
'icon',
|
||||||
|
'ae-ApiControl-highlight-close'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<Input
|
||||||
|
ref={this.inputRef}
|
||||||
|
value={apiStr}
|
||||||
|
type="text"
|
||||||
|
disabled={disabled}
|
||||||
|
placeholder="http://"
|
||||||
|
onChange={this.handleSimpleInputChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{enablePickerMode ? this.renderPickerSchema() : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{render('api-control-dialog', this.renderApiDialog(), {
|
||||||
|
data: normalizeApi(value)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{Array.isArray(footer) && footer.length !== 0 ? (
|
{Array.isArray(footer) && footer.length !== 0 ? (
|
||||||
<footer className="mt-3" key="footer">
|
<footer className={cx('mt-3', footerClassName)} key="footer">
|
||||||
{render('api-control-footer', footer)}
|
{render('api-control-footer', footer)}
|
||||||
</footer>
|
</footer>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import {getEnv} from 'mobx-state-tree';
|
|||||||
import {normalizeApi, isEffectiveApi, isApiOutdated} from 'amis-core';
|
import {normalizeApi, isEffectiveApi, isApiOutdated} from 'amis-core';
|
||||||
|
|
||||||
import {autobind, isObject, anyChanged, createObject} from 'amis-editor-core';
|
import {autobind, isObject, anyChanged, createObject} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
import type {SchemaObject, SchemaCollection, SchemaApi} from 'amis/lib/Schema';
|
import type {SchemaObject, SchemaCollection, SchemaApi} from 'amis/lib/Schema';
|
||||||
import type {Api} from 'amis/lib/types';
|
import type {Api} from 'amis/lib/types';
|
||||||
|
73
packages/amis-editor/src/renderer/ColumnControl.tsx
Normal file
73
packages/amis-editor/src/renderer/ColumnControl.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* @file 表格自定义列可视化编辑控件
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import cx from 'classnames';
|
||||||
|
import findIndex from 'lodash/findIndex';
|
||||||
|
import {
|
||||||
|
FormControlProps,
|
||||||
|
FormItem,
|
||||||
|
TreeSelection
|
||||||
|
} from 'amis';
|
||||||
|
|
||||||
|
|
||||||
|
export interface ColumnControlProps extends FormControlProps {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ColumnsControlState {
|
||||||
|
columns: Array<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ColumnControl extends React.Component<
|
||||||
|
ColumnControlProps,
|
||||||
|
ColumnsControlState
|
||||||
|
> {
|
||||||
|
|
||||||
|
constructor(props: any) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
columns: this.transformColumns(props)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
transformColumns(props: any) {
|
||||||
|
const {data} = props;
|
||||||
|
return data.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(value: Array<any>) {
|
||||||
|
const {onBulkChange} = this.props;
|
||||||
|
const columns = this.state.columns.map(c => ({
|
||||||
|
...c,
|
||||||
|
toggled: findIndex(value, (v: any) => v.value === c.key) > -1
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.setState({columns});
|
||||||
|
onBulkChange && onBulkChange({columns});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {columns} = this.state;
|
||||||
|
const options = columns ? columns.map(c => ({value: c.key, label: c.title})) : [];
|
||||||
|
const value = columns ? columns.filter(c => c.toggled !== false).map(c => ({value: c.key, label: c.title})) : []
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx('ae-ColumnControl')}>
|
||||||
|
<TreeSelection
|
||||||
|
options={options}
|
||||||
|
value={value}
|
||||||
|
onChange={(v: Array<any>) => this.onChange(v)}>
|
||||||
|
</TreeSelection>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FormItem({
|
||||||
|
type: 'ae-columnControl',
|
||||||
|
renderLabel: false
|
||||||
|
})
|
||||||
|
export class ColumnControlRenderer extends ColumnControl {}
|
@ -1,37 +1,244 @@
|
|||||||
import {Icon, InputBox, SchemaVariableListPicker, FormItem} from 'amis';
|
import {
|
||||||
import type {FormControlProps} from 'amis-core';
|
Icon,
|
||||||
|
InputBox,
|
||||||
|
SchemaVariableListPicker,
|
||||||
|
FormItem,
|
||||||
|
SearchBox,
|
||||||
|
CollapseGroup,
|
||||||
|
PickerContainer,
|
||||||
|
Collapse,
|
||||||
|
Checkbox,
|
||||||
|
Spinner
|
||||||
|
} from 'amis';
|
||||||
|
import {FormControlProps, generateIcon} from 'amis-core';
|
||||||
|
import {debounce, remove} from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {autobind} from 'amis-editor-core';
|
import {
|
||||||
|
EditorManager,
|
||||||
|
EditorNodeType,
|
||||||
|
autobind,
|
||||||
|
DSField,
|
||||||
|
DSFieldGroup
|
||||||
|
} from 'amis-editor-core';
|
||||||
|
import {matchSorter} from 'match-sorter';
|
||||||
|
|
||||||
|
export interface DataBindingProps extends FormControlProps {
|
||||||
|
node: EditorNodeType;
|
||||||
|
manager: EditorManager;
|
||||||
|
samePredicate?: (a: any, b: any) => boolean;
|
||||||
|
onBindingChange?: (
|
||||||
|
value: DSField,
|
||||||
|
onBulkChange: (value: any) => void
|
||||||
|
) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DataBindingState {
|
||||||
|
filteredFields: DSFieldGroup[];
|
||||||
|
sourceFields: DSFieldGroup[];
|
||||||
|
loading: boolean;
|
||||||
|
hint: string | void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DataBindingControl extends React.Component<
|
||||||
|
DataBindingProps,
|
||||||
|
DataBindingState
|
||||||
|
> {
|
||||||
|
constructor(props: DataBindingProps) {
|
||||||
|
super(props);
|
||||||
|
this.handleSearchDebounced = debounce(this.handleSearch, 250, {
|
||||||
|
trailing: true,
|
||||||
|
leading: false
|
||||||
|
});
|
||||||
|
this.state = {
|
||||||
|
filteredFields: [],
|
||||||
|
sourceFields: [],
|
||||||
|
loading: false,
|
||||||
|
hint: undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearchDebounced;
|
||||||
|
|
||||||
export class DataBindingControl extends React.Component<FormControlProps> {
|
|
||||||
@autobind
|
@autobind
|
||||||
handleConfirm(result: {value: string; schema: any}) {
|
handleConfirm(result: {label: string; value: string}) {
|
||||||
const {manager, data} = this.props;
|
const {manager, data, onChange, onBulkChange, onBindingChange} = this.props;
|
||||||
|
|
||||||
if (result?.value) {
|
if (result?.value) {
|
||||||
this.props.onChange(`${result.value}`);
|
onChange(result.value);
|
||||||
|
onBulkChange && onBindingChange?.(result, onBulkChange);
|
||||||
manager.config?.dataBindingChange?.(result.value, data, manager);
|
manager.config?.dataBindingChange?.(result.value, data, manager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
async handlePickerOpen() {
|
handlePickerOpen() {
|
||||||
const {manager, node} = this.props;
|
const {manager, node} = this.props;
|
||||||
const withSuper = manager.config?.withSuperDataSchema ?? false;
|
|
||||||
const schemas = await manager.getContextSchemas(node.info.id, !withSuper);
|
// 如果node没变化,就不再重复加载
|
||||||
return {schemas};
|
if (this.state.sourceFields.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
sourceFields: [],
|
||||||
|
filteredFields: [],
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
|
|
||||||
|
manager
|
||||||
|
.getAvailableContextFields(node)
|
||||||
|
.then(groupedFields => {
|
||||||
|
this.setState({
|
||||||
|
sourceFields: groupedFields || [],
|
||||||
|
filteredFields: groupedFields || [],
|
||||||
|
loading: false,
|
||||||
|
hint: groupedFields ? undefined : '暂无可绑定字段'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
hint: '加载可用字段失败,请联系管理员!'
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
@autobind
|
||||||
const {classnames: cx, value, onChange, disabled} = this.props;
|
async handleSearch(keywords: string) {
|
||||||
|
this.setState({
|
||||||
|
filteredFields: matchSorter(this.state.sourceFields, keywords, {
|
||||||
|
keys: ['label', 'value', 'children']
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleSelect() {}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
className,
|
||||||
|
classnames: cx,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
samePredicate = (a, b) => a.value === b.value,
|
||||||
|
multiple,
|
||||||
|
disabled
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const {filteredFields, loading, hint} = this.state;
|
||||||
return (
|
return (
|
||||||
<SchemaVariableListPicker
|
<PickerContainer
|
||||||
onPickerOpen={this.handlePickerOpen}
|
onPickerOpen={this.handlePickerOpen}
|
||||||
|
className={className}
|
||||||
|
title="绑定字段"
|
||||||
|
bodyRender={({value, isOpened, onChange}) => {
|
||||||
|
if (!isOpened) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<Spinner
|
||||||
|
show
|
||||||
|
icon="reload"
|
||||||
|
spinnerClassName={cx('ae-DataBindingList-spinner')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hint) {
|
||||||
|
return <p className={cx('ae-DataBindingList-hint')}>{hint}</p>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx('ae-DataBindingList')}>
|
||||||
|
<div className={cx('ae-DataBindingList-searchBox')}>
|
||||||
|
<SearchBox
|
||||||
|
mini={false}
|
||||||
|
placeholder={'输入名称搜索'}
|
||||||
|
onSearch={this.handleSearchDebounced}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx('ae-DataBindingList-body')}>
|
||||||
|
<CollapseGroup
|
||||||
|
className={cx('ae-DataBindingList-collapseGroup')}
|
||||||
|
defaultActiveKey={filteredFields.map(item => item.value!)}
|
||||||
|
expandIcon={
|
||||||
|
generateIcon(
|
||||||
|
cx,
|
||||||
|
'fa fa-chevron-right ae-DataBindingList-expandIcon',
|
||||||
|
'Icon'
|
||||||
|
)!
|
||||||
|
}
|
||||||
|
expandIconPosition="right"
|
||||||
|
// accordion={true}
|
||||||
|
>
|
||||||
|
{filteredFields.map(item => (
|
||||||
|
<Collapse
|
||||||
|
className={cx('ae-DataBindingList-collapse')}
|
||||||
|
headingClassName={cx('ae-DataBindingList-collapse-title')}
|
||||||
|
bodyClassName={cx('ae-DataBindingList-collapse-body')}
|
||||||
|
propKey={item.value}
|
||||||
|
key={item.value}
|
||||||
|
header={item.label}
|
||||||
|
>
|
||||||
|
{Array.isArray(item.children) &&
|
||||||
|
item.children.length > 0 ? (
|
||||||
|
item.children.map((childItem: DSField) => {
|
||||||
|
if (multiple) {
|
||||||
|
const checked = !!value.find((i: any) =>
|
||||||
|
samePredicate(i, childItem)
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={childItem.value}
|
||||||
|
className={cx('ae-DataBindingList-item')}
|
||||||
|
onClick={() =>
|
||||||
|
onChange(
|
||||||
|
checked
|
||||||
|
? value.concat(childItem)
|
||||||
|
: remove(value, childItem)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Checkbox value={checked}>
|
||||||
|
{childItem.label}
|
||||||
|
</Checkbox>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cx('ae-DataBindingList-item', {
|
||||||
|
'is-active':
|
||||||
|
value && childItem.value === value.value
|
||||||
|
})}
|
||||||
|
onClick={() => onChange(childItem)}
|
||||||
|
key={childItem.value}
|
||||||
|
>
|
||||||
|
{childItem.label}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<p className={cx('ae-DataBindingList-hint')}>
|
||||||
|
暂无可用字段
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</Collapse>
|
||||||
|
))}
|
||||||
|
</CollapseGroup>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
value={value}
|
||||||
onConfirm={this.handleConfirm}
|
onConfirm={this.handleConfirm}
|
||||||
title="绑定变量"
|
|
||||||
>
|
>
|
||||||
{({onClick, isOpened, setState}) => {
|
{({onClick}: {onClick: (e: React.MouseEvent) => void}) => {
|
||||||
return (
|
return (
|
||||||
<InputBox
|
<InputBox
|
||||||
className="ae-InputVariable"
|
className="ae-InputVariable"
|
||||||
@ -50,7 +257,7 @@ export class DataBindingControl extends React.Component<FormControlProps> {
|
|||||||
</InputBox>
|
</InputBox>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</SchemaVariableListPicker>
|
</PickerContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,9 @@ class DataPickerControl extends React.Component<FormControlProps> {
|
|||||||
onChange={() => {}}
|
onChange={() => {}}
|
||||||
header={''}
|
header={''}
|
||||||
>
|
>
|
||||||
{({onClick, isOpened, setState}) => {
|
{({onClick}: {
|
||||||
|
onClick: (e: React.MouseEvent) => void;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<InputBox
|
<InputBox
|
||||||
className="ae-InputVariable"
|
className="ae-InputVariable"
|
||||||
|
268
packages/amis-editor/src/renderer/FeatureControl.tsx
Normal file
268
packages/amis-editor/src/renderer/FeatureControl.tsx
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/**
|
||||||
|
* @file 控制功能开关的控件,这里的功能指需要加子组件来支持的功能
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {findDOMNode} from 'react-dom';
|
||||||
|
import cx from 'classnames';
|
||||||
|
import {FormItem, Button, Icon, FormControlProps, autobind} from 'amis';
|
||||||
|
|
||||||
|
import {clone, remove} from 'lodash';
|
||||||
|
import {GoConfigControl} from './GoConfigControl';
|
||||||
|
import Sortable from 'sortablejs';
|
||||||
|
|
||||||
|
const klass = 'ae-FeatureControl';
|
||||||
|
export type FeatureOption = {
|
||||||
|
label: string;
|
||||||
|
value: any;
|
||||||
|
remove?: (data: any) => void;
|
||||||
|
/** 提供该字段表示删除后还可以再新增回来 */
|
||||||
|
add?: (data: any) => void;
|
||||||
|
isActive?: (data: any) => boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface FeatureControlProps extends FormControlProps {
|
||||||
|
className?: string;
|
||||||
|
removable?: boolean;
|
||||||
|
addable?: boolean;
|
||||||
|
addText?: string;
|
||||||
|
sortable?: boolean;
|
||||||
|
features: Array<FeatureOption> | ((schema: any) => Array<FeatureOption>);
|
||||||
|
goFeatureComp?: (item: FeatureOption) => string; // 去子组件
|
||||||
|
onSort?: (value: FeatureOption[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FeatureControlState {
|
||||||
|
/**
|
||||||
|
* 当前启用的功能
|
||||||
|
*/
|
||||||
|
inUseFeat: FeatureOption[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未启用的功能
|
||||||
|
*/
|
||||||
|
unUseFeat: FeatureOption[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class FeatureControl extends React.Component<
|
||||||
|
FeatureControlProps,
|
||||||
|
FeatureControlState
|
||||||
|
> {
|
||||||
|
constructor(props: FeatureControlProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = FeatureControl.initState(props.data, props.features);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(
|
||||||
|
nextProps: FeatureControlProps,
|
||||||
|
preState: FeatureControlState
|
||||||
|
) {
|
||||||
|
return FeatureControl.initState(
|
||||||
|
nextProps.data,
|
||||||
|
nextProps.features,
|
||||||
|
preState.inUseFeat,
|
||||||
|
preState.unUseFeat
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static initState(
|
||||||
|
data: any,
|
||||||
|
features: FeatureOption[] | ((schema: any) => Array<FeatureOption>),
|
||||||
|
lastInUseFeat?: FeatureOption[],
|
||||||
|
lastUnUseFeat?: FeatureOption[]
|
||||||
|
) {
|
||||||
|
const inUseFeat: FeatureOption[] = [];
|
||||||
|
const unUseFeat: FeatureOption[] = [];
|
||||||
|
|
||||||
|
if (!Array.isArray(features)) {
|
||||||
|
features = features(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
features.forEach(item => {
|
||||||
|
if (item.isActive == null || item.isActive?.(data)) {
|
||||||
|
inUseFeat.push(item);
|
||||||
|
} else if (item.add) {
|
||||||
|
unUseFeat.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
inUseFeat,
|
||||||
|
unUseFeat
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleRemove(item: FeatureOption, index: number) {
|
||||||
|
const {removeFeature, data, onBulkChange} = this.props;
|
||||||
|
const {inUseFeat, unUseFeat} = this.state;
|
||||||
|
|
||||||
|
item.remove?.(data);
|
||||||
|
removeFeature?.(item, data);
|
||||||
|
onBulkChange?.(data);
|
||||||
|
|
||||||
|
remove(inUseFeat, item);
|
||||||
|
item.add && unUseFeat.push(item);
|
||||||
|
|
||||||
|
this.setState({inUseFeat, unUseFeat});
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handleAdd(item: any) {
|
||||||
|
const {addFeature, data, onBulkChange} = this.props;
|
||||||
|
const {inUseFeat, unUseFeat} = this.state;
|
||||||
|
|
||||||
|
inUseFeat.push(item);
|
||||||
|
remove(unUseFeat, item);
|
||||||
|
|
||||||
|
const schema = clone(data);
|
||||||
|
item.add?.(schema);
|
||||||
|
addFeature?.(item, schema);
|
||||||
|
onBulkChange?.(schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
sortable?: Sortable;
|
||||||
|
drag?: HTMLElement | null;
|
||||||
|
@autobind
|
||||||
|
dragRef(ref: any) {
|
||||||
|
const {sortable} = this.props;
|
||||||
|
if (!sortable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.drag && ref) {
|
||||||
|
this.initDragging();
|
||||||
|
} else if (this.drag && !ref) {
|
||||||
|
this.destroyDragging();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.drag = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化拖动
|
||||||
|
*/
|
||||||
|
initDragging() {
|
||||||
|
const dom = findDOMNode(this) as HTMLElement;
|
||||||
|
this.sortable = new Sortable(
|
||||||
|
dom.querySelector(`.${klass}-features`) as HTMLElement,
|
||||||
|
{
|
||||||
|
group: 'FeatureControlGroup',
|
||||||
|
animation: 150,
|
||||||
|
handle: `.${klass}Item-dragBar`,
|
||||||
|
ghostClass: `${klass}Item-dragging`,
|
||||||
|
onEnd: (e: any) => {
|
||||||
|
// 没有移动
|
||||||
|
if (e.newIndex === e.oldIndex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 换回来
|
||||||
|
const parent = e.to as HTMLElement;
|
||||||
|
if (
|
||||||
|
e.newIndex < e.oldIndex &&
|
||||||
|
e.oldIndex < parent.childNodes.length - 1
|
||||||
|
) {
|
||||||
|
parent.insertBefore(e.item, parent.childNodes[e.oldIndex + 1]);
|
||||||
|
} else if (e.oldIndex < parent.childNodes.length - 1) {
|
||||||
|
parent.insertBefore(e.item, parent.childNodes[e.oldIndex]);
|
||||||
|
} else {
|
||||||
|
parent.appendChild(e.item);
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = this.state.inUseFeat.concat();
|
||||||
|
value[e.oldIndex] = value.splice(e.newIndex, 1, value[e.oldIndex])[0];
|
||||||
|
this.setState({inUseFeat: value}, () => {
|
||||||
|
this.props.onSort?.(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拖动的销毁
|
||||||
|
*/
|
||||||
|
destroyDragging() {
|
||||||
|
this.sortable && this.sortable.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderItem(item: FeatureOption, index: number) {
|
||||||
|
const {sortable, goFeatureComp, node, manager} = this.props;
|
||||||
|
|
||||||
|
let content = null;
|
||||||
|
|
||||||
|
if (goFeatureComp) {
|
||||||
|
content = (
|
||||||
|
// @ts-ignore
|
||||||
|
<GoConfigControl
|
||||||
|
className={cx(`${klass}Item-go`)}
|
||||||
|
label={item.label}
|
||||||
|
manager={manager}
|
||||||
|
compId={() => goFeatureComp(item)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
content = <div className={cx(`${klass}Item-label`)}>{item.label}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li className={klass + 'Item'} key={index}>
|
||||||
|
{sortable && (
|
||||||
|
<a className={klass + 'Item-dragBar'}>
|
||||||
|
<Icon icon="drag-bar" className="icon" />
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
{content}
|
||||||
|
<Button
|
||||||
|
className={klass + 'Item-action'}
|
||||||
|
onClick={() => this.handleRemove(item, index)}
|
||||||
|
>
|
||||||
|
<Icon icon="delete-btn" className="icon" />
|
||||||
|
</Button>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderAction() {
|
||||||
|
const {addable, addText, render} = this.props;
|
||||||
|
if (!addable) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return render('action', {
|
||||||
|
type: 'dropdown-button',
|
||||||
|
closeOnClick: true,
|
||||||
|
label: '添加' || addText,
|
||||||
|
className: `${klass}-action`,
|
||||||
|
btnClassName: `${klass}-action--btn`,
|
||||||
|
menuClassName: `${klass}-action--menus`,
|
||||||
|
buttons: this.state.unUseFeat.map(item => {
|
||||||
|
return {
|
||||||
|
label: item.label,
|
||||||
|
onClick: () => this.handleAdd(item)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {className} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx('ae-FeatureControl', className)}>
|
||||||
|
<ul className={cx('ae-FeatureControl-features')} ref={this.dragRef}>
|
||||||
|
{this.state.inUseFeat.map((item, index) =>
|
||||||
|
this.renderItem(item, index)
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{this.renderAction()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FormItem({
|
||||||
|
type: 'ae-feature-control'
|
||||||
|
})
|
||||||
|
export class FeatureControlRenderer extends FeatureControl {}
|
@ -248,7 +248,14 @@ export default class FormulaControl extends React.Component<
|
|||||||
const {node, manager} = this.props.formProps || this.props;
|
const {node, manager} = this.props.formProps || this.props;
|
||||||
await manager?.getContextSchemas(node);
|
await manager?.getContextSchemas(node);
|
||||||
const dataPropsAsOptions = manager?.dataSchema?.getDataPropsAsOptions();
|
const dataPropsAsOptions = manager?.dataSchema?.getDataPropsAsOptions();
|
||||||
return dataPropsAsOptions || [];
|
|
||||||
|
if (dataPropsAsOptions) {
|
||||||
|
return dataPropsAsOptions.map((item: any) => ({
|
||||||
|
selectMode: 'tree',
|
||||||
|
...item
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
@ -331,9 +338,7 @@ export default class FormulaControl extends React.Component<
|
|||||||
@autobind
|
@autobind
|
||||||
renderFormulaValue(item: any) {
|
renderFormulaValue(item: any) {
|
||||||
const html = {__html: item.html};
|
const html = {__html: item.html};
|
||||||
{
|
// bca-disable-line
|
||||||
/* bca-disable-next-line */
|
|
||||||
}
|
|
||||||
return <span dangerouslySetInnerHTML={html}></span>;
|
return <span dangerouslySetInnerHTML={html}></span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +457,13 @@ export default class FormulaControl extends React.Component<
|
|||||||
)}
|
)}
|
||||||
<PickerContainer
|
<PickerContainer
|
||||||
showTitle={false}
|
showTitle={false}
|
||||||
bodyRender={({onClose, value, onChange}) => {
|
bodyRender={({
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}: {
|
||||||
|
onChange: (value: any) => void;
|
||||||
|
value: any;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<FormulaEditor
|
<FormulaEditor
|
||||||
{...rest}
|
{...rest}
|
||||||
@ -470,7 +481,7 @@ export default class FormulaControl extends React.Component<
|
|||||||
onConfirm={this.handleConfirm}
|
onConfirm={this.handleConfirm}
|
||||||
size="md"
|
size="md"
|
||||||
>
|
>
|
||||||
{({onClick, isOpened}) => (
|
{({onClick}: {onClick: (e: React.MouseEvent) => void}) => (
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
tooltip={'点击配置表达式'}
|
tooltip={'点击配置表达式'}
|
||||||
|
49
packages/amis-editor/src/renderer/GoConfigControl.tsx
Normal file
49
packages/amis-editor/src/renderer/GoConfigControl.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* @file 进行详细配置
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import cx from 'classnames';
|
||||||
|
import {Renderer, toast} from 'amis';
|
||||||
|
|
||||||
|
import {EditorManager} from 'amis-editor-core';
|
||||||
|
import {autobind, FormControlProps} from 'amis-core';
|
||||||
|
|
||||||
|
export interface GoCongigControlProps extends FormControlProps {
|
||||||
|
label: string;
|
||||||
|
compId: string | ((data: any) => string);
|
||||||
|
manager: EditorManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GoConfigControl extends React.PureComponent<
|
||||||
|
GoCongigControlProps,
|
||||||
|
any
|
||||||
|
> {
|
||||||
|
@autobind
|
||||||
|
onClick() {
|
||||||
|
const {data: ctx = {}, compId, manager} = this.props;
|
||||||
|
const id = typeof compId === 'string' ? compId : compId(ctx);
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
toast.error('未找到对应组件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
manager.setActiveId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {className, label, data: ctx = {}} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cx('ae-GoConfig', className)} onClick={this.onClick}>
|
||||||
|
{label}
|
||||||
|
<div className={cx('ae-GoConfig-trigger')}>去编辑</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Renderer({
|
||||||
|
type: 'ae-go-config'
|
||||||
|
})
|
||||||
|
export class GoConfigControlRenderer extends GoConfigControl {}
|
@ -20,7 +20,7 @@ import {value2array} from 'amis-ui/lib/components/Select';
|
|||||||
|
|
||||||
import {autobind} from 'amis-editor-core';
|
import {autobind} from 'amis-editor-core';
|
||||||
import {getSchemaTpl} from 'amis-editor-core';
|
import {getSchemaTpl} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
import type {Option} from 'amis';
|
import type {Option} from 'amis';
|
||||||
import type {FormControlProps} from 'amis-core';
|
import type {FormControlProps} from 'amis-core';
|
||||||
@ -396,33 +396,29 @@ export default class OptionControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
const {
|
const {render, label, labelRemark, useMobileUI, env, popOverContainer} =
|
||||||
render,
|
this.props;
|
||||||
label,
|
|
||||||
labelRemark,
|
|
||||||
useMobileUI,
|
|
||||||
env,
|
|
||||||
popOverContainer
|
|
||||||
} = this.props;
|
|
||||||
const classPrefix = env?.theme?.classPrefix;
|
const classPrefix = env?.theme?.classPrefix;
|
||||||
const {source} = this.state;
|
const {source} = this.state;
|
||||||
const optionSourceList = ([
|
const optionSourceList = (
|
||||||
{
|
[
|
||||||
label: '自定义选项',
|
{
|
||||||
value: 'custom'
|
label: '自定义选项',
|
||||||
},
|
value: 'custom'
|
||||||
{
|
},
|
||||||
label: '接口获取',
|
{
|
||||||
value: 'api'
|
label: '接口获取',
|
||||||
}
|
value: 'api'
|
||||||
// {
|
}
|
||||||
// label: '表单实体',
|
// {
|
||||||
// value: 'form'
|
// label: '表单实体',
|
||||||
// }
|
// value: 'form'
|
||||||
] as Array<{
|
// }
|
||||||
label: string;
|
] as Array<{
|
||||||
value: 'custom' | 'api' | 'form';
|
label: string;
|
||||||
}>).map(item => ({
|
value: 'custom' | 'api' | 'form';
|
||||||
|
}>
|
||||||
|
).map(item => ({
|
||||||
...item,
|
...item,
|
||||||
onClick: () => this.handleSourceChange(item.value)
|
onClick: () => this.handleSourceChange(item.value)
|
||||||
}));
|
}));
|
||||||
@ -586,7 +582,7 @@ export default class OptionControl extends React.Component<
|
|||||||
value={label}
|
value={label}
|
||||||
placeholder="请输入文本/值"
|
placeholder="请输入文本/值"
|
||||||
clearable={false}
|
clearable={false}
|
||||||
onChange={value => this.handleEditLabel(index, value)}
|
onChange={(value: string) => this.handleEditLabel(index, value)}
|
||||||
/>
|
/>
|
||||||
{amisRender({
|
{amisRender({
|
||||||
type: 'dropdown-button',
|
type: 'dropdown-button',
|
||||||
@ -636,8 +632,7 @@ export default class OptionControl extends React.Component<
|
|||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl:
|
tpl: '每个选项单列一行,将所有值不重复的项加为新的选项;<br/>每行可通过空格来分别设置label和value,例:"张三 zhangsan"'
|
||||||
'每个选项单列一行,将所有值不重复的项加为新的选项;<br/>每行可通过空格来分别设置label和value,例:"张三 zhangsan"'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
showIcon: true,
|
showIcon: true,
|
||||||
@ -700,6 +695,7 @@ export default class OptionControl extends React.Component<
|
|||||||
getSchemaTpl('apiControl', {
|
getSchemaTpl('apiControl', {
|
||||||
label: '接口',
|
label: '接口',
|
||||||
name: 'source',
|
name: 'source',
|
||||||
|
mode: 'normal',
|
||||||
className: 'ae-ExtendMore',
|
className: 'ae-ExtendMore',
|
||||||
visibleOn: 'data.autoComplete !== false',
|
visibleOn: 'data.autoComplete !== false',
|
||||||
value: api,
|
value: api,
|
||||||
|
@ -1,277 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file 浮窗编辑
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import {findDOMNode} from 'react-dom';
|
|
||||||
import cx from 'classnames';
|
|
||||||
import {FormItem, Button, Overlay, PopOver, Icon, Switch} from 'amis';
|
|
||||||
|
|
||||||
import {isObject, autobind} from 'amis-editor-core';
|
|
||||||
|
|
||||||
import type {Action} from 'amis/lib/types';
|
|
||||||
import type {IScopedContext} from 'amis-core';
|
|
||||||
|
|
||||||
import type {FormControlProps} from 'amis-core';
|
|
||||||
import type {FormSchema} from 'amis/lib/Schema';
|
|
||||||
import {Offset} from 'amis-core/lib/components/PopOver';
|
|
||||||
|
|
||||||
export interface PopoverEditProps extends FormControlProps {
|
|
||||||
className?: string;
|
|
||||||
popOverclassName?: string;
|
|
||||||
btnLabel?: string;
|
|
||||||
btnIcon?: string;
|
|
||||||
iconPosition?: 'right' | 'left';
|
|
||||||
mode: 'popover' | 'dialog';
|
|
||||||
form: Omit<FormSchema, 'type'>;
|
|
||||||
rootClose?: boolean;
|
|
||||||
placement?: string;
|
|
||||||
offset?: ((clip: object, offset: object) => Offset) | Offset;
|
|
||||||
style?: object;
|
|
||||||
overlay?: boolean;
|
|
||||||
container?: React.ReactNode | Function;
|
|
||||||
target?: React.ReactNode | Function;
|
|
||||||
trueValue?: any;
|
|
||||||
falseValue?: any;
|
|
||||||
enableEdit?: boolean;
|
|
||||||
removable?: boolean;
|
|
||||||
onClose: (e: React.UIEvent<any> | void) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PopoverEditState {
|
|
||||||
/**
|
|
||||||
* 是否展示编辑窗口
|
|
||||||
*/
|
|
||||||
show: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否开启编辑
|
|
||||||
*/
|
|
||||||
checked: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PopoverEdit extends React.Component<
|
|
||||||
PopoverEditProps,
|
|
||||||
PopoverEditState
|
|
||||||
> {
|
|
||||||
static defaultProps: Pick<
|
|
||||||
PopoverEditProps,
|
|
||||||
| 'btnIcon'
|
|
||||||
| 'iconPosition'
|
|
||||||
| 'container'
|
|
||||||
| 'placement'
|
|
||||||
| 'overlay'
|
|
||||||
| 'rootClose'
|
|
||||||
| 'mode'
|
|
||||||
| 'trueValue'
|
|
||||||
| 'falseValue'
|
|
||||||
| 'enableEdit'
|
|
||||||
> = {
|
|
||||||
btnIcon: 'pencil',
|
|
||||||
iconPosition: 'right',
|
|
||||||
container: document.body,
|
|
||||||
placement: 'left',
|
|
||||||
overlay: true,
|
|
||||||
rootClose: false,
|
|
||||||
mode: 'popover',
|
|
||||||
trueValue: true,
|
|
||||||
falseValue: false,
|
|
||||||
enableEdit: true
|
|
||||||
};
|
|
||||||
|
|
||||||
overlay: HTMLElement | null;
|
|
||||||
|
|
||||||
constructor(props: PopoverEditProps) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
show: false,
|
|
||||||
checked: !!props.value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
overlayRef(ref: any) {
|
|
||||||
this.overlay = ref ? (findDOMNode(ref) as HTMLElement) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
openPopover() {
|
|
||||||
this.setState({show: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
closePopover() {
|
|
||||||
this.setState({show: false});
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
handleDelete(e: React.UIEvent<any> | void) {
|
|
||||||
const {onDelete} = this.props;
|
|
||||||
|
|
||||||
onDelete && onDelete(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
handleSwitchChange(checked: boolean) {
|
|
||||||
const {onChange, enableEdit} = this.props;
|
|
||||||
|
|
||||||
this.setState({checked});
|
|
||||||
|
|
||||||
if (!enableEdit) {
|
|
||||||
onChange && onChange(checked);
|
|
||||||
} else {
|
|
||||||
// undefined字段会从schema中删除
|
|
||||||
!checked && onChange && onChange(undefined);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
handleSubmit(values: any, action: any) {
|
|
||||||
const {onChange} = this.props;
|
|
||||||
|
|
||||||
onChange && onChange(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
handleAction(
|
|
||||||
e: React.UIEvent<any> | void,
|
|
||||||
action: Action,
|
|
||||||
data: object,
|
|
||||||
throwErrors: boolean = false,
|
|
||||||
delegate?: IScopedContext
|
|
||||||
) {
|
|
||||||
const {onClose} = this.props;
|
|
||||||
|
|
||||||
if (action.actionType === 'close') {
|
|
||||||
this.setState({show: false});
|
|
||||||
onClose && onClose(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderPopover() {
|
|
||||||
const {
|
|
||||||
render,
|
|
||||||
popOverclassName,
|
|
||||||
overlay,
|
|
||||||
offset,
|
|
||||||
target,
|
|
||||||
container,
|
|
||||||
placement,
|
|
||||||
rootClose,
|
|
||||||
style,
|
|
||||||
title,
|
|
||||||
label,
|
|
||||||
form,
|
|
||||||
name,
|
|
||||||
data: ctx
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Overlay
|
|
||||||
show
|
|
||||||
rootClose={rootClose}
|
|
||||||
placement={placement}
|
|
||||||
target={target || this.overlay}
|
|
||||||
container={container}
|
|
||||||
>
|
|
||||||
<PopOver
|
|
||||||
className={cx('ae-PopoverEdit-popover', popOverclassName)}
|
|
||||||
placement={placement}
|
|
||||||
overlay={overlay}
|
|
||||||
offset={offset}
|
|
||||||
style={style}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
<p className="ae-PopoverEdit-title">{title || label}</p>
|
|
||||||
<a onClick={this.closePopover} className="ae-PopoverEdit-close">
|
|
||||||
<Icon icon="close" className="icon" />
|
|
||||||
</a>
|
|
||||||
</header>
|
|
||||||
{isObject(form)
|
|
||||||
? render(
|
|
||||||
'popover-edit-form',
|
|
||||||
{
|
|
||||||
type: 'form',
|
|
||||||
wrapWithPanel: false,
|
|
||||||
panelClassName: 'border-none shadow-none mb-0',
|
|
||||||
bodyClassName: 'p-none',
|
|
||||||
actionsClassName: 'border-none mt-2.5',
|
|
||||||
wrapperComponent: 'div',
|
|
||||||
mode: 'horizontal',
|
|
||||||
autoFocus: true,
|
|
||||||
formLazyChange: true,
|
|
||||||
preventEnterSubmit: true,
|
|
||||||
submitOnChange: true,
|
|
||||||
data: ctx && name ? ctx?.[name] : {},
|
|
||||||
...form
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onSubmit: this.handleSubmit
|
|
||||||
}
|
|
||||||
)
|
|
||||||
: null}
|
|
||||||
</PopOver>
|
|
||||||
</Overlay>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
render,
|
|
||||||
removable,
|
|
||||||
btnIcon,
|
|
||||||
btnLabel,
|
|
||||||
iconPosition,
|
|
||||||
disabled,
|
|
||||||
enableEdit,
|
|
||||||
className
|
|
||||||
} = this.props;
|
|
||||||
const {show, checked} = this.state;
|
|
||||||
const btnLabelNode = btnLabel ? <span>{btnLabel}</span> : null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={cx('ae-PopoverEditControl', className)}>
|
|
||||||
{enableEdit && checked && !disabled ? (
|
|
||||||
<Button
|
|
||||||
level="link"
|
|
||||||
size="sm"
|
|
||||||
ref={this.overlayRef}
|
|
||||||
onClick={this.openPopover}
|
|
||||||
>
|
|
||||||
{iconPosition === 'right' ? (
|
|
||||||
<>
|
|
||||||
{btnLabelNode}
|
|
||||||
<Icon icon={btnIcon} className="icon" />
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Icon icon={btnIcon} className="icon" />
|
|
||||||
{btnLabelNode}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{removable ? (
|
|
||||||
<Button level="link" size="sm" onClick={this.handleDelete}>
|
|
||||||
<Icon icon="delete-btn" className="icon" />
|
|
||||||
</Button>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<Switch
|
|
||||||
value={checked}
|
|
||||||
onChange={this.handleSwitchChange}
|
|
||||||
disabled={disabled}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{show ? this.renderPopover() : null}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@FormItem({
|
|
||||||
type: 'popover-edit'
|
|
||||||
})
|
|
||||||
export class PopoverEditRenderer extends PopoverEdit {}
|
|
@ -169,7 +169,7 @@ export default class SwitchMore extends React.Component<
|
|||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
handleSwitchChange(checked: boolean) {
|
handleSwitchChange(checked: boolean) {
|
||||||
const {onBulkChange, onChange, bulk, defaultData, name} = this.props;
|
const {onBulkChange, onChange, bulk, defaultData, name, pipeOut} = this.props;
|
||||||
|
|
||||||
this.setState({checked});
|
this.setState({checked});
|
||||||
|
|
||||||
@ -179,19 +179,30 @@ export default class SwitchMore extends React.Component<
|
|||||||
if (checked) {
|
if (checked) {
|
||||||
let data = defaultData ? {...defaultData} : {};
|
let data = defaultData ? {...defaultData} : {};
|
||||||
name && (data[name] = true);
|
name && (data[name] = true);
|
||||||
|
if (pipeOut) {
|
||||||
|
data = pipeOut(data);
|
||||||
|
}
|
||||||
onBulkChange && onBulkChange(data);
|
onBulkChange && onBulkChange(data);
|
||||||
}
|
}
|
||||||
// 取消选中后,讲所有字段重置
|
// 取消选中后,讲所有字段重置
|
||||||
else {
|
else {
|
||||||
const values = fromPairs(
|
let values = fromPairs(
|
||||||
this.getFormItemNames().map(i => [i, undefined])
|
this.getFormItemNames().map(i => [i, undefined])
|
||||||
);
|
);
|
||||||
name && (values[name] = false);
|
name && (values[name] = false);
|
||||||
|
if (pipeOut) {
|
||||||
|
values = pipeOut(values);
|
||||||
|
}
|
||||||
onBulkChange && onBulkChange(values);
|
onBulkChange && onBulkChange(values);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onChange(checked ? defaultData || true : undefined);
|
|
||||||
|
let data = checked ? defaultData || true : undefined;
|
||||||
|
if (pipeOut) {
|
||||||
|
data = pipeOut(data);
|
||||||
|
}
|
||||||
|
onChange(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
|
@ -8,7 +8,7 @@ import {render, Button, Switch} from 'amis';
|
|||||||
|
|
||||||
import {autobind} from 'amis-editor-core';
|
import {autobind} from 'amis-editor-core';
|
||||||
import {Validator} from '../validator';
|
import {Validator} from '../validator';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
import {SchemaCollection} from 'amis/lib/Schema';
|
import {SchemaCollection} from 'amis/lib/Schema';
|
||||||
|
|
||||||
export type ValidatorData = {
|
export type ValidatorData = {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import {setSchemaTpl, getSchemaTpl} from 'amis-editor-core';
|
import {setSchemaTpl, getSchemaTpl, tipedLabel} from 'amis-editor-core';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {buildApi, Html} from 'amis';
|
import {buildApi, Html} from 'amis';
|
||||||
|
import {get} from 'lodash';
|
||||||
|
|
||||||
setSchemaTpl('api', (patch: any = {}) => {
|
setSchemaTpl('api', (patch: any = {}) => {
|
||||||
const {name, label, value, description, sampleBuilder, ...rest} = patch;
|
const {name, label, value, description, sampleBuilder, apiDesc, ...rest} =
|
||||||
|
patch;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'container',
|
type: 'container',
|
||||||
@ -13,21 +15,25 @@ setSchemaTpl('api', (patch: any = {}) => {
|
|||||||
label: label || 'API',
|
label: label || 'API',
|
||||||
labelRemark: sampleBuilder
|
labelRemark: sampleBuilder
|
||||||
? {
|
? {
|
||||||
icon: '',
|
label: false,
|
||||||
label: '示例',
|
|
||||||
title: '接口返回示例',
|
title: '接口返回示例',
|
||||||
|
icon: 'fas fa-code',
|
||||||
|
className: 'm-l-xs ae-ApiSample-icon',
|
||||||
tooltipClassName: 'ae-ApiSample-tooltip',
|
tooltipClassName: 'ae-ApiSample-tooltip',
|
||||||
render: (data: any) => (
|
children: () => {
|
||||||
<Html
|
return (
|
||||||
className="ae-ApiSample"
|
<Html
|
||||||
inline={false}
|
className="ae-ApiSample"
|
||||||
html={`
|
inline={false}
|
||||||
<pre><code>${sampleBuilder(data)}</code></pre>
|
html={`<pre><code>${sampleBuilder()}</code></pre>${
|
||||||
`}
|
apiDesc
|
||||||
/>
|
? `<span class="ae-ApiSample-desc">${apiDesc}</span>`
|
||||||
),
|
: ''
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
trigger: 'click',
|
trigger: 'click',
|
||||||
className: 'm-l-xs',
|
|
||||||
rootClose: true,
|
rootClose: true,
|
||||||
placement: 'left'
|
placement: 'left'
|
||||||
}
|
}
|
||||||
@ -166,6 +172,7 @@ setSchemaTpl('api', (patch: any = {}) => {
|
|||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
renderLabel: false,
|
renderLabel: false,
|
||||||
visibleOn: 'this.data',
|
visibleOn: 'this.data',
|
||||||
|
valueType: 'ae-DataPickerControl',
|
||||||
descriptionClassName: 'help-block text-xs m-b-none',
|
descriptionClassName: 'help-block text-xs m-b-none',
|
||||||
description:
|
description:
|
||||||
'<p>当没开启数据映射时,发送数据自动切成白名单模式,配置啥发送啥,请绑定数据。如:<code>{"a": "\\${a}", "b": 2}</code></p><p>如果希望在默认的基础上定制,请先添加一个 Key 为 `&` Value 为 `\\$$` 作为第一行。</p><div>当值为 <code>__undefined</code>时,表示删除对应的字段,可以结合<code>{"&": "\\$$"}</code>来达到黑名单效果。</div>'
|
'<p>当没开启数据映射时,发送数据自动切成白名单模式,配置啥发送啥,请绑定数据。如:<code>{"a": "\\${a}", "b": 2}</code></p><p>如果希望在默认的基础上定制,请先添加一个 Key 为 `&` Value 为 `\\$$` 作为第一行。</p><div>当值为 <code>__undefined</code>时,表示删除对应的字段,可以结合<code>{"&": "\\$$"}</code>来达到黑名单效果。</div>'
|
||||||
@ -346,55 +353,66 @@ setSchemaTpl('apiString', {
|
|||||||
placeholder: 'http://'
|
placeholder: 'http://'
|
||||||
});
|
});
|
||||||
|
|
||||||
setSchemaTpl('initFetch', {
|
setSchemaTpl(
|
||||||
type: 'group',
|
'initFetch',
|
||||||
label: '是否初始加载',
|
(overrides: {visibleOn?: string; name?: string} = {}) => {
|
||||||
visibleOn: 'this.initApi',
|
const visibleOn = get(overrides, 'visibleOn', 'this.initApi');
|
||||||
direction: 'vertical',
|
const fieldName = get(overrides, 'name', 'initFetch');
|
||||||
className: 'm-b-none',
|
const label = get(overrides, 'label', '是否初始加载');
|
||||||
labelRemark: {
|
|
||||||
trigger: 'click',
|
return {
|
||||||
rootClose: true,
|
type: 'group',
|
||||||
className: 'm-l-xs',
|
label: tipedLabel(
|
||||||
content:
|
label,
|
||||||
'当配置初始化接口后,组件初始就会拉取接口数据,可以通过以下配置修改。',
|
'当配置初始化接口后,组件初始就会拉取接口数据,可以通过以下配置修改。'
|
||||||
placement: 'left'
|
),
|
||||||
},
|
visibleOn,
|
||||||
body: [
|
direction: 'vertical',
|
||||||
{
|
body: [
|
||||||
name: 'initFetch',
|
|
||||||
type: 'radios',
|
|
||||||
inline: true,
|
|
||||||
onChange: () => {},
|
|
||||||
// pipeIn: (value:any) => typeof value === 'boolean' ? value : '1'
|
|
||||||
options: [
|
|
||||||
{
|
{
|
||||||
label: '是',
|
name: fieldName,
|
||||||
value: true
|
type: 'radios',
|
||||||
|
inline: true,
|
||||||
|
onChange: () => {},
|
||||||
|
// pipeIn: (value:any) => typeof value === 'boolean' ? value : '1'
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '是',
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '否',
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
label: '表达式',
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
getSchemaTpl('valueFormula', {
|
||||||
label: '否',
|
label: '',
|
||||||
value: false
|
name: `${fieldName}On`,
|
||||||
},
|
autoComplete: false,
|
||||||
|
visibleOn: `typeof this.${fieldName} !== "boolean"`,
|
||||||
{
|
placeholder: '如:this.id 表示有 id 值时初始加载',
|
||||||
label: '表达式',
|
className: 'm-t-n-sm'
|
||||||
value: ''
|
})
|
||||||
}
|
// {
|
||||||
|
// name: `${fieldName}On`,
|
||||||
|
// autoComplete: false,
|
||||||
|
// visibleOn: `typeof this.${fieldName} !== "boolean"`,
|
||||||
|
// type: 'input-text',
|
||||||
|
// placeholder: '如:this.id 表示有 id 值时初始加载',
|
||||||
|
// className: 'm-t-n-sm'
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
},
|
};
|
||||||
|
}
|
||||||
{
|
);
|
||||||
name: 'initFetchOn',
|
|
||||||
autoComplete: false,
|
|
||||||
visibleOn: 'typeof this.initFetch !== "boolean"',
|
|
||||||
type: 'input-text',
|
|
||||||
placeholder: '如:this.id 表示有 id 值时初始加载',
|
|
||||||
className: 'm-t-n-sm'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
setSchemaTpl('proxy', {
|
setSchemaTpl('proxy', {
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
@ -409,31 +427,35 @@ setSchemaTpl('proxy', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setSchemaTpl('apiControl', (patch: any = {}) => {
|
setSchemaTpl('apiControl', (patch: any = {}) => {
|
||||||
const {name, label, value, description, sampleBuilder, ...rest} = patch;
|
const {name, label, value, description, sampleBuilder, apiDesc, ...rest} =
|
||||||
|
patch;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'ae-apiControl',
|
type: 'ae-apiControl',
|
||||||
label,
|
label,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
mode: 'normal',
|
|
||||||
labelRemark: sampleBuilder
|
labelRemark: sampleBuilder
|
||||||
? {
|
? {
|
||||||
icon: '',
|
label: false,
|
||||||
label: '示例',
|
|
||||||
title: '接口返回示例',
|
title: '接口返回示例',
|
||||||
|
icon: 'fas fa-code',
|
||||||
|
className: 'm-l-xs ae-ApiSample-icon',
|
||||||
tooltipClassName: 'ae-ApiSample-tooltip',
|
tooltipClassName: 'ae-ApiSample-tooltip',
|
||||||
render: (data: any) => (
|
children: () => {
|
||||||
<Html
|
return (
|
||||||
className="ae-ApiSample"
|
<Html
|
||||||
inline={false}
|
className="ae-ApiSample"
|
||||||
html={`
|
inline={false}
|
||||||
<pre><code>${sampleBuilder(data)}</code></pre>
|
html={`<pre><code>${sampleBuilder()}</code></pre>${
|
||||||
`}
|
apiDesc
|
||||||
/>
|
? `<span class="ae-ApiSample-desc">${apiDesc}</span>`
|
||||||
),
|
: ''
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
trigger: 'click',
|
trigger: 'click',
|
||||||
className: 'm-l-xs',
|
|
||||||
rootClose: true,
|
rootClose: true,
|
||||||
placement: 'left'
|
placement: 'left'
|
||||||
}
|
}
|
||||||
@ -442,6 +464,50 @@ setSchemaTpl('apiControl', (patch: any = {}) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setSchemaTpl('interval', (more: any = {}) => ({
|
||||||
|
type: 'ae-switch-more',
|
||||||
|
label: '定时刷新',
|
||||||
|
name: 'interval',
|
||||||
|
formType: 'extend',
|
||||||
|
bulk: true,
|
||||||
|
mode: 'normal',
|
||||||
|
form: {
|
||||||
|
body: [
|
||||||
|
getSchemaTpl('withUnit', {
|
||||||
|
label: '刷新间隔',
|
||||||
|
name: 'interval',
|
||||||
|
control: {
|
||||||
|
type: 'input-number',
|
||||||
|
name: 'interval',
|
||||||
|
value: 1000
|
||||||
|
},
|
||||||
|
unit: '毫秒'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...more
|
||||||
|
}));
|
||||||
|
|
||||||
|
setSchemaTpl('silentPolling', () =>
|
||||||
|
getSchemaTpl('switch', {
|
||||||
|
label: tipedLabel('静默刷新', '设置自动定时刷新时是否显示loading'),
|
||||||
|
name: 'silentPolling',
|
||||||
|
visibleOn: '!!this.interval'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
setSchemaTpl('stopAutoRefreshWhen', (extra: any = {}) =>
|
||||||
|
getSchemaTpl('valueFormula', {
|
||||||
|
name: 'stopAutoRefreshWhen',
|
||||||
|
label: tipedLabel(
|
||||||
|
'定时刷新停止',
|
||||||
|
'定时刷新一旦设置会一直刷新,除非给出表达式,条件满足后则停止刷新'
|
||||||
|
),
|
||||||
|
visibleOn: '!!this.interval',
|
||||||
|
...extra
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口控件
|
* 接口控件
|
||||||
*/
|
*/
|
||||||
|
@ -2,9 +2,11 @@ import {
|
|||||||
setSchemaTpl,
|
setSchemaTpl,
|
||||||
getSchemaTpl,
|
getSchemaTpl,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
isObject
|
isObject,
|
||||||
|
tipedLabel,
|
||||||
|
DSField
|
||||||
} from 'amis-editor-core';
|
} from 'amis-editor-core';
|
||||||
import {remarkTpl, tipedLabel} from '../component/BaseControl';
|
import {remarkTpl} from '../component/BaseControl';
|
||||||
import {SchemaObject} from 'amis/lib/Schema';
|
import {SchemaObject} from 'amis/lib/Schema';
|
||||||
import flatten from 'lodash/flatten';
|
import flatten from 'lodash/flatten';
|
||||||
import {InputComponentName} from '../component/InputComponentName';
|
import {InputComponentName} from '../component/InputComponentName';
|
||||||
@ -22,13 +24,46 @@ setSchemaTpl('switch', {
|
|||||||
inputClassName: 'is-inline '
|
inputClassName: 'is-inline '
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分割线
|
||||||
|
*/
|
||||||
|
setSchemaTpl('divider', {
|
||||||
|
type: 'divider',
|
||||||
|
className: 'mx-0'
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带单位的控件
|
||||||
|
*/
|
||||||
|
setSchemaTpl(
|
||||||
|
'withUnit',
|
||||||
|
(config: {name: string; label: string; control: any; unit: string}) => {
|
||||||
|
return {
|
||||||
|
type: 'input-group',
|
||||||
|
name: config.name,
|
||||||
|
label: config.label,
|
||||||
|
body: [
|
||||||
|
config.control,
|
||||||
|
{
|
||||||
|
type: 'tpl',
|
||||||
|
addOnclassName: 'border-0 bg-none',
|
||||||
|
tpl: config.unit
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单项字段name
|
* 表单项字段name
|
||||||
*/
|
*/
|
||||||
setSchemaTpl('formItemName', {
|
setSchemaTpl('formItemName', {
|
||||||
label: '字段名',
|
label: '字段名',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
type: 'ae-DataBindingControl'
|
type: 'ae-DataBindingControl',
|
||||||
|
onBindingChange(field: DSField, onBulkChange: (value: any) => void) {
|
||||||
|
onBulkChange(field.resolveEditSchema?.() || {label: field.label});
|
||||||
|
}
|
||||||
// validations: {
|
// validations: {
|
||||||
// matchRegexp: /^[a-z\$][a-z0-0\-_]*$/i
|
// matchRegexp: /^[a-z\$][a-z0-0\-_]*$/i
|
||||||
// },
|
// },
|
||||||
@ -38,37 +73,45 @@ setSchemaTpl('formItemName', {
|
|||||||
// validateOnChange: false
|
// validateOnChange: false
|
||||||
});
|
});
|
||||||
|
|
||||||
setSchemaTpl('formItemMode', {
|
setSchemaTpl(
|
||||||
label: '布局',
|
'formItemMode',
|
||||||
name: 'mode',
|
(config: {
|
||||||
type: 'button-group-select',
|
// 是不是独立表单,没有可以集成的内容
|
||||||
option: '继承',
|
isForm: boolean;
|
||||||
horizontal: {
|
}) => ({
|
||||||
left: 2,
|
label: '布局',
|
||||||
justify: true
|
name: 'mode',
|
||||||
},
|
type: 'button-group-select',
|
||||||
// className: 'w-full',
|
option: '继承',
|
||||||
pipeIn: defaultValue(''),
|
horizontal: {
|
||||||
options: [
|
left: 2,
|
||||||
{
|
justify: true
|
||||||
label: '内联',
|
|
||||||
value: 'inline'
|
|
||||||
},
|
},
|
||||||
{
|
// className: 'w-full',
|
||||||
label: '水平',
|
pipeIn: defaultValue(''),
|
||||||
value: 'horizontal'
|
options: [
|
||||||
},
|
{
|
||||||
{
|
label: '内联',
|
||||||
label: '垂直',
|
value: 'inline'
|
||||||
value: 'normal'
|
},
|
||||||
},
|
{
|
||||||
{
|
label: '水平',
|
||||||
label: '继承',
|
value: 'horizontal'
|
||||||
value: ''
|
},
|
||||||
}
|
{
|
||||||
],
|
label: '垂直',
|
||||||
pipeOut: (v: string) => (v ? v : undefined)
|
value: 'normal'
|
||||||
});
|
},
|
||||||
|
config?.isForm
|
||||||
|
? null
|
||||||
|
: {
|
||||||
|
label: '继承',
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
].filter(i => i),
|
||||||
|
pipeOut: (v: string) => (v ? v : undefined)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
setSchemaTpl('formItemInline', {
|
setSchemaTpl('formItemInline', {
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
@ -243,37 +286,31 @@ setSchemaTpl(
|
|||||||
key: string;
|
key: string;
|
||||||
visibleOn: string;
|
visibleOn: string;
|
||||||
body: Array<any>;
|
body: Array<any>;
|
||||||
}>,
|
}>
|
||||||
rendererSchema?: any
|
|
||||||
) => {
|
) => {
|
||||||
let currentKey = rendererSchema
|
|
||||||
? `${rendererSchema.$$id}_${rendererSchema.type}_${rendererSchema.configTitle}_collapse`
|
|
||||||
: `config_collapse`;
|
|
||||||
currentKey = currentKey.replace(/-/g, '__');
|
|
||||||
|
|
||||||
const collapseGroupBody = config
|
const collapseGroupBody = config
|
||||||
.filter(
|
.filter(
|
||||||
item => item && Array.isArray(item?.body) && item?.body.length > 0
|
item => item && Array.isArray(item?.body) && item?.body.length > 0
|
||||||
)
|
)
|
||||||
.map((item, index) => ({
|
.map(item => ({
|
||||||
type: 'collapse',
|
type: 'collapse',
|
||||||
|
collapsed: false,
|
||||||
headingClassName: 'ae-formItemControl-header',
|
headingClassName: 'ae-formItemControl-header',
|
||||||
bodyClassName: 'ae-formItemControl-body',
|
bodyClassName: 'ae-formItemControl-body',
|
||||||
...item,
|
...item,
|
||||||
key: `${currentKey}_${item.key || index.toString()}`,
|
key: item.title,
|
||||||
body: flatten(item.body)
|
body: flatten(item.body)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'collapse-group',
|
type: 'collapse-group',
|
||||||
key: currentKey,
|
activeKey: collapseGroupBody.map(panel => panel.title),
|
||||||
expandIconPosition: 'right',
|
expandIconPosition: 'right',
|
||||||
expandIcon: {
|
expandIcon: {
|
||||||
type: 'icon',
|
type: 'icon',
|
||||||
icon: 'chevron-right'
|
icon: 'chevron-right'
|
||||||
},
|
},
|
||||||
className: 'ae-formItemControl ae-styleControl',
|
className: 'ae-formItemControl ae-styleControl',
|
||||||
activeKey: collapseGroupBody.map((group, index) => group.key),
|
|
||||||
body: collapseGroupBody
|
body: collapseGroupBody
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -346,7 +383,7 @@ setSchemaTpl(
|
|||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'ae-formulaControl',
|
type: 'ae-formulaControl',
|
||||||
label: config?.label || '默认值',
|
label: config?.label ?? '默认值',
|
||||||
name: config?.name || 'value',
|
name: config?.name || 'value',
|
||||||
rendererSchema: curRendererSchema,
|
rendererSchema: curRendererSchema,
|
||||||
rendererWrapper: config?.rendererWrapper,
|
rendererWrapper: config?.rendererWrapper,
|
||||||
@ -509,28 +546,29 @@ setSchemaTpl('size', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setSchemaTpl('name', {
|
setSchemaTpl('name', {
|
||||||
label: '名字',
|
label: tipedLabel(
|
||||||
|
'名字',
|
||||||
|
'需要联动时才需要,其他组件可以通过这个名字跟当前组件联动'
|
||||||
|
),
|
||||||
name: 'name',
|
name: 'name',
|
||||||
type: 'input-text',
|
type: 'input-text',
|
||||||
description: '需要联动时才需要,其他组件可以通过这个名字跟当前组件联动',
|
|
||||||
placeholder: '请输入字母或者数字'
|
placeholder: '请输入字母或者数字'
|
||||||
});
|
});
|
||||||
|
|
||||||
setSchemaTpl('reload', {
|
setSchemaTpl('reload', {
|
||||||
label: '刷新目标组件',
|
|
||||||
name: 'reload',
|
name: 'reload',
|
||||||
asFormItem: true,
|
asFormItem: true,
|
||||||
// type: 'input-text',
|
// type: 'input-text',
|
||||||
component: InputComponentName,
|
component: InputComponentName,
|
||||||
description:
|
label: tipedLabel(
|
||||||
'可以指定操作完成后刷新目标组件,请填写目标组件的 <code>name</code> 属性,多个组件请用<code>,</code>隔开,如果目标组件为表单项,请先填写表单的名字,再用<code>.</code>连接表单项的名字如:<code>xxForm.xxControl</code>。另外如果刷新目标对象设置为 <code>window</code>,则会刷新整个页面。',
|
'刷新目标组件',
|
||||||
labelRemark: {
|
'可以指定操作完成后刷新目标组件,请填写目标组件的 <code>name</code> 属性,多个组件请用<code>,</code>隔开,如果目标组件为表单项,请先填写表单的名字,再用<code>.</code>连接表单项的名字如:<code>xxForm.xxControl</code>。另外如果刷新目标对象设置为 <code>window</code>,则会刷新整个页面。'
|
||||||
trigger: 'click',
|
),
|
||||||
className: 'm-l-xs',
|
placeholder: '请输入组件name',
|
||||||
rootClose: true,
|
mode: 'horizontal',
|
||||||
content:
|
horizontal: {
|
||||||
'设置名字后,当前组件操作完成会触发目标组件(根据设置的名字)的刷新。',
|
left: 4,
|
||||||
placement: 'left'
|
justify: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -577,7 +615,7 @@ setSchemaTpl(
|
|||||||
? getSchemaTpl('disabled')
|
? getSchemaTpl('disabled')
|
||||||
: null,
|
: null,
|
||||||
config?.isFormItem ? getSchemaTpl('clearValueOnHidden') : null
|
config?.isFormItem ? getSchemaTpl('clearValueOnHidden') : null
|
||||||
]
|
].filter(Boolean)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {setSchemaTpl, getSchemaTpl, defaultValue} from 'amis-editor-core';
|
import {setSchemaTpl, getSchemaTpl, defaultValue} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {isObject} from 'lodash';
|
||||||
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
|
|
||||||
setSchemaTpl('horizontal-align', {
|
setSchemaTpl('horizontal-align', {
|
||||||
type: 'button-group-select',
|
type: 'button-group-select',
|
||||||
@ -57,47 +58,51 @@ setSchemaTpl('leftRate', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setSchemaTpl('horizontal', () => {
|
setSchemaTpl(
|
||||||
return [
|
'horizontal',
|
||||||
{
|
(config: {visibleOn: string; [propName: string]: any}) => {
|
||||||
type: 'button-group-select',
|
return [
|
||||||
label: '标题宽度',
|
{
|
||||||
name: 'horizontal',
|
type: 'button-group-select',
|
||||||
options: [
|
label: '标题宽度',
|
||||||
{label: '继承', value: 'formHorizontal'},
|
name: 'horizontal',
|
||||||
{label: '固宽', value: 'leftFixed'},
|
options: [
|
||||||
{label: '比例', value: 'leftRate'}
|
{label: '继承', value: 'formHorizontal'},
|
||||||
],
|
{label: '固宽', value: 'leftFixed'},
|
||||||
pipeIn(v: any) {
|
{label: '比例', value: 'leftRate'}
|
||||||
if (!v) {
|
],
|
||||||
return 'formHorizontal';
|
pipeIn(v: any) {
|
||||||
}
|
if (!v) {
|
||||||
if (v.leftFixed) {
|
return 'formHorizontal';
|
||||||
return 'leftFixed';
|
}
|
||||||
}
|
if (v.leftFixed) {
|
||||||
return 'leftRate';
|
return 'leftFixed';
|
||||||
},
|
}
|
||||||
pipeOut(v: any) {
|
return 'leftRate';
|
||||||
const defaultData = {
|
},
|
||||||
formHorizontal: undefined,
|
pipeOut(v: any) {
|
||||||
leftFixed: {leftFixed: 'normal'},
|
const defaultData = {
|
||||||
leftRate: {left: 3, right: 9}
|
formHorizontal: undefined,
|
||||||
};
|
leftFixed: {leftFixed: 'normal'},
|
||||||
|
leftRate: {left: 3, right: 9}
|
||||||
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return defaultData[v];
|
return defaultData[v];
|
||||||
|
},
|
||||||
|
visibleOn: 'this.mode == "horizontal" && this.label !== false',
|
||||||
|
...(isObject(config) ? config : {})
|
||||||
},
|
},
|
||||||
visibleOn: 'this.mode == "horizontal" && this.label !== false'
|
{
|
||||||
},
|
type: 'container',
|
||||||
{
|
className: 'ae-ExtendMore mb-3',
|
||||||
type: 'container',
|
visibleOn:
|
||||||
className: 'ae-ExtendMore mb-3',
|
'this.mode == "horizontal" && this.horizontal && this.label !== false',
|
||||||
visibleOn:
|
body: [getSchemaTpl('leftFixed'), getSchemaTpl('leftRate')]
|
||||||
'this.mode == "horizontal" && this.horizontal && this.label !== false',
|
}
|
||||||
body: [getSchemaTpl('leftFixed'), getSchemaTpl('leftRate')]
|
];
|
||||||
}
|
}
|
||||||
];
|
);
|
||||||
});
|
|
||||||
|
|
||||||
setSchemaTpl('subFormItemMode', {
|
setSchemaTpl('subFormItemMode', {
|
||||||
label: '子表单展示模式',
|
label: '子表单展示模式',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {setSchemaTpl, getSchemaTpl, defaultValue} from 'amis-editor-core';
|
import {setSchemaTpl, getSchemaTpl, defaultValue} from 'amis-editor-core';
|
||||||
import {tipedLabel} from '../component/BaseControl';
|
import {tipedLabel} from 'amis-editor-core';
|
||||||
import {SchemaObject} from 'amis/lib/Schema';
|
import {SchemaObject} from 'amis/lib/Schema';
|
||||||
|
|
||||||
setSchemaTpl('options', {
|
setSchemaTpl('options', {
|
||||||
@ -114,7 +114,7 @@ setSchemaTpl('tree', {
|
|||||||
|
|
||||||
setSchemaTpl('multiple', (schema: any = {}) => {
|
setSchemaTpl('multiple', (schema: any = {}) => {
|
||||||
return {
|
return {
|
||||||
type: 'ae-Switch-More',
|
type: 'ae-switch-more',
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
name: 'multiple',
|
name: 'multiple',
|
||||||
label: '可多选',
|
label: '可多选',
|
||||||
|
@ -9,6 +9,6 @@
|
|||||||
"../../node_modules/@types"
|
"../../node_modules/@types"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"],
|
"include": ["src/**/*", "../amis-editor-core/src/builder"],
|
||||||
"references": []
|
"references": []
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user