amis-saas-3413 [Feature] 「组件配置」组件 - Timeline

Change-Id: I1462b5ff3eca959f10bc0250a4cb29d093f54369
This commit is contained in:
liqiu03 2022-06-20 19:26:36 +08:00
parent 493fb90172
commit 38530c2d5a
4 changed files with 173 additions and 21 deletions

View File

@ -136,6 +136,7 @@ import './plugin/WebComponent';
import {GridPlugin} from './plugin/Grid'; import {GridPlugin} from './plugin/Grid';
import './renderer/OptionControl'; import './renderer/OptionControl';
import './renderer/TimelineItemControl';
import './renderer/APIControl'; import './renderer/APIControl';
import './renderer/ValidationControl'; import './renderer/ValidationControl';
import './renderer/ValidationItem'; import './renderer/ValidationItem';

View File

@ -0,0 +1,146 @@
import React from 'react';
import {getEventControlConfig} from '../util';
import {registerEditorPlugin, getSchemaTpl} from 'amis-editor-core';
import { RendererAction, 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
};
// 事件定义
events: RendererEvent[] = [
{
eventName: 'add',
eventLabel: '新增选项',
description: '新增选项'
},
{
eventName: 'edit',
eventLabel: '编辑选项',
description: '编辑选项'
},
{
eventName: 'delete',
eventLabel: '删除选项',
description: '删除选项'
}
];
panelTitle = '时间轴';
panelJustify = true;
panelBodyCreator = (context: BaseEventContext) =>
getSchemaTpl('tabs', [
{
title: '属性',
body: getSchemaTpl('collapseGroup', [
{
title: '基本',
body: [
getSchemaTpl('formItemName', {
required: true
}),
getSchemaTpl('label'),
getSchemaTpl('labelRemark'),
getSchemaTpl('remark'),
getSchemaTpl('description')
]
},
{
title: '数据',
body: [
getSchemaTpl('timelineItemControl', {
name: 'items',
mode: 'normal',
}),
{
label: '方向',
name: 'direction',
value: 'vertical',
type: 'button-group-select',
inline: true,
options: [
{label: '垂直', value: 'vertical'},
{label: '水平', value: 'horizontal'}
],
},
{
label: '排序',
name: 'reverse',
value: false,
type: 'button-group-select',
inline: false,
options: [
{label: '正序', value: false},
{label: '反序', value: true}
]
},
{
label: '文字方向',
name: 'mode',
value: 'right',
type: 'button-group-select',
visibleOn: 'data.direction === "vertical"',
options: [
{label: '偏左', value: 'right'},
{label: '偏右', value: 'left'},
{label: '左右交替', value: 'alternate'},
]
}
]
},
getSchemaTpl('status', {isFormItem: true})
])
},
{
title: '外观',
body: getSchemaTpl('collapseGroup', [
{
title: '样式',
body: [
{
name: 'className',
label: '外层class',
type: 'input-text',
placeholder: '请输入className'
},
]
},
getSchemaTpl('status')
])
},
{
title: '事件',
className: 'p-none',
body: [
getSchemaTpl('eventControl',{
name: 'onEvent',
...getEventControlConfig(this.manager, context)
})
]
}
]);
}
registerEditorPlugin(TimelinePlugin);

View File

