mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-03 16:07:24 +00:00
220 lines
5.5 KiB
TypeScript
220 lines
5.5 KiB
TypeScript
import React, { PureComponent, Fragment } from 'react';
|
|
|
|
import { Balloon, Badge, Dialog } from '@alifd/next';
|
|
import Editor from '@ali/lowcode-editor-framework';
|
|
import {
|
|
PluginConfig,
|
|
PluginClass,
|
|
} from '@ali/lowcode-editor-framework/lib/definitions';
|
|
import TopIcon from '../TopIcon';
|
|
|
|
import './index.scss';
|
|
|
|
export interface TopPluginProps {
|
|
active?: boolean;
|
|
config: PluginConfig;
|
|
disabled?: boolean;
|
|
editor: Editor;
|
|
locked?: boolean;
|
|
marked?: boolean;
|
|
onClick?: () => void;
|
|
pluginClass: PluginClass | undefined;
|
|
}
|
|
|
|
export interface TopPluginState {
|
|
dialogVisible: boolean;
|
|
}
|
|
|
|
export default class TopPlugin extends PureComponent<
|
|
TopPluginProps,
|
|
TopPluginState
|
|
> {
|
|
static displayName = 'LowcodeTopPlugin';
|
|
|
|
static defaultProps = {
|
|
active: false,
|
|
config: {},
|
|
disabled: false,
|
|
marked: false,
|
|
locked: false,
|
|
onClick: (): void => {},
|
|
};
|
|
|
|
constructor(props, context) {
|
|
super(props, context);
|
|
this.state = {
|
|
dialogVisible: false,
|
|
};
|
|
}
|
|
|
|
componentDidMount(): void {
|
|
const { config, editor } = this.props;
|
|
const pluginKey = config && config.pluginKey;
|
|
if (editor && pluginKey) {
|
|
editor.on(`${pluginKey}.dialog.show`, this.handleShow);
|
|
editor.on(`${pluginKey}.dialog.close`, this.handleClose);
|
|
}
|
|
}
|
|
|
|
componentWillUnmount(): void {
|
|
const { config, editor } = this.props;
|
|
const pluginKey = config && config.pluginKey;
|
|
if (editor && pluginKey) {
|
|
editor.off(`${pluginKey}.dialog.show`, this.handleShow);
|
|
editor.off(`${pluginKey}.dialog.close`, this.handleClose);
|
|
}
|
|
}
|
|
|
|
handleShow = (): void => {
|
|
const { disabled, config, onClick, editor } = this.props;
|
|
const pluginKey = config && config.pluginKey;
|
|
if (disabled || !pluginKey) return;
|
|
this.handleOpen();
|
|
// 考虑到弹窗情况,延时发送消息
|
|
setTimeout((): void => {
|
|
editor.emit(`${pluginKey}.plugin.activate`);
|
|
}, 0);
|
|
onClick && onClick();
|
|
};
|
|
|
|
handleClose = (): void => {
|
|
const { config, editor } = this.props;
|
|
const pluginKey = config && config.pluginKey;
|
|
const plugin = editor.plugins && editor.plugins[pluginKey];
|
|
if (plugin) {
|
|
plugin.close().then((): void => {
|
|
this.setState({
|
|
dialogVisible: false,
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
handleOpen = (): void => {
|
|
// todo dialog类型的插件初始时拿不动插件实例
|
|
this.setState({
|
|
dialogVisible: true,
|
|
});
|
|
};
|
|
|
|
renderIcon = (clickCallback): React.ReactNode => {
|
|
const {
|
|
active,
|
|
disabled,
|
|
marked,
|
|
locked,
|
|
config,
|
|
onClick,
|
|
editor,
|
|
} = this.props;
|
|
const { pluginKey, props } = config || {};
|
|
const { icon, title } = props || {};
|
|
const node = (
|
|
<TopIcon
|
|
className={`lowcode-top-plugin ${pluginKey}`}
|
|
active={active}
|
|
disabled={disabled}
|
|
locked={locked}
|
|
icon={icon}
|
|
title={title}
|
|
onClick={(): void => {
|
|
if (disabled) return;
|
|
// 考虑到弹窗情况,延时发送消息
|
|
setTimeout((): void => {
|
|
editor.emit(`${pluginKey}.plugin.activate`);
|
|
}, 0);
|
|
clickCallback && clickCallback();
|
|
onClick && onClick();
|
|
}}
|
|
/>
|
|
);
|
|
return marked ? <Badge dot>{node}</Badge> : node;
|
|
};
|
|
|
|
render(): React.ReactNode {
|
|
const {
|
|
active,
|
|
marked,
|
|
locked,
|
|
disabled,
|
|
config,
|
|
editor,
|
|
pluginClass: Comp,
|
|
} = this.props;
|
|
const { pluginKey, pluginProps, props, type } = config || {};
|
|
const { onClick, title } = props || {};
|
|
const { dialogVisible } = this.state;
|
|
if (!pluginKey || !type) return null;
|
|
const node = Comp ? (
|
|
<Comp
|
|
editor={editor}
|
|
active={active}
|
|
locked={locked}
|
|
disabled={disabled}
|
|
config={config}
|
|
onClick={(): void => {
|
|
onClick && onClick.call(null, editor);
|
|
}}
|
|
{...pluginProps}
|
|
/>
|
|
) : null;
|
|
|
|
switch (type) {
|
|
case 'LinkIcon':
|
|
return (
|
|
<a {...props.linkProps}>
|
|
{this.renderIcon((): void => {
|
|
onClick && onClick.call(null, editor);
|
|
})}
|
|
</a>
|
|
);
|
|
case 'Icon':
|
|
return this.renderIcon((): void => {
|
|
onClick && onClick.call(null, editor);
|
|
});
|
|
case 'DialogIcon':
|
|
return (
|
|
<Fragment>
|
|
{this.renderIcon((): void => {
|
|
onClick && onClick.call(null, editor);
|
|
this.handleOpen();
|
|
})}
|
|
<Dialog
|
|
onOk={(): void => {
|
|
editor.emit(`${pluginKey}.dialog.onOk`);
|
|
this.handleClose();
|
|
}}
|
|
onCancel={this.handleClose}
|
|
onClose={this.handleClose}
|
|
title={title}
|
|
style={{
|
|
width: 500,
|
|
...(props.dialogProps && props.dialogProps.style),
|
|
}}
|
|
{...props.dialogProps}
|
|
visible={dialogVisible}
|
|
>
|
|
{node}
|
|
</Dialog>
|
|
</Fragment>
|
|
);
|
|
case 'BalloonIcon':
|
|
return (
|
|
<Balloon
|
|
trigger={this.renderIcon((): void => {
|
|
onClick && onClick.call(null, editor);
|
|
})}
|
|
triggerType={['click', 'hover']}
|
|
{...props.balloonProps}
|
|
>
|
|
{node}
|
|
</Balloon>
|
|
);
|
|
case 'Custom':
|
|
return marked ? <Badge dot>{node}</Badge> : node;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
}
|