mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-15 05:36:39 +00:00
daily tag
This commit is contained in:
parent
dd0ee40b8e
commit
7f90b0baa5
@ -4,9 +4,13 @@ module.exports = deepmerge(tslint, {
|
||||
rules: {
|
||||
"global-require": 0,
|
||||
"comma-dangle": 0,
|
||||
"no-unused-expressions": 0,
|
||||
"object-shorthand": 0,
|
||||
"jsx-a11y/anchor-has-content": 0,
|
||||
"react/sort-comp": 0,
|
||||
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".tsx", "ts"] }],
|
||||
"@typescript-eslint/interface-name-prefix": 0,
|
||||
"@typescript-eslint/no-explicit-any": 0
|
||||
"@typescript-eslint/no-explicit-any": 0,
|
||||
"@typescript-eslint/explicit-member-accessibility": 0
|
||||
},
|
||||
});
|
||||
|
||||
@ -5,7 +5,10 @@ export default {
|
||||
title: 'fusion组件库',
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
urls: ['https://unpkg.antfin-inc.com/@alife/next@1.19.18/dist/next.js', 'https://unpkg.antfin-inc.com/@alife/next@1.19.18/dist/next.css'],
|
||||
urls: [
|
||||
'https://unpkg.antfin-inc.com/@alife/next@1.19.18/dist/next.js',
|
||||
'https://unpkg.antfin-inc.com/@alife/next@1.19.18/dist/next.css'
|
||||
],
|
||||
library: 'Next'
|
||||
}
|
||||
},
|
||||
@ -13,114 +16,137 @@ export default {
|
||||
Button: {
|
||||
componentName: 'Button',
|
||||
title: '按钮',
|
||||
devMode:'proCode',
|
||||
devMode: 'proCode',
|
||||
npm: {
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
destructuring: true,
|
||||
exportName: 'Button'
|
||||
},
|
||||
props: [{
|
||||
name: 'type',
|
||||
propType: 'string'
|
||||
}, {
|
||||
name: 'children',
|
||||
propType: 'string'
|
||||
}],
|
||||
configure: {
|
||||
props: [{
|
||||
props: [
|
||||
{
|
||||
name: 'type',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
}
|
||||
}, {
|
||||
propType: 'string'
|
||||
},
|
||||
{
|
||||
name: 'children',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
configure: {
|
||||
props: [
|
||||
{
|
||||
name: 'type',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'children',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
},
|
||||
Input: {
|
||||
componentName: 'Input',
|
||||
title: '输入框',
|
||||
devMode:'proCode',
|
||||
devMode: 'proCode',
|
||||
npm: {
|
||||
package: '@alifd/next',
|
||||
version: '1.19.18',
|
||||
destructuring: true,
|
||||
exportName: 'Input'
|
||||
},
|
||||
props: [{
|
||||
name: 'placeholder',
|
||||
propType: 'string'
|
||||
}],
|
||||
configure: {
|
||||
props: [{
|
||||
props: [
|
||||
{
|
||||
name: 'placeholder',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
propType: 'string'
|
||||
}
|
||||
],
|
||||
configure: {
|
||||
props: [
|
||||
{
|
||||
name: 'placeholder',
|
||||
setter: {
|
||||
componentName: 'Input'
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
componentList: [{
|
||||
title: '基础',
|
||||
icon: '',
|
||||
children: [{
|
||||
componentName: 'Button',
|
||||
title: '按钮',
|
||||
componentList: [
|
||||
{
|
||||
title: '基础',
|
||||
icon: '',
|
||||
package: '@alife/next',
|
||||
snippets: [{
|
||||
title: 'private',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
children: [
|
||||
{
|
||||
componentName: 'Button',
|
||||
props: {
|
||||
type: 'primary'
|
||||
},
|
||||
children: 'Primary'
|
||||
title: '按钮',
|
||||
icon: '',
|
||||
package: '@alife/next',
|
||||
snippets: [
|
||||
{
|
||||
title: 'private',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
componentName: 'Button',
|
||||
props: {
|
||||
type: 'primary'
|
||||
},
|
||||
children: 'Primary'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'secondary',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
componentName: 'Button',
|
||||
props: {
|
||||
type: 'secondary'
|
||||
},
|
||||
children: 'secondary'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'normal',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
componentName: 'Button',
|
||||
props: {
|
||||
type: 'normal'
|
||||
},
|
||||
children: 'normal'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}, {
|
||||
title: 'secondary',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
componentName: 'Button',
|
||||
props: {
|
||||
type: 'secondary'
|
||||
},
|
||||
children: 'secondary'
|
||||
}
|
||||
}, {
|
||||
title: 'normal',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
componentName: 'Button',
|
||||
props: {
|
||||
type: 'normal'
|
||||
},
|
||||
children: 'normal'
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
title: '表单',
|
||||
icon: '',
|
||||
children: [{
|
||||
componentName: 'Input',
|
||||
title: '输入框',
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '表单',
|
||||
icon: '',
|
||||
package: '@alife/next',
|
||||
snippets: [{
|
||||
title: '普通',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
children: [
|
||||
{
|
||||
componentName: 'Input',
|
||||
props: {}
|
||||
title: '输入框',
|
||||
icon: '',
|
||||
package: '@alife/next',
|
||||
snippets: [
|
||||
{
|
||||
title: '普通',
|
||||
screenshort: '',
|
||||
schema: {
|
||||
componentName: 'Input',
|
||||
props: {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@ -4,13 +4,17 @@ import { registerSetter } from '../../../plugin-settings/src';
|
||||
import { createElement } from 'react';
|
||||
|
||||
registerSetter('ClassNameSetter', () => {
|
||||
return createElement('div', {
|
||||
className: 'lc-block-setter'
|
||||
}, '这里是类名绑定');
|
||||
return createElement(
|
||||
'div',
|
||||
{
|
||||
className: 'lc-block-setter'
|
||||
},
|
||||
'这里是类名绑定'
|
||||
);
|
||||
});
|
||||
|
||||
registerSetter('EventsSetter', Input);
|
||||
|
||||
registerSetter('StringSetter', { component: Input, props: { placeholder: "请输入" } });
|
||||
registerSetter('StringSetter', { component: Input, props: { placeholder: '请输入' } });
|
||||
|
||||
registerSetter('NumberSetter', NumberSetter as any);
|
||||
|
||||
@ -111,7 +111,7 @@ export default {
|
||||
title: 'icon',
|
||||
icon: 'dengpao',
|
||||
onClick(editor) {
|
||||
alert(`icon addon invoke, current activeKey: ${ editor.activeKey}`);
|
||||
alert(`icon addon invoke, current activeKey: ${editor.activeKey}`);
|
||||
}
|
||||
},
|
||||
config: {},
|
||||
@ -128,8 +128,8 @@ export default {
|
||||
title: '组件库'
|
||||
},
|
||||
config: {
|
||||
package: "@ali/iceluna-addon-component-list",
|
||||
version: "^1.0.4"
|
||||
package: '@ali/iceluna-addon-component-list',
|
||||
version: '^1.0.4'
|
||||
},
|
||||
pluginProps: {
|
||||
disableAppComponent: true
|
||||
@ -218,7 +218,7 @@ export default {
|
||||
title: 'icon',
|
||||
icon: 'dengpao',
|
||||
onClick(editor) {
|
||||
alert(`icon addon invoke, current activeKey: ${ editor.activeKey}`);
|
||||
alert(`icon addon invoke, current activeKey: ${editor.activeKey}`);
|
||||
}
|
||||
},
|
||||
config: {},
|
||||
@ -234,52 +234,52 @@ export default {
|
||||
version: '^1.0.0'
|
||||
},
|
||||
pluginProps: {}
|
||||
},
|
||||
{
|
||||
pluginKey: 'rightPanel1',
|
||||
type: 'TabPanel',
|
||||
props: {
|
||||
title: '样式'
|
||||
},
|
||||
config: {
|
||||
version: '^1.0.0'
|
||||
},
|
||||
pluginProps: {}
|
||||
},
|
||||
{
|
||||
pluginKey: 'rightPanel2',
|
||||
type: 'TabPanel',
|
||||
props: {
|
||||
title: '属性',
|
||||
icon: 'dengpao'
|
||||
},
|
||||
config: {
|
||||
version: '^1.0.0'
|
||||
},
|
||||
pluginProps: {}
|
||||
},
|
||||
{
|
||||
pluginKey: 'rightPanel3',
|
||||
type: 'TabPanel',
|
||||
props: {
|
||||
title: '事件'
|
||||
},
|
||||
config: {
|
||||
version: '^1.0.0'
|
||||
},
|
||||
pluginProps: {}
|
||||
},
|
||||
{
|
||||
pluginKey: 'rightPanel4',
|
||||
type: 'TabPanel',
|
||||
props: {
|
||||
title: '数据'
|
||||
},
|
||||
config: {
|
||||
version: '^1.0.0'
|
||||
},
|
||||
pluginProps: {}
|
||||
}
|
||||
// {
|
||||
// pluginKey: 'rightPanel1',
|
||||
// type: 'TabPanel',
|
||||
// props: {
|
||||
// title: '样式'
|
||||
// },
|
||||
// config: {
|
||||
// version: '^1.0.0'
|
||||
// },
|
||||
// pluginProps: {}
|
||||
// },
|
||||
// {
|
||||
// pluginKey: 'rightPanel2',
|
||||
// type: 'TabPanel',
|
||||
// props: {
|
||||
// title: '属性',
|
||||
// icon: 'dengpao'
|
||||
// },
|
||||
// config: {
|
||||
// version: '^1.0.0'
|
||||
// },
|
||||
// pluginProps: {}
|
||||
// },
|
||||
// {
|
||||
// pluginKey: 'rightPanel3',
|
||||
// type: 'TabPanel',
|
||||
// props: {
|
||||
// title: '事件'
|
||||
// },
|
||||
// config: {
|
||||
// version: '^1.0.0'
|
||||
// },
|
||||
// pluginProps: {}
|
||||
// },
|
||||
// {
|
||||
// pluginKey: 'rightPanel4',
|
||||
// type: 'TabPanel',
|
||||
// props: {
|
||||
// title: '数据'
|
||||
// },
|
||||
// config: {
|
||||
// version: '^1.0.0'
|
||||
// },
|
||||
// pluginProps: {}
|
||||
// }
|
||||
],
|
||||
centerArea: [
|
||||
{
|
||||
@ -295,7 +295,7 @@ export default {
|
||||
shortCuts: [],
|
||||
lifeCycles: {
|
||||
init: function init(editor) {
|
||||
const transformMaterial = (componentList) => {
|
||||
const transformMaterial = componentList => {
|
||||
return componentList.map(category => {
|
||||
return {
|
||||
name: category.title,
|
||||
@ -318,17 +318,25 @@ export default {
|
||||
};
|
||||
|
||||
const list = transformMaterial(assets.componentList);
|
||||
console.log('+++++', list);
|
||||
editor.set({
|
||||
componentsMap: assets.components,
|
||||
componentMaterial: {
|
||||
library: [{
|
||||
name: 'Fusion组件库',
|
||||
id: 1
|
||||
}],
|
||||
library: [
|
||||
{
|
||||
name: 'Fusion组件库',
|
||||
id: 1
|
||||
}
|
||||
],
|
||||
list
|
||||
}
|
||||
});
|
||||
|
||||
editor.set('dndHelper', {
|
||||
handleResourceDragStart: function(ev, tagName, schema) {
|
||||
// 物料面板中组件snippet的dragStart回调
|
||||
// ev: 原始的domEvent;tagName: 组件的描述文案;schema: snippet的schema
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -22,7 +22,9 @@ export default class AreaManager {
|
||||
const { pluginStatus } = this.editor;
|
||||
const list = pluginType ? this.config.filter((item): boolean => item.type === pluginType) : this.config;
|
||||
|
||||
const isUpdate = list.some((item): boolean => !deepEqual(pluginStatus[item.pluginKey], this.pluginStatus[item.pluginKey]));
|
||||
const isUpdate = list.some(
|
||||
(item): boolean => !deepEqual(pluginStatus[item.pluginKey], this.pluginStatus[item.pluginKey])
|
||||
);
|
||||
this.pluginStatus = clone(pluginStatus);
|
||||
return isUpdate;
|
||||
}
|
||||
|
||||
@ -106,34 +106,37 @@ export interface I18nConfig {
|
||||
'ja-JP'?: I18nMessages;
|
||||
}
|
||||
|
||||
export type I18nFunction = (key: string, params: any) => string | string[];
|
||||
export type I18nFunction = (key: string, params: any) => string;
|
||||
|
||||
export interface Utils {
|
||||
[key: string]: (...args) => any;
|
||||
}
|
||||
|
||||
|
||||
export interface PluginProps {
|
||||
editor: Editor;
|
||||
config: PluginConfig;
|
||||
i18n: I18nFunction;
|
||||
ref?: React.RefObject<Plugin>;
|
||||
i18n?: I18nFunction;
|
||||
ref?: React.RefObject<React.ReactElement>;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
||||
export type Plugin = React.ReactNode & {
|
||||
open?: () => boolean| void| Promise<any>;
|
||||
close?: () => boolean| void| Promise<any>;
|
||||
}
|
||||
open?: () => boolean | void | Promise<any>;
|
||||
close?: () => boolean | void | Promise<any>;
|
||||
};
|
||||
|
||||
export type HOCPlugin = React.ReactNode & {
|
||||
open: () => Promise<any>;
|
||||
close: () => Promise<any>;
|
||||
};
|
||||
|
||||
export interface PluginSet {
|
||||
[key: string]: Plugin;
|
||||
[key: string]: HOCPlugin;
|
||||
}
|
||||
|
||||
export type PluginClass = React.ComponentType<PluginProps> & {
|
||||
init?: (editor: Editor) => void;
|
||||
}
|
||||
};
|
||||
|
||||
export interface PluginClassSet {
|
||||
[key: string]: PluginClass;
|
||||
@ -149,4 +152,3 @@ export interface PluginStatus {
|
||||
export interface PluginStatusSet {
|
||||
[key: string]: PluginStatus;
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,26 @@
|
||||
import Debug from 'debug';
|
||||
import EventEmitter from 'events';
|
||||
import store from 'store';
|
||||
import { EditorConfig, HooksConfig, LocaleType, PluginStatusSet, Utils, PluginClassSet, PluginSet } from './definitions';
|
||||
import {
|
||||
EditorConfig,
|
||||
HooksConfig,
|
||||
LocaleType,
|
||||
PluginStatusSet,
|
||||
Utils,
|
||||
PluginClassSet,
|
||||
PluginSet
|
||||
} from './definitions';
|
||||
|
||||
import * as editorUtils from './utils';
|
||||
|
||||
const {
|
||||
registShortCuts, transformToPromise, unRegistShortCuts
|
||||
} = editorUtils;
|
||||
const { registShortCuts, transformToPromise, unRegistShortCuts } = editorUtils;
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__isDebug?: boolean;
|
||||
__newFunc?: (funcStr: string) => (...args: any[]) => any;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据url参数设置debug选项
|
||||
const debugRegRes = /_?debug=(.*?)(&|$)/.exec(location.search);
|
||||
@ -16,6 +29,7 @@ if (debugRegRes && debugRegRes[1]) {
|
||||
window.__isDebug = true;
|
||||
store.storage.write('debug', debugRegRes[1] === 'true' ? '*' : debugRegRes[1]);
|
||||
} else {
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
window.__isDebug = false;
|
||||
store.remove('debug');
|
||||
}
|
||||
@ -23,13 +37,12 @@ if (debugRegRes && debugRegRes[1]) {
|
||||
// 重要,用于矫正画布执行new Function的window对象上下文
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
window.__newFunc = (funContext: string): ((...args: any[]) => any) => {
|
||||
return new Function(funContext);
|
||||
// eslint-disable-next-line no-new-func
|
||||
return new Function(funContext) as (...args: any[]) => any;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 关闭浏览器前提醒,只有产生过交互才会生效
|
||||
window.onbeforeunload = function(e: Event): string|void {
|
||||
window.onbeforeunload = function(e: Event): string | void {
|
||||
const ev = e || window.event;
|
||||
// 本地调试不生效
|
||||
if (location.href.indexOf('localhost') > 0) {
|
||||
@ -72,7 +85,6 @@ export default class Editor extends EventEmitter {
|
||||
|
||||
public plugins: PluginSet;
|
||||
|
||||
|
||||
public locale: LocaleType;
|
||||
|
||||
public emit: (msg: string, ...args) => void;
|
||||
@ -89,7 +101,7 @@ export default class Editor extends EventEmitter {
|
||||
super();
|
||||
this.config = config;
|
||||
this.components = components;
|
||||
this.utils = {...editorUtils, ...utils};
|
||||
this.utils = { ...editorUtils, ...utils };
|
||||
instance = this;
|
||||
this.init();
|
||||
}
|
||||
@ -128,7 +140,6 @@ export default class Editor extends EventEmitter {
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
4
packages/editor/src/framework/index.d.ts
vendored
4
packages/editor/src/framework/index.d.ts
vendored
@ -1,4 +0,0 @@
|
||||
interface Window {
|
||||
__isDebug?: boolean;
|
||||
__newFunc?: (funcStr: string) => ((...args: any[]) => any);
|
||||
}
|
||||
@ -1,30 +1,19 @@
|
||||
import React, { createRef, PureComponent } from 'react';
|
||||
|
||||
import EditorContext from './context';
|
||||
import { I18nFunction, PluginConfig, PluginClass, Plugin } from './definitions';
|
||||
import { I18nFunction, PluginProps, PluginClass, Plugin } from './definitions';
|
||||
import Editor from './editor';
|
||||
import { acceptsRef, generateI18n, isEmpty, transformToPromise } from './utils';
|
||||
|
||||
export interface PluginProps {
|
||||
editor: Editor;
|
||||
config: PluginConfig;
|
||||
}
|
||||
|
||||
export interface InjectedPluginProps {
|
||||
i18n?: I18nFunction;
|
||||
}
|
||||
|
||||
export default function pluginFactory(
|
||||
Comp: PluginClass
|
||||
): React.ComponentType<PluginProps> {
|
||||
export default function pluginFactory(Comp: PluginClass): React.ComponentType<PluginProps> {
|
||||
class LowcodePlugin extends PureComponent<PluginProps> {
|
||||
public static displayName = 'LowcodeEditorPlugin';
|
||||
|
||||
public static contextType = EditorContext;
|
||||
|
||||
public static init = Comp.init;
|
||||
|
||||
public ref: React.RefObject<Plugin>;
|
||||
|
||||
public ref: React.RefObject<React.ReactElement> & Plugin;
|
||||
|
||||
private editor: Editor;
|
||||
|
||||
@ -39,7 +28,7 @@ export default function pluginFactory(
|
||||
return;
|
||||
}
|
||||
const { locale, messages, editor } = props;
|
||||
this.ref = createRef<Plugin>();
|
||||
this.ref = createRef<React.ReactElement>();
|
||||
// 注册插件
|
||||
this.editor = editor;
|
||||
this.i18n = generateI18n(locale, messages);
|
||||
@ -71,7 +60,6 @@ export default function pluginFactory(
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
|
||||
public render(): React.ReactNode {
|
||||
const { config } = this.props;
|
||||
const props = {
|
||||
|
||||
@ -28,6 +28,17 @@ const ENV = {
|
||||
WEB: 'WEB'
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
sendIDEMessage?: (params: IDEMessageParams) => void;
|
||||
goldlog?: {
|
||||
record: (logKey: string, gmKey: string, goKey: string, method: 'POST' | 'GET') => (...args: any[]) => any;
|
||||
};
|
||||
is_theia?: boolean;
|
||||
vscode?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IDEMessageParams {
|
||||
action: string;
|
||||
data: {
|
||||
@ -37,16 +48,11 @@ export interface IDEMessageParams {
|
||||
};
|
||||
}
|
||||
|
||||
export interface Window {
|
||||
sendIDEMessage: (msg: IDEMessageParams) => void;
|
||||
is_theia?: boolean;
|
||||
}
|
||||
|
||||
/*
|
||||
* 用于构造国际化字符串处理函数
|
||||
*/
|
||||
export function generateI18n(locale: LocaleType = 'zh-CN', messages: I18nMessages = {}): I18nFunction {
|
||||
return (key: string, values): string | string[] => {
|
||||
return (key: string, values): string => {
|
||||
if (!messages || !messages[key]) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@ -10,12 +10,9 @@ import constants from './config/constants';
|
||||
import './config/locale';
|
||||
import './config/setters';
|
||||
|
||||
import pkg from '../package.json';
|
||||
import './global.scss';
|
||||
import './config/theme.scss';
|
||||
|
||||
(window as any).__pkg = pkg;
|
||||
|
||||
const ICE_CONTAINER = document.getElementById('ice-container');
|
||||
|
||||
if (!ICE_CONTAINER) {
|
||||
@ -26,7 +23,7 @@ ReactDOM.render(
|
||||
<Router>
|
||||
<Route
|
||||
path="/*"
|
||||
component={props => (
|
||||
component={(props): React.ReactNode => (
|
||||
<Skeleton
|
||||
{...props}
|
||||
{...(config.skeleton && config.skeleton.props)}
|
||||
|
||||
@ -163,19 +163,15 @@ const SCHEMA = {
|
||||
};
|
||||
|
||||
export default class DesignerPlugin extends PureComponent<PluginProps> {
|
||||
static displayName: 'LowcodePluginDesigner';
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
displayName: 'LowcodePluginDesigner';
|
||||
|
||||
handleDesignerMount = (designer): void => {
|
||||
const {editor} = this.props;
|
||||
const { editor } = this.props;
|
||||
editor.set('designer', designer);
|
||||
editor.emit('designer.ready', designer);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const { editor } = this.props;
|
||||
return (
|
||||
<Designer
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
import React from 'react';
|
||||
import './index.scss';
|
||||
import Editor from '../../framework/index';
|
||||
import { PluginConfig } from '../../framework/definitions';
|
||||
import { PluginProps } from '../../framework/definitions';
|
||||
|
||||
export interface PluginProps {
|
||||
editor: Editor;
|
||||
config: PluginConfig;
|
||||
export interface IProps {
|
||||
logo?: string;
|
||||
href?: string;
|
||||
}
|
||||
|
||||
export default function(props: PluginProps) {
|
||||
const Logo: React.FC<IProps & PluginProps> = (props): React.ReactElement => {
|
||||
return (
|
||||
<div className="lowcode-plugin-logo">
|
||||
<a className="logo" target="blank" href={props.href || '/'} style={{ backgroundImage: `url(${props.logo})` }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Logo;
|
||||
|
||||
@ -1,70 +1,74 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import './index.scss';
|
||||
import Editor from '../../framework/index';
|
||||
import { PluginConfig } from '../../framework/definitions';
|
||||
import { PluginProps } from '../../framework/definitions';
|
||||
import TopIcon from '../../skeleton/components/TopIcon/index';
|
||||
|
||||
export interface PluginProps {
|
||||
editor: Editor;
|
||||
config: PluginConfig;
|
||||
export interface IProps {
|
||||
logo?: string;
|
||||
}
|
||||
|
||||
export interface PluginState{
|
||||
backEnable: boolean;
|
||||
forwardEnable: boolean;
|
||||
};
|
||||
export interface IState {
|
||||
undoEnable: boolean;
|
||||
redoEnable: boolean;
|
||||
}
|
||||
|
||||
export default class UndoRedo extends PureComponent<IProps & PluginProps, IState> {
|
||||
public static display = 'LowcodeUndoRedo';
|
||||
|
||||
export default class UndoRedo extends PureComponent<PluginProps, PluginState> {
|
||||
static display = 'LowcodeUndoRedo';
|
||||
private history: any;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
backEnable: false,
|
||||
forwardEnable: false
|
||||
undoEnable: false,
|
||||
redoEnable: false
|
||||
};
|
||||
if (props.editor.designer) {
|
||||
this.init();
|
||||
} else {
|
||||
props.editor.on('designer.ready', () => {
|
||||
props.editor.on('designer.ready', (): void => {
|
||||
this.init();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
init = (): void => {
|
||||
const {editor} = this.props;
|
||||
this.designer = editor.designer;
|
||||
this.history = this.designer.currentHistory;
|
||||
editor.on('designer.history-change', (history) => {
|
||||
const { editor } = this.props;
|
||||
this.history = editor.designer.currentHistory;
|
||||
this.updateState(this.history.getState());
|
||||
editor.on('designer.history-change', (history): void => {
|
||||
this.history = history;
|
||||
this.history.onStateChange(this.updateState);
|
||||
});
|
||||
this.history.onStateChange(this.updateState);
|
||||
};
|
||||
|
||||
updateState = (state: number): void => {
|
||||
console.log('++++', !!(state & 1), !!(state & 2));
|
||||
this.setState({
|
||||
undoEnable: !!(state & 1),
|
||||
redoEnable: !!(state & 2)
|
||||
});
|
||||
};
|
||||
|
||||
handleBackClick = (): void => {
|
||||
handleUndoClick = (): void => {
|
||||
if (this.history) {
|
||||
this.history.back();
|
||||
}
|
||||
};
|
||||
|
||||
handleForwardClick = (): void => {
|
||||
handleRedoClick = (): void => {
|
||||
if (this.history) {
|
||||
this.history.forward();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
backEnable,
|
||||
forwardEnable
|
||||
} = this.state;
|
||||
render(): React.ReactNode {
|
||||
const { undoEnable, redoEnable } = this.state;
|
||||
return (
|
||||
<div className="lowcode-plugin-undo-redo">
|
||||
<TopIcon icon="houtui" title="后退" onClick={this.handleBackClick}/>
|
||||
<TopIcon icon="qianjin" title="前进" onClick={this.handleForwardClick}/>
|
||||
<TopIcon icon="houtui" title="后退" disabled={!undoEnable} onClick={this.handleUndoClick} />
|
||||
<TopIcon icon="qianjin" title="前进" disabled={!redoEnable} onClick={this.handleRedoClick} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
}
|
||||
&:hover {
|
||||
color: $color-brand1-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
|
||||
@ -30,7 +30,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
disabled: false,
|
||||
marked: false,
|
||||
locked: false,
|
||||
onClick: () => {}
|
||||
onClick: (): void => {}
|
||||
};
|
||||
|
||||
constructor(props, context) {
|
||||
@ -40,7 +40,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
const { config, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
if (editor && pluginKey) {
|
||||
@ -49,7 +49,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
const { config, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
if (editor && pluginKey) {
|
||||
@ -58,12 +58,12 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
}
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
handleClose = (): void => {
|
||||
const { config, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
const plugin = editor.plugins && editor.plugins[pluginKey];
|
||||
if (plugin) {
|
||||
plugin.close().then(() => {
|
||||
if (plugin && plugin.close) {
|
||||
plugin.close().then((): void => {
|
||||
this.setState({
|
||||
dialogVisible: false
|
||||
});
|
||||
@ -71,24 +71,26 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
}
|
||||
};
|
||||
|
||||
handleOpen = () => {
|
||||
handleOpen = (): void => {
|
||||
// todo 对话框类型的插件初始时拿不到插件实例
|
||||
this.setState({
|
||||
dialogVisible: true
|
||||
});
|
||||
};
|
||||
|
||||
handleShow = () => {
|
||||
handleShow = (): void => {
|
||||
const { disabled, config, onClick, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
if (disabled || !pluginKey) return;
|
||||
// 考虑到弹窗情况,延时发送消息
|
||||
setTimeout(() => editor.emit(`${pluginKey}.addon.activate`), 0);
|
||||
setTimeout((): void => editor.emit(`${pluginKey}.plugin.activate`), 0);
|
||||
this.handleOpen();
|
||||
onClick && onClick();
|
||||
if (onClick) {
|
||||
onClick();
|
||||
}
|
||||
};
|
||||
|
||||
renderIcon = clickCallback => {
|
||||
renderIcon = (clickCallback): React.ReactNode => {
|
||||
const { active, disabled, marked, locked, onClick, config } = this.props;
|
||||
const { pluginKey, props } = config || {};
|
||||
const { icon, title } = props || {};
|
||||
@ -100,10 +102,11 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
locked
|
||||
})}
|
||||
data-tooltip={title}
|
||||
onClick={() => {
|
||||
onClick={(): void => {
|
||||
if (disabled) return;
|
||||
// 考虑到弹窗情况,延时发送消息
|
||||
clickCallback && clickCallback();
|
||||
|
||||
onClick && onClick();
|
||||
}}
|
||||
>
|
||||
@ -118,7 +121,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const { marked, locked, active, disabled, config, editor, pluginClass: Comp } = this.props;
|
||||
const { pluginKey, props, type, pluginProps } = config || {};
|
||||
const { onClick, title } = props || {};
|
||||
@ -133,7 +136,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
locked={locked}
|
||||
disabled={disabled}
|
||||
config={config}
|
||||
onClick={() => {
|
||||
onClick={(): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
}}
|
||||
{...pluginProps}
|
||||
@ -145,24 +148,24 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
case 'LinkIcon':
|
||||
return (
|
||||
<a {...(props.linkProps || {})}>
|
||||
{this.renderIcon(() => {
|
||||
{this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
})}
|
||||
</a>
|
||||
);
|
||||
case 'Icon':
|
||||
return this.renderIcon(() => {
|
||||
return this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
});
|
||||
case 'DialogIcon':
|
||||
return (
|
||||
<Fragment>
|
||||
{this.renderIcon(() => {
|
||||
{this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
this.handleOpen();
|
||||
})}
|
||||
<Dialog
|
||||
onOk={() => {
|
||||
onOk={(): void => {
|
||||
editor.emit(`${pluginKey}.dialog.onOk`);
|
||||
this.handleClose();
|
||||
}}
|
||||
@ -171,7 +174,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
title={title}
|
||||
style={{
|
||||
width: 500,
|
||||
...(props && props.style)
|
||||
...(props.dialogProps && props.dialogProps.style)
|
||||
}}
|
||||
{...(props.dialogProps || {})}
|
||||
visible={dialogVisible}
|
||||
@ -183,7 +186,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
case 'BalloonIcon':
|
||||
return (
|
||||
<Balloon
|
||||
trigger={this.renderIcon(() => {
|
||||
trigger={this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
})}
|
||||
align="r"
|
||||
@ -194,7 +197,7 @@ export default class LeftPlugin extends PureComponent<LeftPluginProps, LeftPlugi
|
||||
</Balloon>
|
||||
);
|
||||
case 'PanelIcon':
|
||||
return this.renderIcon(() => {
|
||||
return this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
this.handleOpen();
|
||||
});
|
||||
|
||||
@ -37,7 +37,7 @@ export default class Panel extends PureComponent<PanelProps, PanelState> {
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const { align, draggable, floatable, visible } = this.props;
|
||||
const { width } = this.state;
|
||||
return (
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Icon, Button } from '@alifd/next';
|
||||
import { Icon } from '@alifd/next';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@ -27,22 +27,25 @@ export default class TopIcon extends PureComponent<TopIconProps> {
|
||||
icon: '',
|
||||
id: '',
|
||||
locked: false,
|
||||
onClick: () => {},
|
||||
onClick: (): void => {},
|
||||
style: {},
|
||||
title: ''
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const { active, disabled, icon, locked, title, className, id, style, onClick } = this.props;
|
||||
return (
|
||||
<div className={classNames('lowcode-top-icon', className, {
|
||||
active,
|
||||
disabled,
|
||||
locked
|
||||
})} data-tooltip={title}
|
||||
id={id}
|
||||
style={style}
|
||||
onClick={disabled ? undefined : onClick}>
|
||||
<div
|
||||
className={classNames('lowcode-top-icon', className, {
|
||||
active,
|
||||
disabled,
|
||||
locked
|
||||
})}
|
||||
data-tooltip={title}
|
||||
id={id}
|
||||
style={style}
|
||||
onClick={disabled ? undefined : onClick}
|
||||
>
|
||||
<Icon type={icon} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import React, { PureComponent, Fragment, CSSProperties } from 'react';
|
||||
|
||||
import { Balloon, Badge, Dialog } from '@alifd/next';
|
||||
import TopIcon from '../TopIcon';
|
||||
@ -31,7 +31,7 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
disabled: false,
|
||||
marked: false,
|
||||
locked: false,
|
||||
onClick: () => {}
|
||||
onClick: (): void => {}
|
||||
};
|
||||
|
||||
constructor(props, context) {
|
||||
@ -41,7 +41,7 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
const { config, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
if (editor && pluginKey) {
|
||||
@ -50,7 +50,7 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
const { config, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
if (editor && pluginKey) {
|
||||
@ -59,22 +59,22 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
}
|
||||
}
|
||||
|
||||
handleShow = () => {
|
||||
handleShow = (): void => {
|
||||
const { disabled, config, onClick, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
if (disabled || !pluginKey) return;
|
||||
// 考虑到弹窗情况,延时发送消息
|
||||
setTimeout(() => editor.emit(`${pluginKey}.plugin.activate`), 0);
|
||||
setTimeout((): void => editor.emit(`${pluginKey}.plugin.activate`), 0);
|
||||
this.handleOpen();
|
||||
onClick && onClick();
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
handleClose = (): void => {
|
||||
const { config, editor } = this.props;
|
||||
const pluginKey = config && config.pluginKey;
|
||||
const plugin = editor.plugins && editor.plugins[pluginKey];
|
||||
if (plugin) {
|
||||
plugin.close().then(() => {
|
||||
if (plugin && plugin.close) {
|
||||
plugin.close().then((): void => {
|
||||
this.setState({
|
||||
dialogVisible: false
|
||||
});
|
||||
@ -82,14 +82,14 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
}
|
||||
};
|
||||
|
||||
handleOpen = () => {
|
||||
handleOpen = (): void => {
|
||||
// todo dialog类型的插件初始时拿不动插件实例
|
||||
this.setState({
|
||||
dialogVisible: true
|
||||
});
|
||||
};
|
||||
|
||||
renderIcon = clickCallback => {
|
||||
renderIcon = (clickCallback): React.ReactNode => {
|
||||
const { active, disabled, marked, locked, config, onClick, editor } = this.props;
|
||||
const { pluginKey, props } = config || {};
|
||||
const { icon, title } = props || {};
|
||||
@ -101,10 +101,10 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
locked={locked}
|
||||
icon={icon}
|
||||
title={title}
|
||||
onClick={() => {
|
||||
onClick={(): void => {
|
||||
if (disabled) return;
|
||||
// 考虑到弹窗情况,延时发送消息
|
||||
setTimeout(() => editor.emit(`${pluginKey}.plugin.activate`), 0);
|
||||
setTimeout((): void => editor.emit(`${pluginKey}.plugin.activate`), 0);
|
||||
clickCallback && clickCallback();
|
||||
onClick && onClick();
|
||||
}}
|
||||
@ -113,8 +113,8 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
return marked ? <Badge dot>{node}</Badge> : node;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { active, marked, locked, disabled, config, editor, pluginClass: Comp } = this.props;
|
||||
render(): React.ReactNode {
|
||||
const { active, marked, locked, disabled, config, editor, pluginClass: Comp, style } = this.props;
|
||||
const { pluginKey, pluginProps, props, type } = config || {};
|
||||
const { onClick, title } = props || {};
|
||||
const { dialogVisible } = this.state;
|
||||
@ -127,7 +127,7 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
locked={locked}
|
||||
disabled={disabled}
|
||||
config={config}
|
||||
onClick={() => {
|
||||
onClick={(): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
}}
|
||||
{...pluginProps}
|
||||
@ -139,24 +139,24 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
case 'LinkIcon':
|
||||
return (
|
||||
<a {...props.linkProps}>
|
||||
{this.renderIcon(() => {
|
||||
{this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
})}
|
||||
</a>
|
||||
);
|
||||
case 'Icon':
|
||||
return this.renderIcon(() => {
|
||||
return this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
});
|
||||
case 'DialogIcon':
|
||||
return (
|
||||
<Fragment>
|
||||
{this.renderIcon(() => {
|
||||
{this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
this.handleOpen();
|
||||
})}
|
||||
<Dialog
|
||||
onOk={() => {
|
||||
onOk={(): void => {
|
||||
editor.emit(`${pluginKey}.dialog.onOk`);
|
||||
this.handleClose();
|
||||
}}
|
||||
@ -165,7 +165,7 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
title={title}
|
||||
style={{
|
||||
width: 500,
|
||||
...(props && props.style)
|
||||
...(props.dialogProps && props.dialogProps.style)
|
||||
}}
|
||||
{...props.dialogProps}
|
||||
visible={dialogVisible}
|
||||
@ -177,7 +177,7 @@ export default class TopPlugin extends PureComponent<TopPluginProps, TopPluginSt
|
||||
case 'BalloonIcon':
|
||||
return (
|
||||
<Balloon
|
||||
trigger={this.renderIcon(() => {
|
||||
trigger={this.renderIcon((): void => {
|
||||
onClick && onClick.call(null, editor);
|
||||
})}
|
||||
triggerType={['click', 'hover']}
|
||||
|
||||
@ -9,7 +9,6 @@ body {
|
||||
color: $color-text1-3;
|
||||
}
|
||||
|
||||
|
||||
.next-loading {
|
||||
.next-loading-wrap {
|
||||
height: 100%;
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { HashRouter as Router, Route } from 'react-router-dom';
|
||||
import { Loading, ConfigProvider } from '@alifd/next';
|
||||
|
||||
import Editor from '../framework/editor';
|
||||
import { EditorConfig, Utils, PluginComponents } from '../framework/definitions';
|
||||
import { EditorConfig, Utils, PluginClassSet } from '../framework/definitions';
|
||||
import { comboEditorConfig, parseSearch } from '../framework/utils';
|
||||
|
||||
import defaultConfig from './config/skeleton';
|
||||
@ -19,8 +18,17 @@ import './global.scss';
|
||||
|
||||
let renderIdx = 0;
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__ctx: {
|
||||
editor: Editor;
|
||||
appHelper: Editor;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface SkeletonProps {
|
||||
components: PluginComponents;
|
||||
components: PluginClassSet;
|
||||
config: EditorConfig;
|
||||
history: object;
|
||||
location: object;
|
||||
@ -29,15 +37,15 @@ export interface SkeletonProps {
|
||||
}
|
||||
|
||||
export interface SkeletonState {
|
||||
initReady: boolean;
|
||||
skeletonKey: string;
|
||||
initReady?: boolean;
|
||||
skeletonKey?: string;
|
||||
__hasError?: boolean;
|
||||
}
|
||||
|
||||
export default class Skeleton extends PureComponent<SkeletonProps, SkeletonState> {
|
||||
static displayName = 'LowcodeEditorSkeleton';
|
||||
|
||||
static getDerivedStateFromError() {
|
||||
static getDerivedStateFromError(): SkeletonState {
|
||||
return {
|
||||
__hasError: true
|
||||
};
|
||||
@ -56,11 +64,11 @@ export default class Skeleton extends PureComponent<SkeletonProps, SkeletonState
|
||||
this.init();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
this.editor && this.editor.destroy();
|
||||
}
|
||||
|
||||
componentDidCatch(err) {
|
||||
componentDidCatch(err): void {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
@ -69,15 +77,17 @@ export default class Skeleton extends PureComponent<SkeletonProps, SkeletonState
|
||||
this.editor.destroy();
|
||||
}
|
||||
const { utils, config, components } = this.props;
|
||||
const editor = (this.editor = new Editor(comboEditorConfig(defaultConfig, config), components, {
|
||||
const editor = new Editor(comboEditorConfig(defaultConfig, config), components, {
|
||||
...skeletonUtils,
|
||||
...utils
|
||||
}));
|
||||
});
|
||||
this.editor = editor;
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
window.__ctx = {
|
||||
editor,
|
||||
appHelper: editor
|
||||
};
|
||||
editor.once('editor.reset', () => {
|
||||
editor.once('editor.reset', (): void => {
|
||||
this.setState({
|
||||
initReady: false
|
||||
});
|
||||
@ -85,14 +95,14 @@ export default class Skeleton extends PureComponent<SkeletonProps, SkeletonState
|
||||
this.init(true);
|
||||
});
|
||||
|
||||
this.editor.init().then(() => {
|
||||
this.editor.init().then((): void => {
|
||||
this.setState(
|
||||
{
|
||||
initReady: true,
|
||||
// 刷新IDE时生成新的skeletonKey保证插件生命周期重新执行
|
||||
skeletonKey: isReset ? `skeleton${++renderIdx}` : this.state.skeletonKey
|
||||
},
|
||||
() => {
|
||||
(): void => {
|
||||
editor.emit('editor.ready');
|
||||
editor.emit('ide.ready');
|
||||
isReset && editor.emit('ide.afterReset');
|
||||
@ -101,7 +111,7 @@ export default class Skeleton extends PureComponent<SkeletonProps, SkeletonState
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const { initReady, skeletonKey, __hasError } = this.state;
|
||||
const { location, history, match } = this.props;
|
||||
if (__hasError || !this.editor) {
|
||||
|
||||
@ -12,6 +12,7 @@ export default class CenterArea extends PureComponent<CenterAreaProps> {
|
||||
static displayName = 'LowcodeCenterArea';
|
||||
|
||||
private editor: Editor;
|
||||
|
||||
private areaManager: AreaManager;
|
||||
|
||||
constructor(props) {
|
||||
@ -20,10 +21,11 @@ export default class CenterArea extends PureComponent<CenterAreaProps> {
|
||||
this.areaManager = new AreaManager(this.editor, 'centerArea');
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
this.editor.on('skeleton.update', this.handleSkeletonUpdate);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
|
||||
componentWillUnmount(): void {
|
||||
this.editor.off('skeleton.update', this.handleSkeletonUpdate);
|
||||
}
|
||||
|
||||
@ -34,14 +36,16 @@ export default class CenterArea extends PureComponent<CenterAreaProps> {
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const visiblePluginList = this.areaManager.getVisiblePluginList();
|
||||
return (
|
||||
<div className="lowcode-center-area">
|
||||
{visiblePluginList.map(item => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return <Comp key={item.pluginKey} editor={this.editor} config={item} {...item.pluginProps} />;
|
||||
})}
|
||||
{visiblePluginList.map(
|
||||
(item): React.ReactNode => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return <Comp key={item.pluginKey} editor={this.editor} config={item} {...item.pluginProps} />;
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ export default class LeftAreaNav extends PureComponent<LeftAreaNavProps, LeftAre
|
||||
|
||||
private areaManager: AreaManager;
|
||||
|
||||
private cacheActiveKey: string;
|
||||
// private cacheActiveKey: string;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -31,10 +31,10 @@ export default class LeftAreaNav extends PureComponent<LeftAreaNavProps, LeftAre
|
||||
this.state = {
|
||||
activeKey: 'none'
|
||||
};
|
||||
this.cacheActiveKey = 'none';
|
||||
// this.cacheActiveKey = 'none';
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
this.editor.on('skeleton.update', this.handleSkeletonUpdate);
|
||||
this.editor.on('leftNav.change', this.handlePluginChange);
|
||||
const visiblePanelPluginList = this.areaManager.getVisiblePluginList().filter(item => item.type === 'IconPanel');
|
||||
@ -42,7 +42,7 @@ export default class LeftAreaNav extends PureComponent<LeftAreaNavProps, LeftAre
|
||||
this.handlePluginChange(defaultKey);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
this.editor.off('skeleton.update', this.handleSkeletonUpdate);
|
||||
this.editor.off('leftNav.change', this.handlePluginChange);
|
||||
}
|
||||
@ -61,27 +61,25 @@ export default class LeftAreaNav extends PureComponent<LeftAreaNavProps, LeftAre
|
||||
const nextPlugin = plugins[key];
|
||||
if (activeKey === 'none') {
|
||||
if (nextPlugin) {
|
||||
nextPlugin.open().then(() => {
|
||||
nextPlugin.open().then((): void => {
|
||||
this.updateActiveKey(key);
|
||||
});
|
||||
}
|
||||
} else if (activeKey === key) {
|
||||
if (prePlugin) {
|
||||
prePlugin.close().then(() => {
|
||||
prePlugin.close().then((): void => {
|
||||
this.updateActiveKey('none');
|
||||
});
|
||||
}
|
||||
} else {
|
||||
} else if (prePlugin) {
|
||||
// 先关后开
|
||||
if (prePlugin) {
|
||||
prePlugin.close().then(() => {
|
||||
if (nextPlugin) {
|
||||
nextPlugin.open().then(() => {
|
||||
this.updateActiveKey(key);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
prePlugin.close().then((): void => {
|
||||
if (nextPlugin) {
|
||||
nextPlugin.open().then((): void => {
|
||||
this.updateActiveKey(key);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -111,9 +109,9 @@ export default class LeftAreaNav extends PureComponent<LeftAreaNavProps, LeftAre
|
||||
};
|
||||
|
||||
updateActiveKey = (key: string): void => {
|
||||
if (key === 'none') {
|
||||
this.cacheActiveKey = this.state.activeKey;
|
||||
}
|
||||
// if (key === 'none') {
|
||||
// this.cacheActiveKey = this.state.activeKey;
|
||||
// }
|
||||
this.editor.set('leftNav', key);
|
||||
this.setState({ activeKey: key });
|
||||
this.editor.emit('leftPanel.show', key);
|
||||
@ -121,31 +119,32 @@ export default class LeftAreaNav extends PureComponent<LeftAreaNavProps, LeftAre
|
||||
|
||||
renderPluginList = (list: PluginConfig[] = []): React.ReactElement[] => {
|
||||
const { activeKey } = this.state;
|
||||
return list.map((item, idx) => {
|
||||
const pluginStatus = this.editor.pluginStatus[item.pluginKey];
|
||||
return (
|
||||
<LeftPlugin
|
||||
key={item.pluginKey}
|
||||
config={item}
|
||||
editor={this.editor}
|
||||
pluginClass={this.editor.components[item.pluginKey]}
|
||||
onClick={() => this.handlePluginClick(item)}
|
||||
active={activeKey === item.pluginKey}
|
||||
{...pluginStatus}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return list.map(
|
||||
(item): React.ReactElement => {
|
||||
const pluginStatus = this.editor.pluginStatus[item.pluginKey];
|
||||
return (
|
||||
<LeftPlugin
|
||||
key={item.pluginKey}
|
||||
config={item}
|
||||
editor={this.editor}
|
||||
pluginClass={this.editor.components[item.pluginKey]}
|
||||
onClick={(): void => this.handlePluginClick(item)}
|
||||
active={activeKey === item.pluginKey}
|
||||
{...pluginStatus}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { activeKey } = this.state;
|
||||
render(): React.ReactNode {
|
||||
const topList: PluginConfig[] = [];
|
||||
const bottomList: PluginConfig[] = [];
|
||||
const visiblePluginList = this.areaManager.getVisiblePluginList();
|
||||
if (isEmpty(visiblePluginList)){
|
||||
if (isEmpty(visiblePluginList)) {
|
||||
return null;
|
||||
}
|
||||
visiblePluginList.forEach(item => {
|
||||
visiblePluginList.forEach((item): void => {
|
||||
const align = item.props && item.props.align === 'bottom' ? 'bottom' : 'top';
|
||||
if (align === 'bottom') {
|
||||
bottomList.push(item);
|
||||
|
||||
@ -16,6 +16,7 @@ export default class LeftAreaPanel extends PureComponent<LeftAreaPanelProps, Lef
|
||||
static displayName = 'LowcodeLeftAreaPanel';
|
||||
|
||||
private editor: Editor;
|
||||
|
||||
private areaManager: AreaManager;
|
||||
|
||||
constructor(props) {
|
||||
@ -28,11 +29,12 @@ export default class LeftAreaPanel extends PureComponent<LeftAreaPanelProps, Lef
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
this.editor.on('skeleton.update', this.handleSkeletonUpdate);
|
||||
this.editor.on('leftPanel.show', this.handlePluginChange);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
|
||||
componentWillUnmount(): void {
|
||||
this.editor.off('skeleton.update', this.handleSkeletonUpdate);
|
||||
this.editor.off('leftPanel.show', this.handlePluginChange);
|
||||
}
|
||||
@ -50,20 +52,26 @@ export default class LeftAreaPanel extends PureComponent<LeftAreaPanelProps, Lef
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const { activeKey } = this.state;
|
||||
const list = this.areaManager.getVisiblePluginList('PanelIcon');
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{list.map((item, idx) => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return (
|
||||
<Panel key={item.pluginKey} visible={item.pluginKey === activeKey} {...(item.props && item.props.panelProps)}>
|
||||
<Comp editor={this.editor} config={item} {...item.pluginProps} />
|
||||
</Panel>
|
||||
);
|
||||
})}
|
||||
{list.map(
|
||||
(item): React.ReactElement => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return (
|
||||
<Panel
|
||||
key={item.pluginKey}
|
||||
visible={item.pluginKey === activeKey}
|
||||
{...(item.props && item.props.panelProps)}
|
||||
>
|
||||
<Comp editor={this.editor} config={item} {...item.pluginProps} />
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
.right-panel {
|
||||
overflow: auto;
|
||||
border-top: 2px solid $color-line1-1;
|
||||
// border-top: 2px solid $color-line1-1;
|
||||
}
|
||||
|
||||
//tab定义
|
||||
|
||||
@ -30,7 +30,7 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
this.editor.on('skeleton.update', this.handleSkeletonUpdate);
|
||||
this.editor.on('rightNav.change', this.handlePluginChange);
|
||||
const visiblePluginList = this.areaManager.getVisiblePluginList('TabPanel');
|
||||
@ -38,7 +38,7 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
this.handlePluginChange(defaultKey, true);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
this.editor.off('skeleton.update', this.handleSkeletonUpdate);
|
||||
this.editor.off('rightNav.change', this.handlePluginChange);
|
||||
}
|
||||
@ -53,12 +53,12 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
} else {
|
||||
const currentPlugin = this.editor.plugins[activeKey];
|
||||
if (currentPlugin) {
|
||||
currentPlugin.close().then(() => {
|
||||
currentPlugin.close().then((): void => {
|
||||
this.setState(
|
||||
{
|
||||
activeKey: ''
|
||||
},
|
||||
() => {
|
||||
(): void => {
|
||||
const visiblePluginList = this.areaManager.getVisiblePluginList();
|
||||
const firstPlugin = visiblePluginList && visiblePluginList[0];
|
||||
if (firstPlugin) {
|
||||
@ -75,12 +75,12 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
handlePluginChange = (key: string, isinit?: boolean): void => {
|
||||
const activeKey = this.state.activeKey;
|
||||
const plugins = this.editor.plugins || {};
|
||||
const openPlugin = () => {
|
||||
const openPlugin = (): void => {
|
||||
if (!plugins[key]) {
|
||||
console.error(`plugin ${key} has not regist in the editor`);
|
||||
return;
|
||||
}
|
||||
plugins[key].open().then(() => {
|
||||
plugins[key].open().then((): void => {
|
||||
this.editor.set('rightNav', key);
|
||||
this.setState({
|
||||
activeKey: key
|
||||
@ -89,7 +89,7 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
};
|
||||
if (key === activeKey && !isinit) return;
|
||||
if (activeKey && plugins[activeKey]) {
|
||||
plugins[activeKey].close().then(() => {
|
||||
plugins[activeKey].close().then((): void => {
|
||||
openPlugin();
|
||||
});
|
||||
} else {
|
||||
@ -109,12 +109,7 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
disabled ? 'disabled' : ''
|
||||
}`}
|
||||
>
|
||||
{!!icon && (
|
||||
<Icon
|
||||
size="xs"
|
||||
type={icon}
|
||||
/>
|
||||
)}
|
||||
{!!icon && <Icon size="xs" type={icon} />}
|
||||
{title}
|
||||
</div>
|
||||
);
|
||||
@ -124,7 +119,7 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
return renderTitle();
|
||||
};
|
||||
|
||||
renderTabPanels = (list: PluginConfig[], height: string): void => {
|
||||
renderTabPanels = (list: PluginConfig[], height: string): React.ReactNode => {
|
||||
if (isEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
@ -138,37 +133,41 @@ export default class RightArea extends PureComponent<RightAreaProps, RightAreaSt
|
||||
lazyLoad={false}
|
||||
onChange={this.handlePluginChange}
|
||||
>
|
||||
{list.map((item, idx) => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return (
|
||||
<Tab.Item
|
||||
key={item.pluginKey}
|
||||
title={this.renderTabTitle(item)}
|
||||
disabled={this.editor.pluginStatus[item.pluginKey].disabled}
|
||||
style={{
|
||||
width: `${100/list.length}%`
|
||||
}}
|
||||
>
|
||||
<Comp editor={this.editor} config={item} {...item.pluginProps} />
|
||||
</Tab.Item>
|
||||
);
|
||||
})}
|
||||
{list.map(
|
||||
(item): React.ReactElement => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return (
|
||||
<Tab.Item
|
||||
key={item.pluginKey}
|
||||
title={this.renderTabTitle(item)}
|
||||
disabled={this.editor.pluginStatus[item.pluginKey].disabled}
|
||||
style={{
|
||||
width: `${100 / list.length}%`
|
||||
}}
|
||||
>
|
||||
<Comp editor={this.editor} config={item} {...item.pluginProps} />
|
||||
</Tab.Item>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</Tab>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
renderPanels = (list: PluginConfig[], height: string): void => {
|
||||
return list.map((item) => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return (
|
||||
<div className="right-panel" style={{height}} key={item.pluginKey}>
|
||||
<Comp editor={this.editor} config={item} {...item.pluginProps} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
renderPanels = (list: PluginConfig[], height: string): React.ReactNode => {
|
||||
return list.map(
|
||||
(item): React.ReactElement => {
|
||||
const Comp = this.editor.components[item.pluginKey];
|
||||
return (
|
||||
<div className="right-panel" style={{ height }} key={item.pluginKey}>
|
||||
<Comp editor={this.editor} config={item} {...item.pluginProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const tabList = this.areaManager.getVisiblePluginList('TabPanel');
|
||||
const panelList = this.areaManager.getVisiblePluginList('Panel');
|
||||
if (isEmpty(panelList) && isEmpty(tabList)) {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
background-color: $card-background;
|
||||
background-color: $card-background;
|
||||
border-bottom: 2px solid $color-line1-1;
|
||||
user-select: none;
|
||||
.divider {
|
||||
|
||||
@ -25,11 +25,11 @@ export default class TopArea extends PureComponent<TopAreaProps> {
|
||||
this.areaManager = new AreaManager(props.editor, 'topArea');
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount(): void {
|
||||
this.editor.on('skeleton.update', this.handleSkeletonUpdate);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
this.editor.off('skeleton.update', this.handleSkeletonUpdate);
|
||||
}
|
||||
|
||||
@ -41,30 +41,32 @@ export default class TopArea extends PureComponent<TopAreaProps> {
|
||||
};
|
||||
|
||||
renderPluginList = (list: PluginConfig[] = []): React.ReactElement[] => {
|
||||
return list.map((item, idx) => {
|
||||
const isDivider = item.type === 'Divider';
|
||||
return (
|
||||
<Col
|
||||
className={isDivider ? 'divider' : ''}
|
||||
key={isDivider ? idx : item.pluginKey}
|
||||
style={{
|
||||
width: (item.props && item.props.width) || 36,
|
||||
flex: 'none'
|
||||
}}
|
||||
>
|
||||
{!isDivider && (
|
||||
<TopPlugin config={item} pluginClass={this.editor.components[item.pluginKey]} editor={this.editor} />
|
||||
)}
|
||||
</Col>
|
||||
);
|
||||
});
|
||||
return list.map(
|
||||
(item, idx): React.ReactElement => {
|
||||
const isDivider = item.type === 'Divider';
|
||||
return (
|
||||
<Col
|
||||
className={isDivider ? 'divider' : ''}
|
||||
key={isDivider ? idx : item.pluginKey}
|
||||
style={{
|
||||
width: (item.props && item.props.width) || 36,
|
||||
flex: 'none'
|
||||
}}
|
||||
>
|
||||
{!isDivider && (
|
||||
<TopPlugin config={item} pluginClass={this.editor.components[item.pluginKey]} editor={this.editor} />
|
||||
)}
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
const leftList: PluginConfig[] = [];
|
||||
const rightList: PluginConfig[] = [];
|
||||
const visiblePluginList = this.areaManager.getVisiblePluginList();
|
||||
visiblePluginList.forEach(item => {
|
||||
visiblePluginList.forEach((item): void => {
|
||||
const align = item.props && item.props.align === 'right' ? 'right' : 'left';
|
||||
// 分隔符不允许相邻
|
||||
if (item.type === 'Divider') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user