feat: update skeleton ts defined

This commit is contained in:
liujuping 2023-03-20 18:09:59 +08:00 committed by 林熠
parent fc7c217f8c
commit 21f74f0cc1
19 changed files with 188 additions and 99 deletions

View File

@ -2,7 +2,7 @@
/* eslint-disable max-len */
import { StrictEventEmitter } from 'strict-event-emitter-types';
import { EventEmitter } from 'events';
import { EventBus } from './event-bus';
import { EventBus, IEventBus } from './event-bus';
import {
IPublicModelEditor,
EditorConfig,
@ -52,16 +52,19 @@ export declare interface Editor extends StrictEventEmitter<EventEmitter, GlobalE
eventNames(): Array<string | symbol>;
}
// eslint-disable-next-line no-redeclare
export class Editor extends (EventEmitter as any) implements IPublicModelEditor {
constructor(readonly viewName: string = 'global', readonly workspaceMode: boolean = false) {
// eslint-disable-next-line constructor-super
super();
// set global emitter maxListeners
this.setMaxListeners(200);
this.eventBus = new EventBus(this);
export interface IEditor extends IPublicModelEditor {
config?: EditorConfig;
components?: PluginClassSet;
eventBus: IEventBus;
init(config?: EditorConfig, components?: PluginClassSet): Promise<any>;
}
// eslint-disable-next-line no-redeclare
export class Editor extends EventEmitter implements IEditor {
/**
* Ioc Container
*/
@ -71,10 +74,32 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
return globalLocale.getLocale();
}
config?: EditorConfig;
eventBus: EventBus;
components?: PluginClassSet;
// readonly utils = utils;
private hooks: HookConfig[] = [];
private waits = new Map<
IPublicTypeEditorValueKey,
Array<{
once?: boolean;
resolve: (data: any) => void;
}>
>();
constructor(readonly viewName: string = 'global', readonly workspaceMode: boolean = false) {
// eslint-disable-next-line constructor-super
super();
// set global emitter maxListeners
this.setMaxListeners(200);
this.eventBus = new EventBus(this);
}
get<T = undefined, KeyOrType = any>(
keyOrType: KeyOrType,
): IPublicTypeEditorGetResult<T, KeyOrType> | undefined {
@ -202,12 +227,6 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
this.notifyGot(key || data);
}
config?: EditorConfig;
eventBus: EventBus;
components?: PluginClassSet;
async init(config?: EditorConfig, components?: PluginClassSet): Promise<any> {
this.config = config || {};
this.components = components || {};
@ -270,16 +289,6 @@ export class Editor extends (EventEmitter as any) implements IPublicModelEditor
});
};
/* eslint-disable */
private waits = new Map<
IPublicTypeEditorValueKey,
Array<{
once?: boolean;
resolve: (data: any) => void;
}>
>();
/* eslint-enable */
private notifyGot(key: IPublicTypeEditorValueKey) {
let waits = this.waits.get(key);
if (!waits) {

View File

@ -3,7 +3,7 @@ import { obx, computed, makeObservable } from '@alilc/lowcode-editor-core';
import { Logger } from '@alilc/lowcode-utils';
import { IPublicTypeWidgetBaseConfig } from '@alilc/lowcode-types';
import { WidgetContainer } from './widget/widget-container';
import { Skeleton } from './skeleton';
import { ISkeleton } from './skeleton';
import { IWidget } from './widget/widget';
const logger = new Logger({ level: 'warn', bizName: 'skeleton:area' });
@ -35,7 +35,9 @@ export class Area<C extends IPublicTypeWidgetBaseConfig = any, T extends IWidget
readonly container: WidgetContainer<T, C>;
constructor(readonly skeleton: Skeleton, readonly name: string, handle: (item: T | C) => T, private exclusive?: boolean, defaultSetCurrent = false) {
private lastCurrent: T | null = null;
constructor(readonly skeleton: ISkeleton, readonly name: string, handle: (item: T | C) => T, private exclusive?: boolean, defaultSetCurrent = false) {
makeObservable(this);
this.container = skeleton.createContainer(name, handle, exclusive, () => this.visible, defaultSetCurrent);
}
@ -57,8 +59,6 @@ export class Area<C extends IPublicTypeWidgetBaseConfig = any, T extends IWidget
return this.container.remove(config);
}
private lastCurrent: T | null = null;
setVisible(flag: boolean) {
if (this.exclusive) {
const { current } = this.container;

View File

@ -92,7 +92,10 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
const { extraProps } = this.field;
const { ignoreDefaultValue } = extraProps;
try {
return typeof ignoreDefaultValue === 'function' ? ignoreDefaultValue(this.field.internalToShell()) : false;
if (typeof ignoreDefaultValue === 'function') {
return ignoreDefaultValue(this.field.internalToShellField());
}
return false;
} catch (error) {
console.error('exception when ignoreDefaultValue is excuted', error);
}

View File

@ -1,10 +1,9 @@
import React, { Component } from 'react';
import classNames from 'classnames';
import { observer } from '@alilc/lowcode-editor-core';
import { SettingTopEntry, SettingField } from '@alilc/lowcode-designer';
import StageChain from './stage-chain';
import Stage from './stage';
import { Skeleton } from '../../skeleton';
import { ISkeleton } from '../../skeleton';
import PopupService, { PopupPipe } from '../popup';
import { Stage as StageWidget } from '../../widget/stage';
@ -14,9 +13,7 @@ export type StageBoxProps = typeof StageBoxDefaultProps & {
stageChain?: StageChain;
className?: string;
children: React.ReactNode;
skeleton: Skeleton;
// @todo to remove
target?: SettingTopEntry | SettingField;
skeleton: ISkeleton;
};
type WillDetachMember = () => void;

View File

@ -1,4 +1,4 @@
import { createContext } from 'react';
import { Skeleton } from './skeleton';
import { ISkeleton } from './skeleton';
export const SkeletonContext = createContext<Skeleton>({} as any);
export const SkeletonContext = createContext<ISkeleton>({} as any);

View File

@ -3,9 +3,10 @@ import classNames from 'classnames';
import { observer, Focusable, focusTracker } from '@alilc/lowcode-editor-core';
import { Area } from '../area';
import { Panel } from '../widget/panel';
import { PanelConfig } from '../types';
@observer
export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> {
export default class LeftFloatPane extends Component<{ area: Area<PanelConfig, Panel> }> {
private dispose?: () => void;
private focusing?: Focusable;

View File

@ -1,7 +1,7 @@
import { Component } from 'react';
import { TipContainer, observer } from '@alilc/lowcode-editor-core';
import classNames from 'classnames';
import { Skeleton } from '../skeleton';
import { ISkeleton } from '../skeleton';
import TopArea from './top-area';
import LeftArea from './left-area';
import LeftFixedPane from './left-fixed-pane';
@ -16,7 +16,7 @@ import { EditorConfig, PluginClassSet } from '@alilc/lowcode-types';
@observer
export class Workbench extends Component<{
skeleton: Skeleton;
skeleton: ISkeleton;
config?: EditorConfig;
components?: PluginClassSet;
className?: string;

View File

@ -1,4 +1,4 @@
import { Editor, action, makeObservable, obx, engineConfig } from '@alilc/lowcode-editor-core';
import { action, makeObservable, obx, engineConfig, IEditor } from '@alilc/lowcode-editor-core';
import {
DockConfig,
PanelConfig,
@ -27,6 +27,7 @@ import {
IPublicTypeWidgetBaseConfig,
IPublicTypeWidgetConfigArea,
IPublicTypeSkeletonConfig,
IPublicApiSkeleton,
} from '@alilc/lowcode-types';
const logger = new Logger({ level: 'warn', bizName: 'skeleton' });
@ -42,6 +43,66 @@ export enum SkeletonEvents {
WIDGET_ENABLE = 'skeleton.widget.enable',
}
export interface ISkeleton extends Omit<IPublicApiSkeleton,
'showPanel' |
'hidePanel' |
'showWidget' |
'enableWidget' |
'hideWidget' |
'disableWidget' |
'showArea' |
'onShowPanel' |
'onHidePanel' |
'onShowWidget' |
'onHideWidget' |
'remove' |
'hideArea'
> {
editor: IEditor;
readonly leftArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>;
readonly topArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>;
readonly subTopArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>;
readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>;
readonly leftFixedArea: Area<PanelConfig, Panel>;
readonly leftFloatArea: Area<PanelConfig, Panel>;
readonly rightArea: Area<PanelConfig, Panel>;
readonly mainArea: Area<WidgetConfig | PanelConfig, Widget | Panel>;
readonly bottomArea: Area<PanelConfig, Panel>;
readonly stages: Area<StageConfig, Stage>;
readonly widgets: IWidget[];
getPanel(name: string): Panel | undefined;
getWidget(name: string): IWidget | undefined;
buildFromConfig(config?: EditorConfig, components?: PluginClassSet): void;
createStage(config: any): string | undefined;
getStage(name: string): Stage | null;
createContainer(
name: string,
handle: (item: any) => any,
exclusive?: boolean,
checkVisible?: () => boolean,
defaultSetCurrent?: boolean,
): WidgetContainer;
createPanel(config: PanelConfig): Panel;
}
export class Skeleton {
private panels = new Map<string, Panel>();
@ -69,7 +130,7 @@ export class Skeleton {
readonly widgets: IWidget[] = [];
constructor(readonly editor: Editor, readonly viewName: string = 'global') {
constructor(readonly editor: IEditor, readonly viewName: string = 'global') {
makeObservable(this);
this.leftArea = new Area(
this,
@ -244,7 +305,7 @@ export class Skeleton {
Object.keys(plugins).forEach((area) => {
plugins[area].forEach((item) => {
const { pluginKey, type, props = {}, pluginProps } = item;
const config: Partial<IPublicTypeWidgetBaseConfig> = {
const config: IPublicTypeWidgetBaseConfig = {
area: area as IPublicTypeWidgetConfigArea,
type: 'Widget',
name: pluginKey,
@ -272,7 +333,7 @@ export class Skeleton {
if (pluginKey in components) {
config.content = components[pluginKey];
}
this.add(config as IPublicTypeWidgetBaseConfig);
this.add(config);
});
});
}

View File

@ -4,6 +4,7 @@ import { isPlainObject, isJSFunction, getLogger } from '@alilc/lowcode-utils';
const leadingFnRe = /^function/;
const leadingFnNameRe = /^\w+\s*\(/;
const logger = getLogger({ level: 'warn', bizName: 'skeleton:transducers' });
/**
*
* () => {} / val => {}

View File

@ -1,12 +1,11 @@
import { ReactElement, ComponentType } from 'react';
import {
IPublicTypeTitleContent,
IPublicTypeIconType,
IPublicTypeI18nData,
TipContent,
IPublicTypeWidgetConfigArea,
IPublicTypeWidgetBaseConfig,
IPublicTypePanelDockPanelProps,
IPublicTypePanelDockProps,
} from '@alilc/lowcode-types';
import { IWidget } from './widget/widget';
@ -24,13 +23,7 @@ export function isWidgetConfig(obj: any): obj is WidgetConfig {
return obj && obj.type === 'Widget';
}
export interface DockProps {
title?: IPublicTypeTitleContent;
icon?: IPublicTypeIconType;
size?: 'small' | 'medium' | 'large';
className?: string;
description?: TipContent;
onClick?: () => void;
export interface DockProps extends IPublicTypePanelDockProps {
}
export interface DividerConfig extends IPublicTypeWidgetBaseConfig {

View File

@ -3,7 +3,7 @@ import { makeObservable, obx } from '@alilc/lowcode-editor-core';
import { uniqueId, createContent } from '@alilc/lowcode-utils';
import { getEvent } from '@alilc/lowcode-shell';
import { DockConfig } from '../types';
import { Skeleton } from '../skeleton';
import { ISkeleton } from '../skeleton';
import { DockView, WidgetView } from '../components/widget-views';
import { IWidget } from './widget';
@ -59,7 +59,7 @@ export class Dock implements IWidget {
return this._body;
}
constructor(readonly skeleton: Skeleton, readonly config: DockConfig) {
constructor(readonly skeleton: ISkeleton, readonly config: DockConfig) {
makeObservable(this);
const { props = {}, name } = config;
this.name = name;

View File

@ -1,7 +1,7 @@
import { obx, computed, makeObservable } from '@alilc/lowcode-editor-core';
import { uniqueId } from '@alilc/lowcode-utils';
import { createElement, ReactNode, ReactInstance } from 'react';
import { Skeleton } from '../skeleton';
import { ISkeleton } from '../skeleton';
import { PanelDockConfig } from '../types';
import { Panel } from './panel';
import { PanelDockView, WidgetView } from '../components/widget-views';
@ -18,7 +18,7 @@ export class PanelDock implements IWidget {
readonly name: string;
readonly align?: string;
readonly align?: 'left' | 'right' | 'bottom' | 'center' | 'top' | undefined;
private inited = false;
@ -51,11 +51,6 @@ export class PanelDock implements IWidget {
});
}
getDOMNode() {
// eslint-disable-next-line react/no-find-dom-node
return this._shell ? findDOMNode(this._shell) : null;
}
@obx.ref private _visible = true;
get visible() {
@ -76,7 +71,7 @@ export class PanelDock implements IWidget {
return this._panel || this.skeleton.getPanel(this.panelName);
}
constructor(readonly skeleton: Skeleton, readonly config: PanelDockConfig) {
constructor(readonly skeleton: ISkeleton, readonly config: PanelDockConfig) {
makeObservable(this);
const { content, contentProps, panelProps, name, props } = config;
this.name = name;
@ -84,7 +79,7 @@ export class PanelDock implements IWidget {
this.panelName = config.panelName || name;
this.align = props?.align;
if (content) {
const _panelProps: any = { ...panelProps };
const _panelProps = { ...panelProps };
if (_panelProps.title == null && props) {
_panelProps.title = composeTitle(props.title, undefined, props.description, true, true);
}
@ -102,6 +97,11 @@ export class PanelDock implements IWidget {
}
}
getDOMNode() {
// eslint-disable-next-line react/no-find-dom-node
return this._shell ? findDOMNode(this._shell) : null;
}
setVisible(flag: boolean) {
if (flag === this._visible) {
return;
@ -170,7 +170,6 @@ export class PanelDock implements IWidget {
}
}
export function isPanelDock(obj: any): obj is PanelDock {
return obj && obj.isPanelDock;
}

View File

@ -6,7 +6,7 @@ import { WidgetContainer } from './widget-container';
import { getEvent } from '@alilc/lowcode-shell';
import { PanelConfig, HelpTipConfig } from '../types';
import { TitledPanelView, TabsPanelView, PanelView } from '../components/widget-views';
import { Skeleton } from '../skeleton';
import { ISkeleton } from '../skeleton';
import { composeTitle } from './utils';
import { IWidget } from './widget';
import { isPanelDock, PanelDock } from './panel-dock';
@ -80,7 +80,7 @@ export class Panel implements IWidget {
@obx.ref public parent?: WidgetContainer;
constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) {
constructor(readonly skeleton: ISkeleton, readonly config: PanelConfig) {
makeObservable(this);
const { name, content, props = {} } = config;
const { hideTitleBar, title, icon, description, help } = props;
@ -111,7 +111,7 @@ export class Panel implements IWidget {
props.onInit.call(this, this);
}
if (content.onInit) {
if (typeof content !== 'string' && content && content.onInit) {
content.onInit.call(this, this);
}
// todo: process shortcut

View File

@ -1,6 +1,6 @@
// import { uniqueId } from '@alilc/lowcode-utils';
import { Widget } from './widget';
import { Skeleton } from '../skeleton';
import { ISkeleton } from '../skeleton';
import { WidgetConfig } from '../types';
export interface StageConfig extends WidgetConfig {
@ -17,7 +17,7 @@ export class Stage extends Widget {
direction?: 'right' | 'left';
};
constructor(skeleton: Skeleton, config: StageConfig) {
constructor(skeleton: ISkeleton, config: StageConfig) {
super(skeleton, config);
this.isRoot = config.isRoot || false;
}

View File

@ -3,45 +3,51 @@ import { isI18nData, isTitleConfig } from '@alilc/lowcode-utils';
import { isValidElement } from 'react';
export function composeTitle(title?: IPublicTypeTitleContent, icon?: IPublicTypeIconType, tip?: TipContent, tipAsTitle?: boolean, noIcon?: boolean) {
let _title: IPublicTypeTitleContent | undefined;
if (!title) {
title = {};
_title = {};
if (!icon || tipAsTitle) {
title.label = tip;
_title = {
label: tip,
};
tip = undefined;
}
} else {
_title = title;
}
if (icon || tip) {
if (typeof title !== 'object' || isValidElement(title) || isI18nData(title)) {
if (isValidElement(title)) {
if (title.type === 'svg' || (title.type as any).getIcon) {
if (typeof _title !== 'object' || isValidElement(_title) || isI18nData(_title)) {
if (isValidElement(_title)) {
if (_title.type === 'svg' || _title.type.getIcon) {
if (!icon) {
icon = title as any;
icon = _title;
}
if (tipAsTitle) {
title = tip as any;
_title = tip;
tip = null;
} else {
title = undefined;
_title = undefined;
}
}
}
title = {
label: title,
_title = {
label: _title,
icon,
tip,
};
} else {
title = {
...title,
_title = {
..._title,
icon,
tip,
};
}
}
if (isTitleConfig(title) && noIcon) {
if (isTitleConfig(_title) && noIcon) {
if (!isValidElement(title)) {
title.icon = undefined;
_title.icon = undefined;
}
}
return title;
return _title;
}

View File

@ -3,7 +3,7 @@ import { makeObservable, obx } from '@alilc/lowcode-editor-core';
import { createContent, uniqueId } from '@alilc/lowcode-utils';
import { getEvent } from '@alilc/lowcode-shell';
import { WidgetConfig } from '../types';
import { Skeleton } from '../skeleton';
import { ISkeleton } from '../skeleton';
import { WidgetView } from '../components/widget-views';
import { IPublicTypeTitleContent, IPublicTypeWidgetBaseConfig } from '@alilc/lowcode-types';
@ -15,7 +15,7 @@ export interface IWidget {
readonly visible: boolean;
readonly disabled?: boolean;
readonly body: ReactNode;
readonly skeleton: Skeleton;
readonly skeleton: ISkeleton;
readonly config: IPublicTypeWidgetBaseConfig;
getName(): string;
@ -71,7 +71,7 @@ export class Widget implements IWidget {
readonly title: IPublicTypeTitleContent;
constructor(readonly skeleton: Skeleton, readonly config: WidgetConfig) {
constructor(readonly skeleton: ISkeleton, readonly config: WidgetConfig) {
makeObservable(this);
const { props = {}, name } = config;
this.name = name;

View File

@ -1,4 +1,4 @@
import { Editor as InnerEditor, EventBus } from '@alilc/lowcode-editor-core';
import { IEditor, IEventBus } from '@alilc/lowcode-editor-core';
import { getLogger, isPluginEventName } from '@alilc/lowcode-utils';
import { IPublicApiEvent, IPublicTypeDisposable } from '@alilc/lowcode-types';
@ -11,10 +11,10 @@ type EventOptions = {
const eventBusSymbol = Symbol('eventBus');
export class Event implements IPublicApiEvent {
private readonly [eventBusSymbol]: EventBus;
private readonly [eventBusSymbol]: IEventBus;
private readonly options: EventOptions;
constructor(eventBus: EventBus, options: EventOptions, public workspaceMode = false) {
constructor(eventBus: IEventBus, options: EventOptions, public workspaceMode = false) {
this[eventBusSymbol] = eventBus;
this.options = options;
if (!this.options.prefix) {
@ -69,6 +69,6 @@ export class Event implements IPublicApiEvent {
}
}
export function getEvent(editor: InnerEditor, options: any = { prefix: 'common' }) {
export function getEvent(editor: IEditor, options: any = { prefix: 'common' }) {
return new Event(editor.eventBus, options);
}

View File

@ -1,17 +1,18 @@
import { globalContext } from '@alilc/lowcode-editor-core';
import {
Skeleton as InnerSkeleton,
ISkeleton,
SkeletonEvents,
} from '@alilc/lowcode-editor-skeleton';
import { skeletonSymbol } from '../symbols';
import { IPublicApiSkeleton, IPublicTypeDisposable, IPublicTypeSkeletonConfig, IPublicTypeWidgetConfigArea } from '@alilc/lowcode-types';
const innerSkeletonSymbol = Symbol('skeleton');
export class Skeleton implements IPublicApiSkeleton {
private readonly [innerSkeletonSymbol]: InnerSkeleton;
private readonly [innerSkeletonSymbol]: ISkeleton;
private readonly pluginName: string;
get [skeletonSymbol](): InnerSkeleton {
get [skeletonSymbol](): ISkeleton {
if (this.workspaceMode) {
return this[innerSkeletonSymbol];
}
@ -24,7 +25,7 @@ export class Skeleton implements IPublicApiSkeleton {
}
constructor(
skeleton: InnerSkeleton,
skeleton: ISkeleton,
pluginName: string,
readonly workspaceMode: boolean = false,
) {
@ -57,7 +58,7 @@ export class Skeleton implements IPublicApiSkeleton {
if (!normalizeArea(area)) {
return;
}
skeleton[normalizeArea(area)!].container?.remove(name);
skeleton[normalizeArea(area)].container?.remove(name);
}
/**
@ -185,7 +186,7 @@ export class Skeleton implements IPublicApiSkeleton {
}
}
function normalizeArea(area: IPublicTypeWidgetConfigArea | undefined) {
function normalizeArea(area: IPublicTypeWidgetConfigArea | undefined): 'leftArea' | 'rightArea' | 'topArea' | 'toolbar' | 'mainArea' | 'bottomArea' | 'leftFixedArea' | 'leftFloatArea' | 'stages' {
switch (area) {
case 'leftArea':
case 'left':

View File

@ -1,4 +1,4 @@
import { IPublicTypeWidgetConfigArea } from './';
import { IPublicTypeIconType, IPublicTypeTitleContent, IPublicTypeWidgetConfigArea, TipContent } from './';
export interface IPublicTypeWidgetBaseConfig {
[extra: string]: any;
@ -21,6 +21,24 @@ export interface IPublicTypePanelDockConfig extends IPublicTypeWidgetBaseConfig
type: 'PanelDock';
panelProps?: IPublicTypePanelDockPanelProps;
props?: IPublicTypePanelDockProps;
}
export interface IPublicTypePanelDockProps {
[key: string]: any;
size?: 'small' | 'medium' | 'large';
className?: string;
description?: TipContent;
onClick?: () => void;
icon?: IPublicTypeIconType;
title?: IPublicTypeTitleContent;
}
export interface IPublicTypePanelDockPanelProps {