mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-16 01:40:53 +08:00
amis-saas-5329 [Feature] 「feat」服务调用配置升级
Change-Id: I729bfc812ece83eac5de3b47c2ba340141b45a2d
This commit is contained in:
parent
a3de043b1f
commit
1011cee9cc
@ -188,7 +188,7 @@ export class CRUDPlugin extends BasePlugin {
|
|||||||
scaffoldForm: ScaffoldForm = {
|
scaffoldForm: ScaffoldForm = {
|
||||||
title: '增删改查快速开始-CRUD',
|
title: '增删改查快速开始-CRUD',
|
||||||
body: [
|
body: [
|
||||||
getSchemaTpl('api', {
|
getSchemaTpl('apiControl', {
|
||||||
label: '接口地址',
|
label: '接口地址',
|
||||||
sampleBuilder: (schema: any) =>
|
sampleBuilder: (schema: any) =>
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
|
@ -138,7 +138,7 @@ export class FormPlugin extends BasePlugin {
|
|||||||
scaffoldForm: ScaffoldForm = {
|
scaffoldForm: ScaffoldForm = {
|
||||||
title: '快速创建表单',
|
title: '快速创建表单',
|
||||||
body: [
|
body: [
|
||||||
getSchemaTpl('api', {
|
getSchemaTpl('apiControl', {
|
||||||
label: '提交地址'
|
label: '提交地址'
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
@ -534,7 +534,7 @@ export class FormPlugin extends BasePlugin {
|
|||||||
: {
|
: {
|
||||||
title: '接口',
|
title: '接口',
|
||||||
body: [
|
body: [
|
||||||
getSchemaTpl('api', {
|
getSchemaTpl('apiControl', {
|
||||||
label: '保存接口',
|
label: '保存接口',
|
||||||
description: '用来保存表单数据',
|
description: '用来保存表单数据',
|
||||||
sampleBuilder: () => `{
|
sampleBuilder: () => `{
|
||||||
@ -563,7 +563,7 @@ export class FormPlugin extends BasePlugin {
|
|||||||
pipeOut: (value: any) => (value ? '' : undefined)
|
pipeOut: (value: any) => (value ? '' : undefined)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('api', {
|
getSchemaTpl('apiControl', {
|
||||||
name: 'asyncApi',
|
name: 'asyncApi',
|
||||||
label: '异步检测接口',
|
label: '异步检测接口',
|
||||||
visibleOn: 'data.asyncApi != null',
|
visibleOn: 'data.asyncApi != null',
|
||||||
@ -575,7 +575,7 @@ export class FormPlugin extends BasePlugin {
|
|||||||
type: 'divider'
|
type: 'divider'
|
||||||
},
|
},
|
||||||
|
|
||||||
getSchemaTpl('api', {
|
getSchemaTpl('apiControl', {
|
||||||
name: 'initApi',
|
name: 'initApi',
|
||||||
label: '初始化接口',
|
label: '初始化接口',
|
||||||
description: '用来初始化表单数据',
|
description: '用来初始化表单数据',
|
||||||
@ -657,7 +657,7 @@ export class FormPlugin extends BasePlugin {
|
|||||||
pipeOut: (value: any) => (value ? '' : undefined)
|
pipeOut: (value: any) => (value ? '' : undefined)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSchemaTpl('api', {
|
getSchemaTpl('apiControl', {
|
||||||
name: 'initAsyncApi',
|
name: 'initAsyncApi',
|
||||||
label: '异步检测接口',
|
label: '异步检测接口',
|
||||||
visibleOn: 'data.initAsyncApi != null',
|
visibleOn: 'data.initAsyncApi != null',
|
||||||
|
@ -170,21 +170,36 @@ export class PagePlugin extends BasePlugin {
|
|||||||
{
|
{
|
||||||
title: '接口',
|
title: '接口',
|
||||||
body: [
|
body: [
|
||||||
getSchemaTpl('api', {
|
getSchemaTpl('apiControl', {
|
||||||
label: '数据初始化接口',
|
label: '数据初始化接口',
|
||||||
name: 'initApi',
|
name: 'initApi',
|
||||||
sampleBuilder: () => `{
|
sampleBuilder: () => `{
|
||||||
"status": 0,
|
"status": 0,
|
||||||
"msg": "",
|
"msg": "",
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
// 示例数据
|
// 示例数据
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"a": "sample"
|
"a": "sample"
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// getSchemaTpl('api', {
|
||||||
|
// label: '数据初始化接口',
|
||||||
|
// name: 'initApi',
|
||||||
|
// sampleBuilder: () => `{
|
||||||
|
// "status": 0,
|
||||||
|
// "msg": "",
|
||||||
|
|
||||||
|
// data: {
|
||||||
|
// // 示例数据
|
||||||
|
// "id": 1,
|
||||||
|
// "a": "sample"
|
||||||
|
// }
|
||||||
|
// }`
|
||||||
|
// }),
|
||||||
|
|
||||||
getSchemaTpl('initFetch'),
|
getSchemaTpl('initFetch'),
|
||||||
|
|
||||||
getSchemaTpl('switch', {
|
getSchemaTpl('switch', {
|
||||||
|
@ -237,24 +237,43 @@ export default class APIControl extends React.Component<
|
|||||||
onPickerClose?.();
|
onPickerClose?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
const {render, actions, enablePickerMode} = this.props;
|
const {render, label, labelRemark, useMobileUI, popOverContainer, env} =
|
||||||
|
this.props;
|
||||||
|
const classPrefix = env?.theme?.classPrefix;
|
||||||
|
|
||||||
const actionsDom =
|
// const actionsDom =
|
||||||
Array.isArray(actions) && actions.length > 0
|
// Array.isArray(actions) && actions.length > 0
|
||||||
? actions.map((action, index) => {
|
// ? actions.map((action, index) => {
|
||||||
return render(`action/${index}`, action, {
|
// return render(`action/${index}`, action, {
|
||||||
key: index,
|
// key: index,
|
||||||
onAction: this.handleAction.bind(this, action)
|
// onAction: this.handleAction.bind(this, action)
|
||||||
});
|
// });
|
||||||
})
|
// })
|
||||||
: null;
|
// : null;
|
||||||
|
|
||||||
return actionsDom || enablePickerMode ? (
|
return (
|
||||||
<header className="ae-ApiControl-header" key="header">
|
<header className="ApiControl-header" key="header">
|
||||||
{enablePickerMode ? this.renderPickerSchema() : actionsDom}
|
<label className={cx(`${classPrefix}Form-label`)}>
|
||||||
|
{label || ''}
|
||||||
|
{labelRemark
|
||||||
|
? render('label-remark', {
|
||||||
|
type: 'remark',
|
||||||
|
icon: labelRemark.icon || 'warning-mark',
|
||||||
|
tooltip: labelRemark,
|
||||||
|
className: cx(`Form-lableRemark`, labelRemark?.className),
|
||||||
|
useMobileUI,
|
||||||
|
container: popOverContainer
|
||||||
|
? popOverContainer
|
||||||
|
: env && env.getModalContainer
|
||||||
|
? env.getModalContainer
|
||||||
|
: undefined
|
||||||
|
})
|
||||||
|
: null}
|
||||||
|
</label>
|
||||||
</header>
|
</header>
|
||||||
) : null;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPickerSchema() {
|
renderPickerSchema() {
|
||||||
@ -953,6 +972,7 @@ export default class APIControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@FormItem({
|
@FormItem({
|
||||||
type: 'ae-apiControl'
|
type: 'ae-apiControl',
|
||||||
|
renderLabel: false
|
||||||
})
|
})
|
||||||
export class APIControlRenderer extends APIControl {}
|
export class APIControlRenderer extends APIControl {}
|
||||||
|
@ -47,7 +47,7 @@ export interface OptionControlState {
|
|||||||
api: SchemaApi;
|
api: SchemaApi;
|
||||||
labelField: string;
|
labelField: string;
|
||||||
valueField: string;
|
valueField: string;
|
||||||
source: 'custom' | 'api' | 'form';
|
source: 'custom' | 'api' | 'apicenter';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class OptionControl extends React.Component<
|
export default class OptionControl extends React.Component<
|
||||||
@ -209,7 +209,7 @@ export default class OptionControl extends React.Component<
|
|||||||
data.value = defaultValue || undefined;
|
data.value = defaultValue || undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source === 'api') {
|
if (source === 'api' || source === 'apicenter') {
|
||||||
const {api, labelField, valueField} = this.state;
|
const {api, labelField, valueField} = this.state;
|
||||||
data.source = api;
|
data.source = api;
|
||||||
data.labelField = labelField;
|
data.labelField = labelField;
|
||||||
@ -296,7 +296,7 @@ export default class OptionControl extends React.Component<
|
|||||||
* 切换选项类型
|
* 切换选项类型
|
||||||
*/
|
*/
|
||||||
@autobind
|
@autobind
|
||||||
handleSourceChange(source: 'custom' | 'api' | 'form') {
|
handleSourceChange(source: 'custom' | 'api' | 'apicenter') {
|
||||||
this.setState({source: source}, this.onChange);
|
this.setState({source: source}, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,8 +396,15 @@ export default class OptionControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderHeader() {
|
renderHeader() {
|
||||||
const {render, label, labelRemark, useMobileUI, env, popOverContainer} =
|
const {
|
||||||
this.props;
|
render,
|
||||||
|
label,
|
||||||
|
labelRemark,
|
||||||
|
useMobileUI,
|
||||||
|
env,
|
||||||
|
popOverContainer,
|
||||||
|
hasApiCenter
|
||||||
|
} = this.props;
|
||||||
const classPrefix = env?.theme?.classPrefix;
|
const classPrefix = env?.theme?.classPrefix;
|
||||||
const {source} = this.state;
|
const {source} = this.state;
|
||||||
const optionSourceList = (
|
const optionSourceList = (
|
||||||
@ -407,16 +414,17 @@ export default class OptionControl extends React.Component<
|
|||||||
value: 'custom'
|
value: 'custom'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '接口获取',
|
label: '外部接口',
|
||||||
value: 'api'
|
value: 'api'
|
||||||
}
|
},
|
||||||
|
...(hasApiCenter ? [{label: 'API中心', value: 'apicenter'}] : [])
|
||||||
// {
|
// {
|
||||||
// label: '表单实体',
|
// label: '表单实体',
|
||||||
// value: 'form'
|
// value: 'form'
|
||||||
// }
|
// }
|
||||||
] as Array<{
|
] as Array<{
|
||||||
label: string;
|
label: string;
|
||||||
value: 'custom' | 'api' | 'form';
|
value: 'custom' | 'api' | 'apicenter';
|
||||||
}>
|
}>
|
||||||
).map(item => ({
|
).map(item => ({
|
||||||
...item,
|
...item,
|
||||||
@ -698,7 +706,7 @@ export default class OptionControl extends React.Component<
|
|||||||
renderApiPanel() {
|
renderApiPanel() {
|
||||||
const {render} = this.props;
|
const {render} = this.props;
|
||||||
const {source, api, labelField, valueField} = this.state;
|
const {source, api, labelField, valueField} = this.state;
|
||||||
if (source !== 'api') {
|
if (source === 'custom') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,6 +719,7 @@ export default class OptionControl extends React.Component<
|
|||||||
visibleOn: 'data.autoComplete !== false',
|
visibleOn: 'data.autoComplete !== false',
|
||||||
value: api,
|
value: api,
|
||||||
onChange: this.handleAPIChange,
|
onChange: this.handleAPIChange,
|
||||||
|
sourceType: source,
|
||||||
footer: [
|
footer: [
|
||||||
{
|
{
|
||||||
label: tipedLabel(
|
label: tipedLabel(
|
||||||
|
@ -26,7 +26,7 @@ import type {Option} from 'amis';
|
|||||||
import type {FormControlProps} from 'amis-core';
|
import type {FormControlProps} from 'amis-core';
|
||||||
import {SchemaApi} from 'amis/lib/Schema';
|
import {SchemaApi} from 'amis/lib/Schema';
|
||||||
|
|
||||||
export type OptionControlItem = Option & {checked?: boolean, _key?: string};
|
export type OptionControlItem = Option & {checked?: boolean; _key?: string};
|
||||||
|
|
||||||
export interface OptionControlProps extends FormControlProps {
|
export interface OptionControlProps extends FormControlProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -37,14 +37,14 @@ export interface OptionControlState {
|
|||||||
api: SchemaApi;
|
api: SchemaApi;
|
||||||
labelField: string;
|
labelField: string;
|
||||||
valueField: string;
|
valueField: string;
|
||||||
source: 'custom' | 'api';
|
source: 'custom' | 'api' | 'apicenter';
|
||||||
modalVisible: boolean
|
modalVisible: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOption: OptionControlItem = {
|
const defaultOption: OptionControlItem = {
|
||||||
label: '',
|
label: '',
|
||||||
value: ''
|
value: ''
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class TreeOptionControl extends React.Component<
|
export default class TreeOptionControl extends React.Component<
|
||||||
OptionControlProps,
|
OptionControlProps,
|
||||||
@ -69,9 +69,11 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
transformOptions(props: OptionControlProps) {
|
transformOptions(props: OptionControlProps) {
|
||||||
const {data: {options}} = props;
|
const {
|
||||||
|
data: {options}
|
||||||
|
} = props;
|
||||||
if (!options || !options.length) {
|
if (!options || !options.length) {
|
||||||
return [{...defaultOption}]
|
return [{...defaultOption}];
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
@ -87,7 +89,10 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
if (option.children && option.children.length) {
|
if (option.children && option.children.length) {
|
||||||
option.children = this.pretreatOptions(option.children);
|
option.children = this.pretreatOptions(option.children);
|
||||||
}
|
}
|
||||||
option.value = option.value == null || option.value === '' ? option.label : option.value;
|
option.value =
|
||||||
|
option.value == null || option.value === ''
|
||||||
|
? option.label
|
||||||
|
: option.value;
|
||||||
return option;
|
return option;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -109,7 +114,7 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
data.options = this.pretreatOptions(options);
|
data.options = this.pretreatOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source === 'api') {
|
if (source === 'api' || source === 'apicenter') {
|
||||||
const {api, labelField, valueField} = this.state;
|
const {api, labelField, valueField} = this.state;
|
||||||
data.source = api;
|
data.source = api;
|
||||||
data.labelField = labelField;
|
data.labelField = labelField;
|
||||||
@ -123,7 +128,7 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
* 切换选项类型
|
* 切换选项类型
|
||||||
*/
|
*/
|
||||||
@autobind
|
@autobind
|
||||||
handleSourceChange(source: 'custom' | 'api') {
|
handleSourceChange(source: 'custom' | 'api' | 'apicenter') {
|
||||||
this.setState({source: source}, this.onChange);
|
this.setState({source: source}, this.onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,23 +139,27 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
labelRemark,
|
labelRemark,
|
||||||
useMobileUI,
|
useMobileUI,
|
||||||
env,
|
env,
|
||||||
popOverContainer
|
popOverContainer,
|
||||||
|
hasApiCenter
|
||||||
} = this.props;
|
} = 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'
|
||||||
] as Array<{
|
},
|
||||||
label: string;
|
...(hasApiCenter ? [{label: 'API中心', value: 'apicenter'}] : [])
|
||||||
value: 'custom' | 'api';
|
] as Array<{
|
||||||
}>).map(item => ({
|
label: string;
|
||||||
|
value: 'custom' | 'api' | 'apicenter';
|
||||||
|
}>
|
||||||
|
).map(item => ({
|
||||||
...item,
|
...item,
|
||||||
onClick: () => this.handleSourceChange(item.value)
|
onClick: () => this.handleSourceChange(item.value)
|
||||||
}));
|
}));
|
||||||
@ -200,11 +209,11 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEditLabelOrValue (value: string, path: string, key: string) {
|
handleEditLabelOrValue(value: string, path: string, key: string) {
|
||||||
const options = cloneDeep(this.state.options);
|
const options = cloneDeep(this.state.options);
|
||||||
const {path: nodePath} = this.getNodePath(path);
|
const {path: nodePath} = this.getNodePath(path);
|
||||||
set(options, `${nodePath}.${key}`, value);
|
set(options, `${nodePath}.${key}`, value);
|
||||||
this.setState({options}, () => this.rereshBindDrag());
|
this.setState({options}, () => this.rereshBindDrag());
|
||||||
}
|
}
|
||||||
@autobind
|
@autobind
|
||||||
handleDelete(pathStr: string, index: number) {
|
handleDelete(pathStr: string, index: number) {
|
||||||
@ -216,12 +225,12 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
const path = pathStr.split('-');
|
const path = pathStr.split('-');
|
||||||
if (path.length === 1) {
|
if (path.length === 1) {
|
||||||
options.splice(index, 1);
|
options.splice(index, 1);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const {parentPath} = this.getNodePath(pathStr);
|
const {parentPath} = this.getNodePath(pathStr);
|
||||||
const parentNode = get(options, parentPath, {});
|
const parentNode = get(options, parentPath, {});
|
||||||
parentNode?.children?.splice(index, 1);
|
parentNode?.children?.splice(index, 1);
|
||||||
if (!parentNode?.children.length) { // 去除僵尸子节点
|
if (!parentNode?.children.length) {
|
||||||
|
// 去除僵尸子节点
|
||||||
delete parentNode.children;
|
delete parentNode.children;
|
||||||
}
|
}
|
||||||
set(options, parentPath, parentNode);
|
set(options, parentPath, parentNode);
|
||||||
@ -231,7 +240,7 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
@autobind
|
@autobind
|
||||||
getNodePath(pathStr: string) {
|
getNodePath(pathStr: string) {
|
||||||
let pathArr = pathStr.split('-');
|
let pathArr = pathStr.split('-');
|
||||||
if(pathArr.length === 1) {
|
if (pathArr.length === 1) {
|
||||||
return {
|
return {
|
||||||
path: pathArr,
|
path: pathArr,
|
||||||
parentPath: ''
|
parentPath: ''
|
||||||
@ -251,8 +260,7 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
const path = pathStr.split('-');
|
const path = pathStr.split('-');
|
||||||
if (path.length === 1) {
|
if (path.length === 1) {
|
||||||
options.splice(+path[0] + 1, 0, {...defaultOption}); // 加在后面一项
|
options.splice(+path[0] + 1, 0, {...defaultOption}); // 加在后面一项
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const index = path[path.length - 1];
|
const index = path[path.length - 1];
|
||||||
const {parentPath} = this.getNodePath(pathStr);
|
const {parentPath} = this.getNodePath(pathStr);
|
||||||
const parentNode = get(options, parentPath, {});
|
const parentNode = get(options, parentPath, {});
|
||||||
@ -264,7 +272,9 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
@autobind
|
@autobind
|
||||||
addChildOption(pathStr: string) {
|
addChildOption(pathStr: string) {
|
||||||
if (pathStr.split('-').length >= 7) {
|
if (pathStr.split('-').length >= 7) {
|
||||||
toast.warning('层级过深,建议使用【接口获取】管理选项', {closeButton: true});
|
toast.warning('层级过深,建议使用【接口获取】管理选项', {
|
||||||
|
closeButton: true
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const options = cloneDeep(this.state.options);
|
const options = cloneDeep(this.state.options);
|
||||||
@ -272,8 +282,7 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
const node = get(options, path) || [];
|
const node = get(options, path) || [];
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
node.children.push({...defaultOption});
|
node.children.push({...defaultOption});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
node.children = [{...defaultOption}];
|
node.children = [{...defaultOption}];
|
||||||
}
|
}
|
||||||
set(options, path, node);
|
set(options, path, node);
|
||||||
@ -292,22 +301,26 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
if (option.children && option.children.length) {
|
if (option.children && option.children.length) {
|
||||||
const parent = cloneDeep(option);
|
const parent = cloneDeep(option);
|
||||||
delete parent.children;
|
delete parent.children;
|
||||||
return <div className={cx('ae-TreeOptionControlItem-parent')} key={`parent${path}${key}${option.label}`}>
|
return (
|
||||||
{this.renderOptions(parent, key, indexes)}
|
|
||||||
<div
|
<div
|
||||||
className={cx('ae-TreeOptionControlItem-son')}
|
className={cx('ae-TreeOptionControlItem-parent')}
|
||||||
key={`son${path}${key}${option.label}`}
|
key={`parent${path}${key}${option.label}`}
|
||||||
data-level={path}
|
|
||||||
>
|
>
|
||||||
{
|
{this.renderOptions(parent, key, indexes)}
|
||||||
option.children.map((option: any, key: number) => {
|
<div
|
||||||
return this.renderOptions(option, key, indexes.concat(key))
|
className={cx('ae-TreeOptionControlItem-son')}
|
||||||
})
|
key={`son${path}${key}${option.label}`}
|
||||||
}
|
data-level={path}
|
||||||
|
>
|
||||||
|
{option.children.map((option: any, key: number) => {
|
||||||
|
return this.renderOptions(option, key, indexes.concat(key));
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
}
|
}
|
||||||
return <div
|
return (
|
||||||
|
<div
|
||||||
className="ae-TreeOptionControlItem"
|
className="ae-TreeOptionControlItem"
|
||||||
key={`child${path}${key}${option.label}`}
|
key={`child${path}${key}${option.label}`}
|
||||||
data-path={path}
|
data-path={path}
|
||||||
@ -320,7 +333,8 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
value={option.label}
|
value={option.label}
|
||||||
placeholder="选项名称"
|
placeholder="选项名称"
|
||||||
clearable={false}
|
clearable={false}
|
||||||
onBlur={(event: any) => { // 这里使用onBlur替代onChange 减少渲染次数
|
onBlur={(event: any) => {
|
||||||
|
// 这里使用onBlur替代onChange 减少渲染次数
|
||||||
this.handleEditLabelOrValue(event.target.value, path, 'label');
|
this.handleEditLabelOrValue(event.target.value, path, 'label');
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -372,7 +386,8 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
<Icon className="icon" icon="delete-bold-btn" />
|
<Icon className="icon" icon="delete-bold-btn" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@autobind
|
@autobind
|
||||||
dragRef(ref: any) {
|
dragRef(ref: any) {
|
||||||
@ -390,28 +405,30 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
initDragging() {
|
initDragging() {
|
||||||
const rootSortable = new Sortable(
|
const rootSortable = new Sortable(this.drag as HTMLElement, {
|
||||||
this.drag as HTMLElement,
|
group: 'TreeOptionControlGroup',
|
||||||
{
|
animation: 150,
|
||||||
group: 'TreeOptionControlGroup',
|
handle: '.ae-TreeOptionControlItem-dragBar',
|
||||||
animation: 150,
|
ghostClass: 'ae-TreeOptionControlItem-dragging',
|
||||||
handle: '.ae-TreeOptionControlItem-dragBar',
|
onEnd: (e: any) => {
|
||||||
ghostClass: 'ae-TreeOptionControlItem-dragging',
|
const options = cloneDeep(this.state.options);
|
||||||
onEnd: (e: any) => {
|
const {oldIndex, newIndex} = e;
|
||||||
const options = cloneDeep(this.state.options);
|
[options[newIndex], options[oldIndex]] = [
|
||||||
const {oldIndex, newIndex} = e;
|
options[oldIndex],
|
||||||
[options[newIndex], options[oldIndex]] = [options[oldIndex], options[newIndex]];
|
options[newIndex]
|
||||||
this.setState({options}, () => this.rereshBindDrag());
|
];
|
||||||
},
|
this.setState({options}, () => this.rereshBindDrag());
|
||||||
onMove: (e: any) => {
|
},
|
||||||
const {from, to} = e;
|
onMove: (e: any) => {
|
||||||
// 暂时不支持跨级拖拽
|
const {from, to} = e;
|
||||||
return from.dataset.level === to.dataset.level;
|
// 暂时不支持跨级拖拽
|
||||||
}
|
return from.dataset.level === to.dataset.level;
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
this.sortables.push(rootSortable);
|
this.sortables.push(rootSortable);
|
||||||
const parents = this.drag?.querySelectorAll('.ae-TreeOptionControlItem-son');
|
const parents = this.drag?.querySelectorAll(
|
||||||
|
'.ae-TreeOptionControlItem-son'
|
||||||
|
);
|
||||||
if (!parents) {
|
if (!parents) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -432,7 +449,10 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
const {parentPath} = this.getNodePath(nodePath);
|
const {parentPath} = this.getNodePath(nodePath);
|
||||||
const children = get(options, `${parentPath}.children`) || [];
|
const children = get(options, `${parentPath}.children`) || [];
|
||||||
if (children) {
|
if (children) {
|
||||||
[children[oldIndex], children[newIndex]] = [children[newIndex], children[oldIndex]];
|
[children[oldIndex], children[newIndex]] = [
|
||||||
|
children[newIndex],
|
||||||
|
children[oldIndex]
|
||||||
|
];
|
||||||
set(options, `${parentPath}.children`, children);
|
set(options, `${parentPath}.children`, children);
|
||||||
this.setState({options});
|
this.setState({options});
|
||||||
}
|
}
|
||||||
@ -467,32 +487,38 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
this.hideModal();
|
this.hideModal();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Modal.Header
|
<Modal.Header
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
|
this.hideModal();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
选项管理
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<div className="ae-TreeOptionControl-content" ref={this.dragRef}>
|
||||||
|
{options.map((option, key) =>
|
||||||
|
this.renderOptions(option, key, [key])
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
this.hideModal();
|
this.hideModal();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
选项管理
|
取消
|
||||||
</Modal.Header>
|
</Button>
|
||||||
<Modal.Body>
|
<Button
|
||||||
<div className="ae-TreeOptionControl-content" ref={this.dragRef}>
|
level="primary"
|
||||||
{options.map((option, key) => this.renderOptions(option, key, [key]))}
|
onClick={() => {
|
||||||
</div>
|
this.onChange();
|
||||||
</Modal.Body>
|
this.hideModal(true);
|
||||||
<Modal.Footer>
|
}}
|
||||||
<Button
|
>
|
||||||
onClick={() => {
|
确认
|
||||||
this.hideModal();
|
</Button>
|
||||||
}}
|
</Modal.Footer>
|
||||||
>取消</Button>
|
|
||||||
<Button
|
|
||||||
level="primary"
|
|
||||||
onClick={() => {
|
|
||||||
this.onChange();
|
|
||||||
this.hideModal(true);
|
|
||||||
}}
|
|
||||||
>确认</Button>
|
|
||||||
</Modal.Footer>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -515,7 +541,7 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
renderApiPanel() {
|
renderApiPanel() {
|
||||||
const {render} = this.props;
|
const {render} = this.props;
|
||||||
const {source, api, labelField, valueField} = this.state;
|
const {source, api, labelField, valueField} = this.state;
|
||||||
if (source !== 'api') {
|
if (source === 'custom') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,6 +554,7 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
visibleOn: 'data.autoComplete !== false',
|
visibleOn: 'data.autoComplete !== false',
|
||||||
value: api,
|
value: api,
|
||||||
onChange: this.handleAPIChange,
|
onChange: this.handleAPIChange,
|
||||||
|
sourceType: source,
|
||||||
footer: [
|
footer: [
|
||||||
{
|
{
|
||||||
label: tipedLabel(
|
label: tipedLabel(
|
||||||
@ -569,9 +596,11 @@ export default class TreeOptionControl extends React.Component<
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
modalVisible: true
|
modalVisible: true
|
||||||
})
|
});
|
||||||
}}
|
}}
|
||||||
>选项管理</Button>
|
>
|
||||||
|
选项管理
|
||||||
|
</Button>
|
||||||
{this.renderModal()}
|
{this.renderModal()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user