mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-01 03:28:20 +08:00
merge feat-timeline
Change-Id: I009b295c17ae4ddc05eb2fb247dfe7c3a55e5fea
This commit is contained in:
commit
b9645bce9d
@ -122,6 +122,7 @@ import './plugin/Table';
|
||||
import './plugin/Tabs';
|
||||
import './plugin/Tasks';
|
||||
import './plugin/Time';
|
||||
import './plugin/Timeline';
|
||||
import './plugin/Tpl';
|
||||
import './plugin/AnchorNav';
|
||||
import './plugin/Video';
|
||||
@ -135,6 +136,7 @@ import './plugin/WebComponent';
|
||||
import {GridPlugin} from './plugin/Grid';
|
||||
|
||||
import './renderer/OptionControl';
|
||||
import './renderer/TimelineItemControl';
|
||||
import './renderer/APIControl';
|
||||
import './renderer/ValidationControl';
|
||||
import './renderer/ValidationItem';
|
||||
|
133
packages/amis-editor/src/plugin/Timeline.tsx
Normal file
133
packages/amis-editor/src/plugin/Timeline.tsx
Normal file
@ -0,0 +1,133 @@
|
||||
import React from 'react';
|
||||
import {getEventControlConfig} from '../util';
|
||||
import {tipedLabel} from '../component/BaseControl';
|
||||
import {
|
||||
registerEditorPlugin,
|
||||
getSchemaTpl
|
||||
} from 'amis-editor-core';
|
||||
import { RendererEvent } from 'amis-editor-comp/dist/renderers/event-action';
|
||||
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
|
||||
|
||||
export class TimelinePlugin extends BasePlugin {
|
||||
rendererName = 'timeline';
|
||||
$schema = '/schemas/TimelineSchema.json';
|
||||
label: '时间轴';
|
||||
type: 'timeline';
|
||||
name = '时间轴';
|
||||
isBaseComponent = true;
|
||||
icon = 'fa fa-bars';
|
||||
description = '用来展示时间轴';
|
||||
docLink = '/amis/zh-CN/components/timeline';
|
||||
tags = ['功能'];
|
||||
scaffold = {
|
||||
type: 'timeline',
|
||||
label: '时间轴',
|
||||
name: 'timeline',
|
||||
items: [
|
||||
{time: '2012-12-21', title: '节点数据'},
|
||||
{time: '2012-12-24', title: '节点数据'}
|
||||
]
|
||||
};
|
||||
previewSchema = {
|
||||
...this.scaffold
|
||||
};
|
||||
|
||||
// TODO 事件定义
|
||||
events: RendererEvent[] = [];
|
||||
|
||||
panelTitle = '时间轴';
|
||||
panelJustify = true;
|
||||
panelBodyCreator = (context: BaseEventContext) =>
|
||||
getSchemaTpl('tabs', [
|
||||
{
|
||||
title: '属性',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本',
|
||||
body: [
|
||||
getSchemaTpl('formItemName', {
|
||||
required: true
|
||||
}),
|
||||
getSchemaTpl('label'),
|
||||
{
|
||||
label: '排序',
|
||||
name: 'reverse',
|
||||
value: false,
|
||||
type: 'button-group-select',
|
||||
inline: false,
|
||||
options: [
|
||||
{label: '正序', value: false},
|
||||
{label: '反序', value: true}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '时间轴方向',
|
||||
name: 'direction',
|
||||
value: 'vertical',
|
||||
type: 'button-group-select',
|
||||
inline: true,
|
||||
options: [
|
||||
{label: '垂直', value: 'vertical'},
|
||||
{label: '水平', value: 'horizontal'}
|
||||
],
|
||||
},
|
||||
{
|
||||
label: tipedLabel(
|
||||
'文字位置',
|
||||
'文字相对时间轴位置'
|
||||
),
|
||||
name: 'mode',
|
||||
value: 'right',
|
||||
type: 'button-group-select',
|
||||
visibleOn: 'data.direction === "vertical"',
|
||||
options: [
|
||||
{label: '左侧', value: 'right'},
|
||||
{label: '右侧', value: 'left'},
|
||||
{label: '两侧交替', value: 'alternate'},
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '数据',
|
||||
body: [
|
||||
getSchemaTpl('timelineItemControl', {
|
||||
name: 'items',
|
||||
mode: 'normal',
|
||||
}),
|
||||
]
|
||||
},
|
||||
getSchemaTpl('status')
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '外观',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '样式',
|
||||
body: [
|
||||
{
|
||||
name: 'className',
|
||||
label: '外层',
|
||||
type: 'input-text',
|
||||
placeholder: '请输入className'
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '事件',
|
||||
className: 'p-none',
|
||||
body: [
|
||||
getSchemaTpl('eventControl',{
|
||||
name: 'onEvent',
|
||||
...getEventControlConfig(this.manager, context)
|
||||
})
|
||||
]
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
registerEditorPlugin(TimelinePlugin);
|
585
packages/amis-editor/src/renderer/TimelineItemControl.tsx
Normal file
585
packages/amis-editor/src/renderer/TimelineItemControl.tsx
Normal file
@ -0,0 +1,585 @@
|
||||
/**
|
||||
* @file Timeline组件节点的可视化编辑控件
|
||||
*/
|
||||
import React from 'react';
|
||||
import {findDOMNode} from 'react-dom';
|
||||
import cx from 'classnames';
|
||||
import uniqBy from 'lodash/uniqBy';
|
||||
import Sortable from 'sortablejs';
|
||||
import {
|
||||
render as amisRender,
|
||||
FormItem,
|
||||
Icon,
|
||||
InputBox
|
||||
} from 'amis';
|
||||
import {tipedLabel} from '../component/BaseControl';
|
||||
import {autobind} from 'amis-editor-core';
|
||||
import {getSchemaTpl} from 'amis-editor-core';
|
||||
import type {FormControlProps} from 'amis-core';
|
||||
import {SchemaApi} from 'amis/lib/Schema';
|
||||
import { isObject } from 'lodash';
|
||||
|
||||
type TimelineItem = {
|
||||
title: string;
|
||||
time: string;
|
||||
detail?: string;
|
||||
otherConfig?: boolean;
|
||||
detailCollapsedText?: string;
|
||||
detailExpandedText?: string;
|
||||
color?: string | 'info' | 'success' | 'warning' | 'danger';
|
||||
icon?: string;
|
||||
}
|
||||
export interface TimelineItemProps extends FormControlProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface TimelineItemState {
|
||||
items: Array<Partial<TimelineItem>>;
|
||||
source: 'custom' | 'api';
|
||||
api: SchemaApi;
|
||||
}
|
||||
|
||||
export default class TimelineItemControl extends React.Component<
|
||||
TimelineItemProps,
|
||||
TimelineItemState
|
||||
> {
|
||||
sortable?: Sortable;
|
||||
drag?: HTMLElement | null;
|
||||
target: HTMLElement | null;
|
||||
|
||||
constructor(props: TimelineItemProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
items: props.value,
|
||||
api: props.data.source,
|
||||
source: props.data.source ? 'api' : 'custom'
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 切换选项类型
|
||||
*/
|
||||
@autobind
|
||||
handleSourceChange(source: 'custom' | 'api') {
|
||||
this.setState({source: source}, this.onChange);
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleAPIChange(source: SchemaApi) {
|
||||
this.setState({api: source}, this.onChange);
|
||||
}
|
||||
|
||||
onChange() {
|
||||
const {source} = this.state;
|
||||
const {onBulkChange} = this.props;
|
||||
const data: Partial<TimelineItemProps> = {
|
||||
source: undefined,
|
||||
items: undefined
|
||||
};
|
||||
|
||||
if (source === 'custom') {
|
||||
const {items} = this.state;
|
||||
data.items = items.map(item => ({...item}))
|
||||
}
|
||||
if (source === 'api') {}
|
||||
onBulkChange && onBulkChange(data);
|
||||
}
|
||||
|
||||
@autobind
|
||||
toggleEdit(values: TimelineItem, index: number) {
|
||||
const items = this.state.items.concat();
|
||||
items[index] = values;
|
||||
|
||||
this.setState({items}, this.onChange);
|
||||
}
|
||||
|
||||
toggleCopy(index: number) {
|
||||
const {items} = this.state;
|
||||
const res = items.concat(items[index]);
|
||||
this.setState({items: res}, this.onChange);
|
||||
}
|
||||
|
||||
toggleDelete(index: number) {
|
||||
const items = this.state.items.concat();
|
||||
items.splice(index, 1);
|
||||
this.setState({items}, this.onChange);
|
||||
}
|
||||
|
||||
handleEditLabel(index: number, value: string, attr: 'time' | 'title') {
|
||||
const items = this.state.items.concat();
|
||||
|
||||
items.splice(index, 1, {...items[index], [attr]: value});
|
||||
this.setState({items}, () => this.onChange());
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleBatchAdd(values: {batchItems: string}, action: any) {
|
||||
const items = this.state.items.concat();
|
||||
|
||||
const addedOptions: Array<Partial<TimelineItem>> = values.batchItems
|
||||
.split('\n')
|
||||
.map(option => {
|
||||
const item = option.trim();
|
||||
if (~item.indexOf(' ')) {
|
||||
let [time, title] = item.split(' ');
|
||||
return {time: time.trim(), title: title.trim()};
|
||||
}
|
||||
return {label: item, value: item};
|
||||
});
|
||||
const newOptions = uniqBy([...items, ...addedOptions], 'time');
|
||||
|
||||
this.setState({items: newOptions}, () => this.onChange());
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleAdd(values: TimelineItem) {
|
||||
var {items} = this.state;
|
||||
|
||||
const itemsTemp = items.concat({...values});
|
||||
this.setState({items: itemsTemp}, this.onChange);
|
||||
}
|
||||
|
||||
buildAddOrEditSchema(props?: Partial<TimelineItem>) {
|
||||
return [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'time',
|
||||
required: true,
|
||||
placeholder: '请输入时间',
|
||||
label: '时间',
|
||||
value: props?.['time']
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'title',
|
||||
required: true,
|
||||
placeholder: '请输入标题',
|
||||
label: '标题',
|
||||
value: props?.['title']
|
||||
},
|
||||
{
|
||||
type: 'textarea',
|
||||
maxRows: 2,
|
||||
label: '描述',
|
||||
name: 'detail',
|
||||
value: props?.['detail'],
|
||||
placeholder: '请输入内容'
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'detailCollapsedText',
|
||||
value: props?.['detailCollapsedText'],
|
||||
placeholder: '请输入',
|
||||
label: tipedLabel(
|
||||
'折叠前文案',
|
||||
'无配置情况,默认显示标题'
|
||||
),
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'detailExpandedText',
|
||||
value: props?.['detailExpandedText'],
|
||||
placeholder: '请输入',
|
||||
label: tipedLabel(
|
||||
'折叠后文案',
|
||||
'无配置情况,默认显示标题'
|
||||
)
|
||||
},
|
||||
{
|
||||
type: 'input-color',
|
||||
name: 'color',
|
||||
value: props?.['color'],
|
||||
placeholder: '请输入',
|
||||
label: '颜色'
|
||||
},
|
||||
{
|
||||
type: 'icon-picker',
|
||||
name: 'icon',
|
||||
value: props?.['icon'],
|
||||
placeholder: '请输入',
|
||||
label: '图标',
|
||||
className: 'fix-icon-picker-overflow',
|
||||
pipeIn: (value: any) => value?.icon,
|
||||
pipeOut: (value: any) => {
|
||||
if (value) {
|
||||
return {
|
||||
type: 'icon',
|
||||
vendor: '',
|
||||
icon: value
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
buildBatchAddSchema() {
|
||||
return {
|
||||
type: 'action',
|
||||
actionType: 'dialog',
|
||||
label: '批量添加',
|
||||
dialog: {
|
||||
title: '批量添加选项',
|
||||
headerClassName: 'font-bold',
|
||||
closeOnEsc: true,
|
||||
closeOnOutside: false,
|
||||
showCloseButton: true,
|
||||
body: [
|
||||
{
|
||||
type: 'alert',
|
||||
level: 'warning',
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '每个选项单列一行,将所有值不重复的项加为新的选项;<br/>每行可通过空格来分别设置time和title,例:"2022-06-23 期末补考"'
|
||||
}
|
||||
],
|
||||
showIcon: true,
|
||||
className: 'mb-2.5'
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
wrapWithPanel: false,
|
||||
mode: 'normal',
|
||||
wrapperComponent: 'div',
|
||||
resetAfterSubmit: true,
|
||||
autoFocus: true,
|
||||
preventEnterSubmit: true,
|
||||
horizontal: {
|
||||
left: 0,
|
||||
right: 12
|
||||
},
|
||||
body: [
|
||||
{
|
||||
name: 'batchItems',
|
||||
type: 'textarea',
|
||||
label: '',
|
||||
placeholder: '请输入选项内容',
|
||||
trimContents: true,
|
||||
minRows: 10,
|
||||
maxRows: 50,
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
buildAddSchema() {
|
||||
return {
|
||||
type: 'action',
|
||||
actionType: 'dialog',
|
||||
label: '添加选项',
|
||||
active: true,
|
||||
dialog: {
|
||||
title: '节点配置',
|
||||
headerClassName: 'font-bold',
|
||||
closeOnEsc: true,
|
||||
closeOnOutside: false,
|
||||
showCloseButton: true,
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
wrapWithPanel: false,
|
||||
wrapperComponent: 'div',
|
||||
resetAfterSubmit: true,
|
||||
autoFocus: true,
|
||||
preventEnterSubmit: true,
|
||||
horizontal: {
|
||||
justify: true,
|
||||
left: 3,
|
||||
right: 9
|
||||
},
|
||||
body: this.buildAddOrEditSchema()
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
dragRef(ref: any) {
|
||||
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('.ae-TimelineItemControl-content') as HTMLElement,
|
||||
{
|
||||
group: 'TimelineItemControlGroup',
|
||||
animation: 150,
|
||||
handle: '.ae-TimelineItemControlItem-dragBar',
|
||||
ghostClass: 'ae-TimelineItemControlItem--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 items = this.state.items.concat();
|
||||
|
||||
items[e.oldIndex] = items.splice(
|
||||
e.newIndex,
|
||||
1,
|
||||
items[e.oldIndex]
|
||||
)[0];
|
||||
|
||||
this.setState({items}, () => this.onChange());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
destroyDragging() {
|
||||
this.sortable && this.sortable.destroy();
|
||||
}
|
||||
|
||||
renderHeader() {
|
||||
const {render, label, labelRemark, useMobileUI, env, popOverContainer} =
|
||||
this.props;
|
||||
|
||||
const classPrefix = env?.theme?.classPrefix;
|
||||
const {source} = this.state;
|
||||
const optionSourceList = (
|
||||
[
|
||||
{
|
||||
label: '自定义选项',
|
||||
value: 'custom'
|
||||
},
|
||||
{
|
||||
label: '接口获取',
|
||||
value: 'api'
|
||||
}
|
||||
] as Array<{
|
||||
label: string;
|
||||
value: 'custom' | 'api';
|
||||
}>
|
||||
).map(item => ({
|
||||
...item,
|
||||
onClick: () => this.handleSourceChange(item.value)
|
||||
}));
|
||||
|
||||
return (
|
||||
<header className="ae-TimelineItemControl-header">
|
||||
<label className={cx(`${classPrefix}Form-label`)}>
|
||||
{label || ''}
|
||||
{labelRemark
|
||||
? render('label-remark', {
|
||||
type: 'remark',
|
||||
icon: labelRemark.icon || 'warning-mark',
|
||||
tooltip: labelRemark,
|
||||
className: cx(`Form-lableRemark`, labelRemark?.className),
|
||||
useMobileUI,
|
||||
container: popOverContainer
|
||||
? popOverContainer
|
||||
: env && env.getModalContainer
|
||||
? env.getModalContainer
|
||||
: undefined
|
||||
})
|
||||
: null}
|
||||
</label>
|
||||
<div>
|
||||
{render(
|
||||
'validation-control-addBtn',
|
||||
{
|
||||
type: 'dropdown-button',
|
||||
level: 'link',
|
||||
size: 'sm',
|
||||
label: '${selected}',
|
||||
align: 'right',
|
||||
closeOnClick: true,
|
||||
closeOnOutside: true,
|
||||
buttons: optionSourceList
|
||||
},
|
||||
{
|
||||
popOverContainer: null,
|
||||
data: {
|
||||
selected: optionSourceList.find(item => item.value === source)!
|
||||
.label
|
||||
}
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
renderOption(props: TimelineItem & {index: number}) {
|
||||
const {time, title, index} = props;
|
||||
return (
|
||||
<li className="ae-TimelineItemControlItem" key={index}>
|
||||
<div className="ae-TimelineItemControlItem-Main">
|
||||
<a className="ae-TimelineItemControlItem-dragBar">
|
||||
<Icon icon="drag-bar" className="icon" />
|
||||
</a>
|
||||
<InputBox
|
||||
className="ae-TimelineItemControlItem-input"
|
||||
value={time}
|
||||
placeholder="请输入显示时间"
|
||||
clearable={false}
|
||||
onChange={(value: string) => this.handleEditLabel(index, value, 'time')}
|
||||
/>
|
||||
{/* {amisRender(
|
||||
{
|
||||
type: "input-date",
|
||||
name: "time",
|
||||
value: time,
|
||||
className: "ae-TimelineItemControlItem-inputDate",
|
||||
label: ""
|
||||
}
|
||||
)} */}
|
||||
|
||||
{amisRender({
|
||||
type: 'dropdown-button',
|
||||
className: 'ae-TimelineItemControlItem-dropdown',
|
||||
btnClassName: 'px-2',
|
||||
icon: 'fa fa-ellipsis-h',
|
||||
hideCaret: true,
|
||||
closeOnClick: true,
|
||||
align: 'right',
|
||||
menuClassName: 'ae-TimelineItemControlItem-ulmenu',
|
||||
buttons: [
|
||||
{
|
||||
type: 'action',
|
||||
className: 'ae-TimelineItemControlItem-action',
|
||||
label: '编辑',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '节点配置',
|
||||
headerClassName: 'font-bold',
|
||||
closeOnEsc: true,
|
||||
closeOnOutside: false,
|
||||
showCloseButton: true,
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
wrapWithPanel: false,
|
||||
wrapperComponent: 'div',
|
||||
resetAfterSubmit: true,
|
||||
autoFocus: true,
|
||||
preventEnterSubmit: true,
|
||||
horizontal: {
|
||||
justify: true,
|
||||
left: 3,
|
||||
right: 9
|
||||
},
|
||||
body: this.buildAddOrEditSchema(props),
|
||||
onSubmit: (e: any) => this.toggleEdit(e, index)
|
||||
},
|
||||
],
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
className: 'ae-TimelineItemControlItem-action',
|
||||
label: '复制',
|
||||
onClick: () => this.toggleCopy(index)
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
className: 'ae-TimelineItemControlItem-action',
|
||||
label: '删除',
|
||||
onClick: () => this.toggleDelete(index)
|
||||
}
|
||||
]
|
||||
})}
|
||||
</div>
|
||||
<div className="ae-TimelineItemControlItem-Main">
|
||||
<InputBox
|
||||
className="ae-TimelineItemControlItem-input-title"
|
||||
value={title}
|
||||
clearable={false}
|
||||
placeholder="请输入标题"
|
||||
onChange={(value: string) => this.handleEditLabel(index, value, 'title')}
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
renderApiPanel() {
|
||||
const {render} = this.props;
|
||||
const {source, api} = this.state;
|
||||
if (source !== 'api') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return render(
|
||||
'api',
|
||||
getSchemaTpl('apiControl', {
|
||||
label: '接口',
|
||||
name: 'source',
|
||||
className: 'ae-ExtendMore',
|
||||
visibleOn: 'data.autoComplete !== false',
|
||||
value: api,
|
||||
onChange: this.handleAPIChange
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {source, items} = this.state;
|
||||
const {render, className} = this.props;
|
||||
return (
|
||||
<div className={cx('ae-TimelineItemControl', className)}>
|
||||
{this.renderHeader()}
|
||||
|
||||
{source === 'custom'
|
||||
? <div className="ae-TimelineItemControl-wrapper">
|
||||
{Array.isArray(items) && items.length ? (
|
||||
<ul className="ae-TimelineItemControl-content" ref={this.dragRef} >
|
||||
{items.map((item: TimelineItem, index: number) =>
|
||||
this.renderOption({...item, index})
|
||||
)}
|
||||
</ul>
|
||||
) : (
|
||||
<div className="ae-TimelineItemControl-placeholder">无选项</div>
|
||||
)}
|
||||
|
||||
<div className="ae-TimelineItemControl-footer">
|
||||
{amisRender(this.buildAddSchema(), {
|
||||
onSubmit: this.handleAdd
|
||||
})}
|
||||
{amisRender(this.buildBatchAddSchema(), {
|
||||
onSubmit: this.handleBatchAdd
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
: null}
|
||||
{this.renderApiPanel()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@FormItem({type: 'ae-timelineItemControl', renderLabel: false})
|
||||
export class TimelineItemControlRenderer extends React.Component<TimelineItemProps> {
|
||||
render() {
|
||||
return <TimelineItemControl {...this.props} />
|
||||
}
|
||||
}
|
@ -1008,3 +1008,16 @@ setSchemaTpl(
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
setSchemaTpl('iconLink', (schema: {name: 'icon' | 'rightIcon', visibleOn: boolean}) => {
|
||||
const {name, visibleOn} = schema;
|
||||
return {
|
||||
name: name,
|
||||
visibleOn,
|
||||
label: '图标',
|
||||
type: 'icon-picker',
|
||||
placeholder: '点击选择图标',
|
||||
clearable: true,
|
||||
description: ''
|
||||
}
|
||||
});
|
||||
|
@ -305,6 +305,15 @@ setSchemaTpl('optionControlV2', {
|
||||
closeDefaultCheck: true // 关闭默认值设置
|
||||
});
|
||||
|
||||
/**
|
||||
* 时间轴组件选项控件
|
||||
*/
|
||||
setSchemaTpl('timelineItemControl', {
|
||||
label: '数据',
|
||||
model: 'normal',
|
||||
type: 'ae-timelineItemControl'
|
||||
});
|
||||
|
||||
setSchemaTpl('treeOptionControl', {
|
||||
label: '数据',
|
||||
mode: 'normal',
|
||||
|
Loading…
Reference in New Issue
Block a user