@ -9,17 +9,13 @@ import Sortable from 'sortablejs';
import { import {
render as amisRender, render as amisRender,
FormItem, FormItem,
Button,
Checkbox,
Icon, Icon,
InputBox, InputBox
SchemaApi
} from 'amis'; } from 'amis';
import {autobind} from '../../util'; import {autobind} from 'amis-editor-core';
import {getSchemaTpl} from '../../component/schemaTpl'; import {getSchemaTpl} from 'amis-editor-core';
import {tipedLabel} from '../../component/control/BaseControl'; import type {FormControlProps} from 'amis-core';
import type {FormControlProps} from 'amis/lib/renderers/Form/Item'; import {SchemaApi} from 'amis/lib/Schema';
import { boolean } from 'mobx-state-tree/dist/internal';
type TimelineItem = { type TimelineItem = {
title: string; title: string;
@ -213,7 +209,7 @@ export default class TimelineItemControl extends React.Component<
}, },
{ {
visibleOn: 'this["otherConfig"]', visibleOn: 'this["otherConfig"]',
type: 'icon-text', type: 'input-text',
name: 'icon', name: 'icon',
value: props?.['icon'], value: props?.['icon'],
placeholder: '请输入', placeholder: '请输入',
@ -322,12 +318,12 @@ export default class TimelineItemControl extends React.Component<
const dom = findDOMNode(this) as HTMLElement; const dom = findDOMNode(this) as HTMLElement;
this.sortable = new Sortable( this.sortable = new Sortable(
dom.querySelector('.ae-OptionControl-content') as HTMLElement, dom.querySelector('.ae-TimelineItemControl-content') as HTMLElement,
{ {
group: 'OptionControlGroup', group: 'TimelineItemControlGroup',
animation: 150, animation: 150,
handle: '.ae-OptionControlItem-dragBar', handle: '.ae-TimelineItemControlItem-dragBar',
ghostClass: 'ae-OptionControlItem--dragging', ghostClass: 'ae-TimelineItemControlItem--dragging',
onEnd: (e: any) => { onEnd: (e: any) => {
// 没有移动 // 没有移动
if (e.newIndex === e.oldIndex) { if (e.newIndex === e.oldIndex) {
@ -391,7 +387,7 @@ export default class TimelineItemControl extends React.Component<
})); }));
return ( return (
<header className="ae-OptionControl-header"> <header className="ae-TimelineItemControl-header">
<label className={cx(`${classPrefix}Form-label`)}> <label className={cx(`${classPrefix}Form-label`)}>
{label || ''} {label || ''}
{labelRemark {labelRemark
@ -531,7 +527,7 @@ export default class TimelineItemControl extends React.Component<
renderApiPanel() { renderApiPanel() {
const {render} = this.props; const {render} = this.props;
const {source, api, labelField, valueField} = this.state; const {source, api} = this.state;
if (source !== 'api') { if (source !== 'api') {
return null; return null;
} }
@ -553,22 +549,22 @@ export default class TimelineItemControl extends React.Component<
const {source, items} = this.state; const {source, items} = this.state;
const {render, className} = this.props; const {render, className} = this.props;
return ( return (
<div className={cx('ae-OptionControl ae-TimelineItemControl', className)}> <div className={cx('ae-TimelineItemControl', className)}>
{this.renderHeader()} {this.renderHeader()}
{source === 'custom' {source === 'custom'
? <div className="ae-OptionControl-wrapper ae-TimelineItemControl-wrapper"> ? <div className="ae-TimelineItemControl-wrapper">
{Array.isArray(items) && items.length ? ( {Array.isArray(items) && items.length ? (
<ul className="ae-OptionControl-content ae-TimelineItemControl-content" ref={this.dragRef} > <ul className="ae-TimelineItemControl-content" ref={this.dragRef} >
{items.map((item: TimelineItem, index: number) => {items.map((item: TimelineItem, index: number) =>
this.renderOption({...item, index}) this.renderOption({...item, index})
)} )}
</ul> </ul>
) : ( ) : (
<div className="ae-OptionControl-placeholder"></div> <div className="ae-TimelineItemControl-placeholder"></div>
)} )}
<div className="ae-OptionControl-footer"> <div className="ae-TimelineItemControl-footer">
{amisRender(this.buildAddSchema(), { {amisRender(this.buildAddSchema(), {
onSubmit: this.handleAdd onSubmit: this.handleAdd
})} })}

View File

@ -298,3 +298,12 @@ setSchemaTpl('optionControlV2', {
type: 'ae-optionControl', type: 'ae-optionControl',
closeDefaultCheck: true // 关闭默认值设置 closeDefaultCheck: true // 关闭默认值设置
}); });
/**
*
*/
setSchemaTpl('timelineItemControl', {
label: '数据',
model: 'normal',
type: 'ae-timelineItemControl'
});