mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-05 09:47:20 +00:00
Merge branch 'develop' into release/1.1.4-beta
This commit is contained in:
commit
bd6f83da6a
@ -52,6 +52,6 @@ module.exports = {
|
||||
'error',
|
||||
{ default: ['signature', 'field', 'constructor', 'method'] }
|
||||
],
|
||||
'no-unused-vars': ['error', { "destructuredArrayIgnorePattern": "^_" }]
|
||||
'@typescript-eslint/no-unused-vars': ['error']
|
||||
},
|
||||
};
|
||||
|
||||
@ -220,7 +220,7 @@ checkNesting(
|
||||
**@since v1.0.16**
|
||||
|
||||
### isDetectingNode
|
||||
检查拖拽放置的目标节点是否可以放置该拖拽对象
|
||||
判断是否当前节点处于被探测状态
|
||||
|
||||
```typescript
|
||||
/**
|
||||
|
||||
@ -13,9 +13,9 @@ import { observer, computed, Tip, globalContext } from '@alilc/lowcode-editor-co
|
||||
import { createIcon, isReactComponent, isActionContentObject } from '@alilc/lowcode-utils';
|
||||
import { IPublicTypeActionContentObject } from '@alilc/lowcode-types';
|
||||
import { BuiltinSimulatorHost } from '../host';
|
||||
import { OffsetObserver } from '../../designer';
|
||||
import { Node } from '../../document';
|
||||
import { INode, OffsetObserver } from '../../designer';
|
||||
import NodeSelector from '../node-selector';
|
||||
import { ISimulatorHost } from '../../simulator';
|
||||
|
||||
@observer
|
||||
export class BorderSelectingInstance extends Component<{
|
||||
@ -116,8 +116,8 @@ class Toolbar extends Component<{ observed: OffsetObserver }> {
|
||||
}
|
||||
}
|
||||
|
||||
function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActionContentObject, key: string, node: Node) {
|
||||
if (isValidElement(content)) {
|
||||
function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActionContentObject, key: string, node: INode) {
|
||||
if (isValidElement<{ key: string; node: INode }>(content)) {
|
||||
return cloneElement(content, { key, node });
|
||||
}
|
||||
if (isReactComponent(content)) {
|
||||
@ -130,7 +130,7 @@ function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActio
|
||||
key={key}
|
||||
className="lc-borders-action"
|
||||
onClick={() => {
|
||||
action && action(node);
|
||||
action && action(node.internalToShellNode()!);
|
||||
const workspace = globalContext.get('workspace');
|
||||
const editor = workspace.isActive ? workspace.window.editor : globalContext.get('editor');
|
||||
const npm = node?.componentMeta?.npm;
|
||||
@ -153,8 +153,8 @@ function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActio
|
||||
}
|
||||
|
||||
@observer
|
||||
export class BorderSelectingForNode extends Component<{ host: BuiltinSimulatorHost; node: Node }> {
|
||||
get host(): BuiltinSimulatorHost {
|
||||
export class BorderSelectingForNode extends Component<{ host: ISimulatorHost; node: INode }> {
|
||||
get host(): ISimulatorHost {
|
||||
return this.props.host;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
getPublicPath,
|
||||
focusTracker,
|
||||
engineConfig,
|
||||
globalLocale,
|
||||
IReactionPublic,
|
||||
IReactionOptions,
|
||||
IReactionDisposer,
|
||||
@ -47,26 +48,26 @@ import {
|
||||
getRectTarget,
|
||||
CanvasPoint,
|
||||
Designer,
|
||||
IDesigner,
|
||||
} from '../designer';
|
||||
import { parseMetadata } from './utils/parse-metadata';
|
||||
import { getClosestClickableNode } from './utils/clickable';
|
||||
import {
|
||||
IPublicTypeComponentMetadata,
|
||||
IPublicTypeComponentSchema,
|
||||
IPublicTypePackage,
|
||||
IPublicEnumTransitionType,
|
||||
IPublicEnumDragObjectType,
|
||||
IPublicTypeDragNodeObject,
|
||||
IPublicTypeNodeInstance,
|
||||
IPublicTypeComponentInstance,
|
||||
IPublicTypeLocationChildrenDetail,
|
||||
IPublicTypeLocationDetailType,
|
||||
IPublicTypeRect,
|
||||
IPublicModelNode,
|
||||
} from '@alilc/lowcode-types';
|
||||
import { BuiltinSimulatorRenderer } from './renderer';
|
||||
import { clipboard } from '../designer/clipboard';
|
||||
import { LiveEditing } from './live-editing/live-editing';
|
||||
import { Project } from '../project';
|
||||
import { IProject, Project } from '../project';
|
||||
import { IScroller } from '../designer/scroller';
|
||||
import { isElementNode, isDOMNodeVisible } from '../utils/misc';
|
||||
import { debounce } from 'lodash';
|
||||
@ -164,9 +165,9 @@ const defaultRaxEnvironment = [
|
||||
export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProps> {
|
||||
readonly isSimulator = true;
|
||||
|
||||
readonly project: Project;
|
||||
readonly project: IProject;
|
||||
|
||||
readonly designer: Designer;
|
||||
readonly designer: IDesigner;
|
||||
|
||||
readonly viewport = new Viewport();
|
||||
|
||||
@ -198,7 +199,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
|
||||
@computed get locale(): string {
|
||||
return this.get('locale');
|
||||
return this.get('locale') || globalLocale.getLocale();
|
||||
}
|
||||
|
||||
@computed get deviceClassName(): string | undefined {
|
||||
@ -217,7 +218,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
return this.get('requestHandlersMap') || null;
|
||||
}
|
||||
|
||||
get thisRequiredInJSE(): any {
|
||||
get thisRequiredInJSE(): boolean {
|
||||
return engineConfig.get('thisRequiredInJSE') ?? true;
|
||||
}
|
||||
|
||||
@ -559,8 +560,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
return;
|
||||
}
|
||||
// FIXME: dirty fix remove label-for fro liveEditing
|
||||
(downEvent.target as HTMLElement).removeAttribute('for');
|
||||
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
|
||||
downEvent.target?.removeAttribute('for');
|
||||
const nodeInst = this.getNodeInstanceFromElement(downEvent.target);
|
||||
const { focusNode } = documentModel;
|
||||
const node = getClosestClickableNode(nodeInst?.node || focusNode, downEvent);
|
||||
// 如果找不到可点击的节点,直接返回
|
||||
@ -675,11 +676,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
const x = new Event('click');
|
||||
x.initEvent('click', true);
|
||||
this._iframe?.dispatchEvent(x);
|
||||
const target = e.target as HTMLElement;
|
||||
const target = e.target;
|
||||
|
||||
const customizeIgnoreSelectors = engineConfig.get('customizeIgnoreSelectors');
|
||||
// TODO: need more elegant solution to ignore click events of components in designer
|
||||
const defaultIgnoreSelectors: any = [
|
||||
const defaultIgnoreSelectors: string[] = [
|
||||
'.next-input-group',
|
||||
'.next-checkbox-group',
|
||||
'.next-checkbox-wrapper',
|
||||
@ -741,7 +742,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
};
|
||||
const leave = () => {
|
||||
this.project.currentDocument && detecting.leave(this.project.currentDocument)
|
||||
this.project.currentDocument && detecting.leave(this.project.currentDocument);
|
||||
};
|
||||
|
||||
doc.addEventListener('mouseover', hover, true);
|
||||
@ -812,7 +813,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
/**
|
||||
* @see ISimulator
|
||||
*/
|
||||
setSuspense(suspended: boolean) {
|
||||
setSuspense(/** _suspended: boolean */) {
|
||||
return false;
|
||||
// if (suspended) {
|
||||
// /*
|
||||
@ -897,7 +898,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
return this.renderer?.getComponent(componentName) || null;
|
||||
}
|
||||
|
||||
createComponent(schema: IPublicTypeComponentSchema): Component | null {
|
||||
createComponent(/** _schema: IPublicTypeComponentSchema */): Component | null {
|
||||
return null;
|
||||
// return this.renderer?.createComponent(schema) || null;
|
||||
}
|
||||
@ -1018,7 +1019,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
}
|
||||
|
||||
if (last) {
|
||||
const r: any = new DOMRect(last.x, last.y, last.r - last.x, last.b - last.y);
|
||||
const r: IPublicTypeRect = new DOMRect(last.x, last.y, last.r - last.x, last.b - last.y);
|
||||
r.elements = elements;
|
||||
r.computed = _computed;
|
||||
return r;
|
||||
@ -1186,13 +1187,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
*/
|
||||
locate(e: ILocateEvent): any {
|
||||
const { dragObject } = e;
|
||||
const { nodes } = dragObject as IPublicTypeDragNodeObject;
|
||||
|
||||
const nodes = dragObject?.nodes;
|
||||
|
||||
const operationalNodes = nodes?.filter((node) => {
|
||||
const onMoveHook = node.componentMeta?.advanced.callbacks?.onMoveHook;
|
||||
const canMove = onMoveHook && typeof onMoveHook === 'function' ? onMoveHook(node.internalToShellNode()) : true;
|
||||
|
||||
let parentContainerNode: Node | null = null;
|
||||
let parentContainerNode: INode | null = null;
|
||||
let parentNode = node.parent;
|
||||
|
||||
while (parentNode) {
|
||||
@ -1254,7 +1256,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
};
|
||||
|
||||
const locationData = {
|
||||
target: container as INode,
|
||||
target: container,
|
||||
detail,
|
||||
source: `simulator${document.id}`,
|
||||
event: e,
|
||||
@ -1279,12 +1281,12 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
return this.designer.createLocation(locationData);
|
||||
}
|
||||
|
||||
let nearRect = null;
|
||||
let nearIndex = 0;
|
||||
let nearNode = null;
|
||||
let nearDistance = null;
|
||||
let minTop = null;
|
||||
let maxBottom = null;
|
||||
let nearRect: IPublicTypeRect | null = null;
|
||||
let nearIndex: number = 0;
|
||||
let nearNode: INode | null = null;
|
||||
let nearDistance: number | null = null;
|
||||
let minTop: number | null = null;
|
||||
let maxBottom: number | null = null;
|
||||
|
||||
for (let i = 0, l = children.size; i < l; i++) {
|
||||
const node = children.get(i)!;
|
||||
@ -1341,8 +1343,13 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
const vertical = inline || row;
|
||||
|
||||
// TODO: fix type
|
||||
const near: any = {
|
||||
node: nearNode,
|
||||
const near: {
|
||||
node: IPublicModelNode;
|
||||
pos: 'before' | 'after' | 'replace';
|
||||
rect?: IPublicTypeRect;
|
||||
align?: 'V' | 'H';
|
||||
} = {
|
||||
node: nearNode.internalToShellNode()!,
|
||||
pos: 'before',
|
||||
align: vertical ? 'V' : 'H',
|
||||
};
|
||||
@ -1465,7 +1472,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
container = container.parent;
|
||||
instance = this.getClosestNodeInstance(dropContainer.instance, container.id)?.instance;
|
||||
dropContainer = {
|
||||
container: container,
|
||||
container,
|
||||
instance,
|
||||
};
|
||||
} else {
|
||||
@ -1483,12 +1490,12 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
/**
|
||||
* 控制接受
|
||||
*/
|
||||
handleAccept({ container, instance }: DropContainer, e: ILocateEvent): boolean {
|
||||
handleAccept({ container }: DropContainer, e: ILocateEvent): boolean {
|
||||
const { dragObject } = e;
|
||||
const document = this.currentDocument!;
|
||||
const focusNode = document.focusNode;
|
||||
if (isRootNode(container) || container.contains(focusNode)) {
|
||||
return document.checkNesting(focusNode, dragObject as any);
|
||||
return document.checkNesting(focusNode!, dragObject as any);
|
||||
}
|
||||
|
||||
const meta = (container as Node).componentMeta;
|
||||
@ -1509,15 +1516,12 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
getNearByContainer(
|
||||
{ container, instance }: DropContainer,
|
||||
drillDownExcludes: Set<INode>,
|
||||
e: ILocateEvent,
|
||||
) {
|
||||
const { children } = container;
|
||||
const document = this.project.currentDocument!;
|
||||
if (!children || children.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const nearDistance: any = null;
|
||||
const nearBy: any = null;
|
||||
for (let i = 0, l = children.size; i < l; i++) {
|
||||
let child = children.get(i);
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
import { Overlay } from '@alifd/next';
|
||||
import React from 'react';
|
||||
import React, { MouseEvent } from 'react';
|
||||
import { Title, globalContext } from '@alilc/lowcode-editor-core';
|
||||
import { canClickNode } from '@alilc/lowcode-utils';
|
||||
import './index.less';
|
||||
|
||||
import { Node, INode } from '@alilc/lowcode-designer';
|
||||
import { INode } from '@alilc/lowcode-designer';
|
||||
|
||||
const { Popup } = Overlay;
|
||||
|
||||
export interface IProps {
|
||||
node: Node;
|
||||
node: INode;
|
||||
}
|
||||
|
||||
export interface IState {
|
||||
parentNodes: Node[];
|
||||
parentNodes: INode[];
|
||||
}
|
||||
|
||||
type UnionNode = INode | null;
|
||||
@ -26,14 +26,18 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
||||
componentDidMount() {
|
||||
const parentNodes = this.getParentNodes(this.props.node);
|
||||
this.setState({
|
||||
parentNodes,
|
||||
parentNodes: parentNodes ?? [],
|
||||
});
|
||||
}
|
||||
|
||||
// 获取节点的父级节点(最多获取 5 层)
|
||||
getParentNodes = (node: Node) => {
|
||||
getParentNodes = (node: INode) => {
|
||||
const parentNodes: any[] = [];
|
||||
const { focusNode } = node.document;
|
||||
const focusNode = node.document?.focusNode;
|
||||
|
||||
if (!focusNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (node.contains(focusNode) || !focusNode.contains(node)) {
|
||||
return parentNodes;
|
||||
@ -53,12 +57,12 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
||||
return parentNodes;
|
||||
};
|
||||
|
||||
onSelect = (node: Node) => (e: unknown) => {
|
||||
onSelect = (node: INode) => (event: MouseEvent) => {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const canClick = canClickNode(node, e as MouseEvent);
|
||||
const canClick = canClickNode(node.internalToShellNode()!, event);
|
||||
|
||||
if (canClick && typeof node.select === 'function') {
|
||||
node.select();
|
||||
@ -76,19 +80,19 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
||||
}
|
||||
};
|
||||
|
||||
onMouseOver = (node: Node) => (_: any, flag = true) => {
|
||||
onMouseOver = (node: INode) => (_: any, flag = true) => {
|
||||
if (node && typeof node.hover === 'function') {
|
||||
node.hover(flag);
|
||||
}
|
||||
};
|
||||
|
||||
onMouseOut = (node: Node) => (_: any, flag = false) => {
|
||||
onMouseOut = (node: INode) => (_: any, flag = false) => {
|
||||
if (node && typeof node.hover === 'function') {
|
||||
node.hover(flag);
|
||||
}
|
||||
};
|
||||
|
||||
renderNodes = (/* node: Node */) => {
|
||||
renderNodes = () => {
|
||||
const nodes = this.state.parentNodes;
|
||||
if (!nodes || nodes.length < 1) {
|
||||
return null;
|
||||
@ -136,7 +140,7 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
||||
triggerType="hover"
|
||||
offset={[0, 0]}
|
||||
>
|
||||
<div className="instance-node-selector">{this.renderNodes(node)}</div>
|
||||
<div className="instance-node-selector">{this.renderNodes()}</div>
|
||||
</Popup>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -16,17 +16,15 @@ import {
|
||||
IPublicModelScroller,
|
||||
IPublicTypeLocationData,
|
||||
IPublicEnumTransformStage,
|
||||
IPublicModelDragon,
|
||||
IPublicModelDropLocation,
|
||||
IPublicModelLocateEvent,
|
||||
} from '@alilc/lowcode-types';
|
||||
import { megreAssets, IPublicTypeAssetsJson, isNodeSchema, isDragNodeObject, isDragNodeDataObject, isLocationChildrenDetail, Logger } from '@alilc/lowcode-utils';
|
||||
import { Project } from '../project';
|
||||
import { IProject, Project } from '../project';
|
||||
import { Node, DocumentModel, insertChildren, INode } from '../document';
|
||||
import { ComponentMeta, IComponentMeta } from '../component-meta';
|
||||
import { INodeSelector, Component } from '../simulator';
|
||||
import { Scroller } from './scroller';
|
||||
import { Dragon, IDragon, ILocateEvent } from './dragon';
|
||||
import { Dragon, IDragon } from './dragon';
|
||||
import { ActiveTracker, IActiveTracker } from './active-tracker';
|
||||
import { Detecting } from './detecting';
|
||||
import { DropLocation } from './location';
|
||||
@ -64,7 +62,11 @@ export interface DesignerProps {
|
||||
export interface IDesigner {
|
||||
readonly shellModelFactory: IShellModelFactory;
|
||||
|
||||
get dragon(): IPublicModelDragon;
|
||||
viewName: string | undefined;
|
||||
|
||||
readonly project: IProject;
|
||||
|
||||
get dragon(): IDragon;
|
||||
|
||||
get activeTracker(): IActiveTracker;
|
||||
|
||||
@ -78,6 +80,10 @@ export interface IDesigner {
|
||||
|
||||
createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller;
|
||||
|
||||
refreshComponentMetasMap(): void;
|
||||
|
||||
createOffsetObserver(nodeInstance: INodeSelector): OffsetObserver | null;
|
||||
|
||||
/**
|
||||
* 创建插入位置,考虑放到 dragon 中
|
||||
*/
|
||||
@ -92,6 +98,8 @@ export interface IDesigner {
|
||||
generateMetadata?: () => IPublicTypeComponentMetadata | null,
|
||||
): IComponentMeta;
|
||||
|
||||
clearLocation(): void;
|
||||
|
||||
createComponentMeta(data: IPublicTypeComponentMetadata): IComponentMeta | null;
|
||||
|
||||
getComponentMetasMap(): Map<string, IComponentMeta>;
|
||||
@ -118,7 +126,7 @@ export class Designer implements IDesigner {
|
||||
|
||||
readonly detecting = new Detecting();
|
||||
|
||||
readonly project: Project;
|
||||
readonly project: IProject;
|
||||
|
||||
readonly editor: IPublicModelEditor;
|
||||
|
||||
@ -140,7 +148,7 @@ export class Designer implements IDesigner {
|
||||
|
||||
@obx.ref private _simulatorComponent?: ComponentType<any>;
|
||||
|
||||
@obx.ref private _simulatorProps?: Record<string, any> | ((project: Project) => object);
|
||||
@obx.ref private _simulatorProps?: Record<string, any> | ((project: IProject) => object);
|
||||
|
||||
@obx.ref private _suspensed = false;
|
||||
|
||||
|
||||
@ -11,9 +11,9 @@ import {
|
||||
IPublicModelSensor,
|
||||
} from '@alilc/lowcode-types';
|
||||
import { setNativeSelection, cursor } from '@alilc/lowcode-utils';
|
||||
import { Node } from '../document';
|
||||
import { INode, Node } from '../document';
|
||||
import { ISimulatorHost, isSimulatorHost } from '../simulator';
|
||||
import { Designer } from './designer';
|
||||
import { IDesigner } from './designer';
|
||||
import { makeEventsHandler } from '../utils/misc';
|
||||
|
||||
export interface ILocateEvent extends IPublicModelLocateEvent {
|
||||
@ -88,14 +88,17 @@ function getSourceSensor(dragObject: IPublicModelDragObject): ISimulatorHost | n
|
||||
if (!isDragNodeObject(dragObject)) {
|
||||
return null;
|
||||
}
|
||||
return dragObject.nodes[0]?.document.simulator || null;
|
||||
return dragObject.nodes[0]?.document?.simulator || null;
|
||||
}
|
||||
|
||||
function isDragEvent(e: any): e is DragEvent {
|
||||
return e?.type?.startsWith('drag');
|
||||
}
|
||||
|
||||
export interface IDragon extends IPublicModelDragon {
|
||||
export interface IDragon extends IPublicModelDragon<
|
||||
INode,
|
||||
ILocateEvent
|
||||
> {
|
||||
emitter: IEventBus;
|
||||
}
|
||||
|
||||
@ -130,7 +133,7 @@ export class Dragon implements IDragon {
|
||||
|
||||
emitter: IEventBus = createModuleEventBus('Dragon');
|
||||
|
||||
constructor(readonly designer: Designer) {
|
||||
constructor(readonly designer: IDesigner) {
|
||||
makeObservable(this);
|
||||
this.viewName = designer.viewName;
|
||||
}
|
||||
@ -167,7 +170,7 @@ export class Dragon implements IDragon {
|
||||
* @param dragObject 拖拽对象
|
||||
* @param boostEvent 拖拽初始时事件
|
||||
*/
|
||||
boost(dragObject: IPublicModelDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node | IPublicModelNode) {
|
||||
boost(dragObject: IPublicModelDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: INode | IPublicModelNode) {
|
||||
const { designer } = this;
|
||||
const masterSensors = this.getMasterSensors();
|
||||
const handleEvents = makeEventsHandler(boostEvent, masterSensors);
|
||||
@ -264,7 +267,7 @@ export class Dragon implements IDragon {
|
||||
this.emitter.emit('rgl.add.placeholder', {
|
||||
rglNode,
|
||||
fromRglNode,
|
||||
node: locateEvent.dragObject.nodes[0],
|
||||
node: locateEvent.dragObject?.nodes[0],
|
||||
event: e,
|
||||
});
|
||||
designer.clearLocation();
|
||||
|
||||
@ -2,7 +2,7 @@ import requestIdleCallback, { cancelIdleCallback } from 'ric-shim';
|
||||
import { obx, computed, makeObservable } from '@alilc/lowcode-editor-core';
|
||||
import { uniqueId } from '@alilc/lowcode-utils';
|
||||
import { INodeSelector, IViewport } from '../simulator';
|
||||
import { Node } from '../document';
|
||||
import { INode } from '../document';
|
||||
|
||||
export class OffsetObserver {
|
||||
readonly id = uniqueId('oobx');
|
||||
@ -93,11 +93,11 @@ export class OffsetObserver {
|
||||
|
||||
private pid: number | undefined;
|
||||
|
||||
readonly viewport: IViewport;
|
||||
readonly viewport: IViewport | undefined;
|
||||
|
||||
private isRoot: boolean;
|
||||
|
||||
readonly node: Node;
|
||||
readonly node: INode;
|
||||
|
||||
readonly compute: () => void;
|
||||
|
||||
@ -105,10 +105,10 @@ export class OffsetObserver {
|
||||
const { node, instance } = nodeInstance;
|
||||
this.node = node;
|
||||
const doc = node.document;
|
||||
const host = doc.simulator!;
|
||||
const focusNode = doc.focusNode;
|
||||
const host = doc?.simulator;
|
||||
const focusNode = doc?.focusNode;
|
||||
this.isRoot = node.contains(focusNode!);
|
||||
this.viewport = host.viewport;
|
||||
this.viewport = host?.viewport;
|
||||
makeObservable(this);
|
||||
if (this.isRoot) {
|
||||
this.hasOffset = true;
|
||||
@ -118,7 +118,7 @@ export class OffsetObserver {
|
||||
return;
|
||||
}
|
||||
|
||||
let pid: number;
|
||||
let pid: number | undefined;
|
||||
const compute = () => {
|
||||
if (pid !== this.pid) {
|
||||
return;
|
||||
|
||||
@ -35,7 +35,7 @@ import {
|
||||
isDragNodeDataObject,
|
||||
isNode,
|
||||
} from '@alilc/lowcode-utils';
|
||||
import { IProject, Project } from '../project';
|
||||
import { IProject } from '../project';
|
||||
import { ISimulatorHost } from '../simulator';
|
||||
import { IComponentMeta } from '../component-meta';
|
||||
import { IDesigner, IHistory } from '../designer';
|
||||
@ -56,7 +56,7 @@ export type GetDataType<T, NodeType> = T extends undefined
|
||||
export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
|
||||
ISelection,
|
||||
IHistory,
|
||||
INode | IRootNode,
|
||||
INode,
|
||||
IDropLocation,
|
||||
IModalNodesManager,
|
||||
IProject
|
||||
@ -81,6 +81,8 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
|
||||
|
||||
readonly designer: IDesigner;
|
||||
|
||||
selection: ISelection;
|
||||
|
||||
get rootNode(): INode | null;
|
||||
|
||||
get simulator(): ISimulatorHost | null;
|
||||
@ -98,8 +100,6 @@ export interface IDocumentModel extends Omit< IPublicModelDocumentModel<
|
||||
|
||||
get currentRoot(): INode | null;
|
||||
|
||||
selection: ISelection;
|
||||
|
||||
isBlank(): boolean;
|
||||
|
||||
/**
|
||||
|
||||
@ -6,7 +6,6 @@ import {
|
||||
IPublicApiMaterial,
|
||||
IPublicApiEvent,
|
||||
IPublicApiCommon,
|
||||
IPublicTypeCompositeObject,
|
||||
IPublicApiPlugins,
|
||||
IPublicTypePluginConfig,
|
||||
IPublicApiLogger,
|
||||
@ -16,7 +15,9 @@ import {
|
||||
IPublicApiCanvas,
|
||||
IPublicApiWorkspace,
|
||||
IPublicTypePluginMeta,
|
||||
IPublicTypePluginRegisterOptions,
|
||||
} from '@alilc/lowcode-types';
|
||||
import PluginContext from './plugin-context';
|
||||
|
||||
export type PluginPreference = Map<string, Record<string, IPublicTypePreferenceValueType>>;
|
||||
|
||||
@ -72,7 +73,7 @@ export interface ILowCodePluginManagerCore {
|
||||
register(
|
||||
pluginModel: IPublicTypePlugin,
|
||||
pluginOptions?: any,
|
||||
options?: IPublicTypeCompositeObject,
|
||||
options?: IPublicTypePluginRegisterOptions,
|
||||
): Promise<void>;
|
||||
init(pluginPreference?: Map<string, Record<string, IPublicTypePreferenceValueType>>): Promise<void>;
|
||||
get(pluginName: string): ILowCodePluginRuntime | undefined;
|
||||
@ -81,6 +82,7 @@ export interface ILowCodePluginManagerCore {
|
||||
delete(pluginName: string): any;
|
||||
setDisabled(pluginName: string, flag: boolean): void;
|
||||
dispose(): void;
|
||||
_getLowCodePluginContext (options: IPluginContextOptions): PluginContext;
|
||||
}
|
||||
|
||||
export type ILowCodePluginManager = ILowCodePluginManagerCore & ILowCodePluginManagerPluginAccessor;
|
||||
|
||||
@ -41,6 +41,14 @@ export interface IProject extends Omit< IBaseApiProject<
|
||||
|
||||
get documents(): IDocumentModel[];
|
||||
|
||||
get i18n(): {
|
||||
[local: string]: {
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
mountSimulator(simulator: ISimulatorHost): void;
|
||||
|
||||
open(doc?: string | IDocumentModel | IPublicTypeRootSchema): IDocumentModel | null;
|
||||
|
||||
getDocumentByFileName(fileName: string): IDocumentModel | null;
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { ComponentType } from 'react';
|
||||
import { IPublicTypeComponentMetadata, IPublicTypeNodeSchema, IPublicTypeScrollable, IPublicTypeComponentInstance, IPublicModelSensor, IPublicTypeNodeInstance, IPublicTypePackage } from '@alilc/lowcode-types';
|
||||
import { Point, ScrollTarget, ILocateEvent } from './designer';
|
||||
import { Point, ScrollTarget, ILocateEvent, IDesigner } from './designer';
|
||||
import { BuiltinSimulatorRenderer } from './builtin-simulator/renderer';
|
||||
import { INode } from './document';
|
||||
import { IProject } from './project';
|
||||
|
||||
export type AutoFit = '100%';
|
||||
// eslint-disable-next-line no-redeclare
|
||||
@ -89,6 +90,10 @@ export interface ISimulatorHost<P = object> extends IPublicModelSensor<INode> {
|
||||
readonly contentDocument?: Document;
|
||||
readonly renderer?: BuiltinSimulatorRenderer;
|
||||
|
||||
readonly project: IProject;
|
||||
|
||||
readonly designer: IDesigner;
|
||||
|
||||
// dependsAsset // like react jQuery lodash
|
||||
// themesAsset
|
||||
// componentsAsset
|
||||
|
||||
@ -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,15 +52,18 @@ export declare interface Editor extends StrictEventEmitter<EventEmitter, GlobalE
|
||||
eventNames(): Array<string | symbol>;
|
||||
}
|
||||
|
||||
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 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 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) {
|
||||
|
||||
@ -339,8 +339,8 @@ function fireCallback(callback: IPublicTypeHotkeyCallback, e: KeyboardEvent, com
|
||||
}
|
||||
}
|
||||
|
||||
export interface IHotKey extends IPublicApiHotkey {
|
||||
|
||||
export interface IHotKey extends Omit<IPublicApiHotkey, 'bind' | 'callbacks'> {
|
||||
activate(activate: boolean): void;
|
||||
}
|
||||
|
||||
export class Hotkey implements IHotKey {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Component } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { TipItem } from './tip-item';
|
||||
import { tipHandler } from './tip-handler';
|
||||
|
||||
@ -25,7 +26,7 @@ export class TipContainer extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return window.ReactDOM.createPortal(
|
||||
return ReactDOM.createPortal(
|
||||
<div className="lc-tips-container">
|
||||
<TipItem />
|
||||
</div>,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Component, isValidElement, ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { createIcon, isI18nData } from '@alilc/lowcode-utils';
|
||||
import { IPublicTypeTitleContent, IPublicTypeI18nData } from '@alilc/lowcode-types';
|
||||
import { createIcon, isI18nData, isTitleConfig } from '@alilc/lowcode-utils';
|
||||
import { IPublicTypeTitleContent, IPublicTypeI18nData, IPublicTypeTitleConfig } from '@alilc/lowcode-types';
|
||||
import { intl } from '../../intl';
|
||||
import { Tip } from '../tip';
|
||||
import './title.less';
|
||||
@ -88,7 +88,8 @@ export class Title extends Component<{
|
||||
|
||||
render() {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { title, className } = this.props;
|
||||
const { title, className } = this.props;
|
||||
let _title: IPublicTypeTitleConfig;
|
||||
if (title == null) {
|
||||
return null;
|
||||
}
|
||||
@ -96,34 +97,40 @@ export class Title extends Component<{
|
||||
return title;
|
||||
}
|
||||
if (typeof title === 'string' || isI18nData(title)) {
|
||||
title = { label: title };
|
||||
_title = { label: title };
|
||||
} else if (isTitleConfig(title)) {
|
||||
_title = title;
|
||||
} else {
|
||||
_title = {
|
||||
label: title,
|
||||
};
|
||||
}
|
||||
|
||||
const icon = title.icon ? createIcon(title.icon, { size: 20 }) : null;
|
||||
const icon = _title.icon ? createIcon(_title.icon, { size: 20 }) : null;
|
||||
|
||||
let tip: any = null;
|
||||
if (title.tip) {
|
||||
if (isValidElement(title.tip) && title.tip.type === Tip) {
|
||||
tip = title.tip;
|
||||
if (_title.tip) {
|
||||
if (isValidElement(_title.tip) && _title.tip.type === Tip) {
|
||||
tip = _title.tip;
|
||||
} else {
|
||||
const tipProps =
|
||||
typeof title.tip === 'object' && !(isValidElement(title.tip) || isI18nData(title.tip))
|
||||
? title.tip
|
||||
: { children: title.tip };
|
||||
typeof _title.tip === 'object' && !(isValidElement(_title.tip) || isI18nData(_title.tip))
|
||||
? _title.tip
|
||||
: { children: _title.tip };
|
||||
tip = <Tip {...tipProps} />;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
className={classNames('lc-title', className, title.className, {
|
||||
className={classNames('lc-title', className, _title.className, {
|
||||
'has-tip': !!tip,
|
||||
'only-icon': !title.label,
|
||||
'only-icon': !_title.label,
|
||||
})}
|
||||
onClick={this.handleClick}
|
||||
>
|
||||
{icon ? <b className="lc-title-icon">{icon}</b> : null}
|
||||
{this.renderLabel(title.label)}
|
||||
{this.renderLabel(_title.label)}
|
||||
{tip}
|
||||
</span>
|
||||
);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -47,6 +47,8 @@ function HelpTip({ tip }: any) {
|
||||
|
||||
@observer
|
||||
export class PanelDockView extends Component<DockProps & { dock: PanelDock }> {
|
||||
private lastActived = false;
|
||||
|
||||
componentDidMount() {
|
||||
this.checkActived();
|
||||
}
|
||||
@ -55,8 +57,6 @@ export class PanelDockView extends Component<DockProps & { dock: PanelDock }> {
|
||||
this.checkActived();
|
||||
}
|
||||
|
||||
private lastActived = false;
|
||||
|
||||
checkActived() {
|
||||
const { dock } = this.props;
|
||||
if (dock.actived !== this.lastActived) {
|
||||
@ -134,7 +134,7 @@ export class DraggableLineView extends Component<{ panel: Panel }> {
|
||||
// 默认 关闭,通过配置开启
|
||||
const enableDrag = this.props.panel.config.props?.enableDrag;
|
||||
const isRightArea = this.props.panel.config?.area === 'rightArea';
|
||||
if (isRightArea || !enableDrag || this.props.panel?.parent.name === 'leftFixedArea') {
|
||||
if (isRightArea || !enableDrag || this.props.panel?.parent?.name === 'leftFixedArea') {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
@ -159,6 +159,8 @@ export class DraggableLineView extends Component<{ panel: Panel }> {
|
||||
|
||||
@observer
|
||||
export class TitledPanelView extends Component<{ panel: Panel; area?: string }> {
|
||||
private lastVisible = false;
|
||||
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
}
|
||||
@ -167,8 +169,6 @@ export class TitledPanelView extends Component<{ panel: Panel; area?: string }>
|
||||
this.checkVisible();
|
||||
}
|
||||
|
||||
private lastVisible = false;
|
||||
|
||||
checkVisible() {
|
||||
const { panel } = this.props;
|
||||
const currentVisible = panel.inited && panel.visible;
|
||||
@ -218,6 +218,8 @@ export class PanelView extends Component<{
|
||||
hideOperationRow?: boolean;
|
||||
hideDragLine?: boolean;
|
||||
}> {
|
||||
private lastVisible = false;
|
||||
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
}
|
||||
@ -226,8 +228,6 @@ export class PanelView extends Component<{
|
||||
this.checkVisible();
|
||||
}
|
||||
|
||||
private lastVisible = false;
|
||||
|
||||
checkVisible() {
|
||||
const { panel } = this.props;
|
||||
const currentVisible = panel.inited && panel.visible;
|
||||
@ -331,6 +331,9 @@ class PanelTitle extends Component<{ panel: Panel; className?: string }> {
|
||||
|
||||
@observer
|
||||
export class WidgetView extends Component<{ widget: IWidget }> {
|
||||
private lastVisible = false;
|
||||
private lastDisabled: boolean | undefined = false;
|
||||
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
this.checkDisabled();
|
||||
@ -341,9 +344,6 @@ export class WidgetView extends Component<{ widget: IWidget }> {
|
||||
this.checkDisabled();
|
||||
}
|
||||
|
||||
private lastVisible = false;
|
||||
private lastDisabled = false;
|
||||
|
||||
checkVisible() {
|
||||
const { widget } = this.props;
|
||||
const currentVisible = widget.visible;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -323,10 +323,8 @@ body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
&.has-tip {
|
||||
cursor: pointer;
|
||||
}
|
||||
&.actived {
|
||||
color: #0079f2;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -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 => {}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -461,6 +461,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
locale: renderer.locale,
|
||||
messages: _schema.i18n || {},
|
||||
device: renderer.device,
|
||||
locale: renderer.locale,
|
||||
appHelper: renderer.context,
|
||||
rendererName: 'LowCodeRenderer',
|
||||
thisRequiredInJSE: host.thisRequiredInJSE,
|
||||
@ -632,4 +633,4 @@ function getLowCodeComponentProps(props: any) {
|
||||
return newProps;
|
||||
}
|
||||
|
||||
export default new SimulatorRendererContainer();
|
||||
export default new SimulatorRendererContainer();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {
|
||||
LowCodePluginManager,
|
||||
ILowCodePluginManager,
|
||||
} from '@alilc/lowcode-designer';
|
||||
import { globalContext } from '@alilc/lowcode-editor-core';
|
||||
import {
|
||||
@ -14,8 +14,8 @@ import { pluginsSymbol } from '../symbols';
|
||||
|
||||
const innerPluginsSymbol = Symbol('plugin');
|
||||
export class Plugins implements IPublicApiPlugins {
|
||||
private readonly [innerPluginsSymbol]: LowCodePluginManager;
|
||||
get [pluginsSymbol](): LowCodePluginManager {
|
||||
private readonly [innerPluginsSymbol]: ILowCodePluginManager;
|
||||
get [pluginsSymbol](): ILowCodePluginManager {
|
||||
if (this.workspaceMode) {
|
||||
return this[innerPluginsSymbol];
|
||||
}
|
||||
@ -27,7 +27,7 @@ export class Plugins implements IPublicApiPlugins {
|
||||
return this[innerPluginsSymbol];
|
||||
}
|
||||
|
||||
constructor(plugins: LowCodePluginManager, public workspaceMode: boolean = false) {
|
||||
constructor(plugins: ILowCodePluginManager, public workspaceMode: boolean = false) {
|
||||
this[innerPluginsSymbol] = plugins;
|
||||
}
|
||||
|
||||
|
||||
@ -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':
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { IPublicApiWorkspace, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types';
|
||||
import { Workspace as InnerWorkSpace } from '@alilc/lowcode-workspace';
|
||||
import { IWorkspace } from '@alilc/lowcode-workspace';
|
||||
import { Plugins } from '@alilc/lowcode-shell';
|
||||
import { workspaceSymbol } from '../symbols';
|
||||
import { Resource as ShellResource, Window as ShellWindow } from '../model';
|
||||
|
||||
export class Workspace implements IPublicApiWorkspace {
|
||||
readonly [workspaceSymbol]: InnerWorkSpace;
|
||||
readonly [workspaceSymbol]: IWorkspace;
|
||||
|
||||
constructor(innerWorkspace: InnerWorkSpace) {
|
||||
constructor(innerWorkspace: IWorkspace) {
|
||||
this[workspaceSymbol] = innerWorkspace;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import {
|
||||
IDragon,
|
||||
ILocateEvent as InnerLocateEvent,
|
||||
INode,
|
||||
} from '@alilc/lowcode-designer';
|
||||
import { dragonSymbol, nodeSymbol } from '../symbols';
|
||||
import LocateEvent from './locate-event';
|
||||
@ -11,18 +13,19 @@ import {
|
||||
IPublicModelDragObject,
|
||||
IPublicTypeDragNodeDataObject,
|
||||
IPublicModelNode,
|
||||
IPublicTypeDragObject,
|
||||
} from '@alilc/lowcode-types';
|
||||
|
||||
export const innerDragonSymbol = Symbol('innerDragonSymbol');
|
||||
|
||||
export class Dragon implements IPublicModelDragon {
|
||||
private readonly [innerDragonSymbol]: IPublicModelDragon;
|
||||
private readonly [innerDragonSymbol]: IDragon;
|
||||
|
||||
constructor(innerDragon: IPublicModelDragon, readonly workspaceMode: boolean) {
|
||||
constructor(innerDragon: IDragon, readonly workspaceMode: boolean) {
|
||||
this[innerDragonSymbol] = innerDragon;
|
||||
}
|
||||
|
||||
get [dragonSymbol](): any {
|
||||
get [dragonSymbol](): IDragon {
|
||||
if (this.workspaceMode) {
|
||||
return this[innerDragonSymbol];
|
||||
}
|
||||
@ -38,7 +41,7 @@ export class Dragon implements IPublicModelDragon {
|
||||
}
|
||||
|
||||
static create(
|
||||
dragon: IPublicModelDragon | null,
|
||||
dragon: IDragon | null,
|
||||
workspaceMode: boolean,
|
||||
): IPublicModelDragon | null {
|
||||
if (!dragon) {
|
||||
@ -102,11 +105,13 @@ export class Dragon implements IPublicModelDragon {
|
||||
* @param dragObject 拖拽对象
|
||||
* @param boostEvent 拖拽初始时事件
|
||||
*/
|
||||
boost(dragObject: DragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node | IPublicModelNode): void {
|
||||
boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: IPublicModelNode & {
|
||||
[nodeSymbol]: INode;
|
||||
}): void {
|
||||
return this[dragonSymbol].boost({
|
||||
...dragObject,
|
||||
nodes: dragObject.nodes.map((node: any) => node[nodeSymbol]),
|
||||
}, boostEvent, fromRglNode);
|
||||
}, boostEvent, fromRglNode?.[nodeSymbol]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import { ILocateEvent as InnerLocateEvent } from '@alilc/lowcode-designer';
|
||||
import { ILocateEvent } from '@alilc/lowcode-designer';
|
||||
import { locateEventSymbol } from '../symbols';
|
||||
import { DragObject } from './drag-object';
|
||||
import { IPublicModelLocateEvent, IPublicModelDragObject } from '@alilc/lowcode-types';
|
||||
|
||||
export default class LocateEvent implements IPublicModelLocateEvent {
|
||||
private readonly [locateEventSymbol]: InnerLocateEvent;
|
||||
private readonly [locateEventSymbol]: ILocateEvent;
|
||||
|
||||
constructor(locateEvent: InnerLocateEvent) {
|
||||
constructor(locateEvent: ILocateEvent) {
|
||||
this[locateEventSymbol] = locateEvent;
|
||||
}
|
||||
|
||||
static create(locateEvent: InnerLocateEvent): IPublicModelLocateEvent | null {
|
||||
static create(locateEvent: ILocateEvent): IPublicModelLocateEvent | null {
|
||||
if (!locateEvent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { IPublicModelResource } from '@alilc/lowcode-types';
|
||||
import { Resource as InnerResource } from '@alilc/lowcode-workspace';
|
||||
import { IResource } from '@alilc/lowcode-workspace';
|
||||
import { resourceSymbol } from '../symbols';
|
||||
|
||||
export class Resource implements IPublicModelResource {
|
||||
readonly [resourceSymbol]: InnerResource;
|
||||
readonly [resourceSymbol]: IResource;
|
||||
|
||||
constructor(resource: InnerResource) {
|
||||
constructor(resource: IResource) {
|
||||
this[resourceSymbol] = resource;
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { windowSymbol } from '../symbols';
|
||||
import { IPublicModelResource, IPublicModelWindow, IPublicTypeDisposable } from '@alilc/lowcode-types';
|
||||
import { EditorWindow } from '@alilc/lowcode-workspace';
|
||||
import { IEditorWindow } from '@alilc/lowcode-workspace';
|
||||
import { Resource as ShellResource } from './resource';
|
||||
|
||||
export class Window implements IPublicModelWindow {
|
||||
private readonly [windowSymbol]: EditorWindow;
|
||||
private readonly [windowSymbol]: IEditorWindow;
|
||||
|
||||
get id() {
|
||||
return this[windowSymbol]?.id;
|
||||
@ -22,7 +22,7 @@ export class Window implements IPublicModelWindow {
|
||||
return new ShellResource(this[windowSymbol].resource);
|
||||
}
|
||||
|
||||
constructor(editorWindow: EditorWindow) {
|
||||
constructor(editorWindow: IEditorWindow) {
|
||||
this[windowSymbol] = editorWindow;
|
||||
}
|
||||
|
||||
|
||||
@ -2,19 +2,20 @@ import { IPublicModelWindow } from '../model';
|
||||
import { IPublicApiPlugins, IPublicModelResource, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType } from '@alilc/lowcode-types';
|
||||
|
||||
export interface IPublicApiWorkspace<
|
||||
Plugins = IPublicApiPlugins
|
||||
Plugins = IPublicApiPlugins,
|
||||
ModelWindow = IPublicModelWindow
|
||||
> {
|
||||
|
||||
/** 是否启用 workspace 模式 */
|
||||
isActive: boolean;
|
||||
|
||||
/** 当前设计器窗口 */
|
||||
window: IPublicModelWindow;
|
||||
window: ModelWindow;
|
||||
|
||||
plugins: Plugins;
|
||||
|
||||
/** 当前设计器的编辑窗口 */
|
||||
windows: IPublicModelWindow[];
|
||||
windows: ModelWindow[];
|
||||
|
||||
/** 获取资源树列表 */
|
||||
get resourceList(): IPublicModelResource[];
|
||||
|
||||
@ -1,8 +1,3 @@
|
||||
export interface IPublicModelDragObject {
|
||||
import { IPublicTypeDragNodeDataObject, IPublicTypeDragNodeObject } from '../type';
|
||||
|
||||
get type(): any;
|
||||
|
||||
get nodes(): any;
|
||||
|
||||
get data(): any;
|
||||
}
|
||||
export type IPublicModelDragObject = Readonly<IPublicTypeDragNodeObject> | Readonly<IPublicTypeDragNodeDataObject>;
|
||||
|
||||
@ -3,7 +3,8 @@ import { IPublicTypeDragNodeDataObject, IPublicTypeDragObject } from '../type';
|
||||
import { IPublicModelDragObject, IPublicModelLocateEvent, IPublicModelNode } from './';
|
||||
|
||||
export interface IPublicModelDragon<
|
||||
Node = IPublicModelNode
|
||||
Node = IPublicModelNode,
|
||||
LocateEvent = IPublicModelLocateEvent
|
||||
> {
|
||||
|
||||
/**
|
||||
@ -18,7 +19,7 @@ export interface IPublicModelDragon<
|
||||
* @param func
|
||||
* @returns
|
||||
*/
|
||||
onDragstart(func: (e: IPublicModelLocateEvent) => any): () => void;
|
||||
onDragstart(func: (e: LocateEvent) => any): () => void;
|
||||
|
||||
/**
|
||||
* 绑定 drag 事件
|
||||
@ -26,7 +27,7 @@ export interface IPublicModelDragon<
|
||||
* @param func
|
||||
* @returns
|
||||
*/
|
||||
onDrag(func: (e: IPublicModelLocateEvent) => any): () => void;
|
||||
onDrag(func: (e: LocateEvent) => any): () => void;
|
||||
|
||||
/**
|
||||
* 绑定 dragend 事件
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
export interface IPublicModelResource {
|
||||
export interface IBaseModelResource<
|
||||
Resource
|
||||
> {
|
||||
get title(): string | undefined;
|
||||
|
||||
get icon(): ReactElement | undefined;
|
||||
@ -13,7 +15,9 @@ export interface IPublicModelResource {
|
||||
|
||||
get category(): string | undefined;
|
||||
|
||||
get children(): IPublicModelResource[];
|
||||
get children(): Resource[];
|
||||
|
||||
get viewName(): string | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export type IPublicModelResource = IBaseModelResource<IPublicModelResource>;
|
||||
|
||||
@ -2,7 +2,9 @@ import { ReactElement } from 'react';
|
||||
import { IPublicTypeDisposable, IPublicTypeNodeSchema } from '../type';
|
||||
import { IPublicModelResource } from './resource';
|
||||
|
||||
export interface IPublicModelWindow {
|
||||
export interface IPublicModelWindow<
|
||||
Resource = IPublicModelResource
|
||||
> {
|
||||
|
||||
/** 窗口 id */
|
||||
id: string;
|
||||
@ -14,7 +16,7 @@ export interface IPublicModelWindow {
|
||||
icon?: ReactElement;
|
||||
|
||||
/** 窗口资源类型 */
|
||||
resource?: IPublicModelResource;
|
||||
resource?: Resource;
|
||||
|
||||
/** 当前窗口导入 schema */
|
||||
importSchema(schema: IPublicTypeNodeSchema): void;
|
||||
|
||||
@ -1,19 +1,23 @@
|
||||
import { IPublicModelNode } from '../model';
|
||||
import { IPublicTypeIconType, TipContent } from './';
|
||||
|
||||
/**
|
||||
* 动作描述
|
||||
*/
|
||||
export interface IPublicTypeActionContentObject {
|
||||
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
icon?: IPublicTypeIconType;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
title?: TipContent;
|
||||
|
||||
/**
|
||||
* 执行动作
|
||||
*/
|
||||
action?: (currentNode: any) => void;
|
||||
action?: (currentNode: IPublicModelNode) => void;
|
||||
}
|
||||
|
||||
@ -15,13 +15,14 @@ export enum LocationDetailType {
|
||||
}
|
||||
|
||||
export type IPublicTypeRect = DOMRect & {
|
||||
elements: Array<Element | Text>;
|
||||
elements?: Array<Element | Text>;
|
||||
computed?: boolean;
|
||||
};
|
||||
|
||||
export interface IPublicTypeLocationChildrenDetail {
|
||||
type: IPublicTypeLocationDetailType.Children;
|
||||
index?: number | null;
|
||||
|
||||
/**
|
||||
* 是否有效位置
|
||||
*/
|
||||
@ -43,8 +44,7 @@ export interface IPublicTypeLocationPropDetail {
|
||||
domNode?: HTMLElement;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
export type IPublicTypeLocationDetail = IPublicTypeLocationChildrenDetail | IPublicTypeLocationPropDetail | { type: string; [key: string]: any };
|
||||
export type IPublicTypeLocationDetail = IPublicTypeLocationChildrenDetail | IPublicTypeLocationPropDetail | { [key: string]: any; type: string };
|
||||
|
||||
export interface IPublicTypeLocationData<
|
||||
Node = IPublicModelNode
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { MouseEvent } from 'react';
|
||||
import { IPublicTypePropType, IPublicTypeComponentAction } from './';
|
||||
import { IPublicModelNode, IPublicModelProp, IPublicModelSettingField } from '../model';
|
||||
|
||||
|
||||
@ -1,20 +1,27 @@
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
export interface IPublicResourceData {
|
||||
|
||||
/** 资源名字 */
|
||||
resourceName: string;
|
||||
|
||||
/** 资源标题 */
|
||||
title: string;
|
||||
title?: string;
|
||||
|
||||
/** 分类 */
|
||||
category?: string;
|
||||
|
||||
/** 资源视图 */
|
||||
viewName?: string;
|
||||
|
||||
/** 资源 icon */
|
||||
icon?: ReactElement;
|
||||
|
||||
/** 资源其他配置 */
|
||||
options: {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
/** 资源子元素 */
|
||||
children?: IPublicResourceData[];
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { IPublicTypeActionContentObject } from '@alilc/lowcode-types';
|
||||
|
||||
export function isActionContentObject(obj: any): boolean {
|
||||
export function isActionContentObject(obj: any): obj is IPublicTypeActionContentObject {
|
||||
return obj && typeof obj === 'object';
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { IPublicTypeLocationData } from '@alilc/lowcode-types';
|
||||
|
||||
export function isLocationData(obj: any): boolean {
|
||||
export function isLocationData(obj: any): obj is IPublicTypeLocationData {
|
||||
return obj && obj.target && obj.detail;
|
||||
}
|
||||
@ -10,14 +10,13 @@ const pseudoMap = ['hover', 'focus', 'active', 'visited'];
|
||||
|
||||
const RE_CAMEL = /[A-Z]/g;
|
||||
const RE_HYPHEN = /[-\s]+(.)?/g;
|
||||
const CSS_REG = /:root(.*)\{.*/i;
|
||||
const PROPS_REG = /([^:]*):\s?(.*)/i;
|
||||
|
||||
// 给 css 分组
|
||||
function groupingCss(css) {
|
||||
function groupingCss(css: string) {
|
||||
let stackLength = 0;
|
||||
let startIndex = 0;
|
||||
const group = [];
|
||||
const group: string[] = [];
|
||||
css.split('').forEach((char, index) => {
|
||||
if (char === '{') {
|
||||
stackLength++;
|
||||
@ -33,38 +32,38 @@ function groupingCss(css) {
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
function isString(str) {
|
||||
function isString(str: any): str is string {
|
||||
return {}.toString.call(str) === '[object String]';
|
||||
}
|
||||
|
||||
function hyphenate(str) {
|
||||
function hyphenate(str: string): string {
|
||||
return str.replace(RE_CAMEL, w => `-${w}`).toLowerCase();
|
||||
}
|
||||
|
||||
function camelize(str) {
|
||||
function camelize(str: string): string {
|
||||
return str.replace(RE_HYPHEN, (m, w) => (w ? w.toUpperCase() : ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* convert
|
||||
* {background-color: "red"}
|
||||
* to
|
||||
* background-color: red;
|
||||
*/
|
||||
function runtimeToCss(runtime) {
|
||||
const css = [];
|
||||
function runtimeToCss(runtime: Record<string, string>) {
|
||||
const css: string[] = [];
|
||||
Object.keys(runtime).forEach((key) => {
|
||||
css.push(` ${key}: ${runtime[key]};`);
|
||||
});
|
||||
return css.join('\n');
|
||||
}
|
||||
|
||||
function toNativeStyle(runtime) {
|
||||
function toNativeStyle(runtime: Record<string, string> | undefined) {
|
||||
if (!runtime) {
|
||||
return {};
|
||||
}
|
||||
if (runtime.default) {
|
||||
const normalized = {};
|
||||
const normalized: Record<string, string> = {};
|
||||
Object.keys(runtime).forEach((pseudo) => {
|
||||
if (pseudo === 'extra') {
|
||||
normalized[pseudo] = runtime[pseudo];
|
||||
@ -98,14 +97,13 @@ function normalizeStyle(style) {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
const normalized = {};
|
||||
const normalized: Record<string, string | Record<string, string>> = {};
|
||||
Object.keys(style).forEach((key) => {
|
||||
normalized[hyphenate(key)] = style[key];
|
||||
});
|
||||
return normalized;
|
||||
}
|
||||
|
||||
|
||||
function toCss(runtime) {
|
||||
if (!runtime) {
|
||||
return (
|
||||
@ -115,7 +113,7 @@ function toCss(runtime) {
|
||||
}
|
||||
|
||||
if (runtime.default) {
|
||||
const css = [];
|
||||
const css: string[] = [];
|
||||
Object.keys(runtime).forEach((pseudo) => {
|
||||
if (pseudo === 'extra') {
|
||||
Array.isArray(runtime.extra) && css.push(runtime.extra.join('\n'));
|
||||
@ -140,11 +138,14 @@ ${runtimeToCss(normalizeStyle(runtime))}
|
||||
);
|
||||
}
|
||||
|
||||
function cssToRuntime(css) {
|
||||
function cssToRuntime(css: string) {
|
||||
if (!css) {
|
||||
return {};
|
||||
}
|
||||
const runtime = {};
|
||||
const runtime: {
|
||||
extra?: string[];
|
||||
default?: Record<string, string>;
|
||||
} = {};
|
||||
const groups = groupingCss(css);
|
||||
groups.forEach((cssItem) => {
|
||||
if (!cssItem.startsWith(':root')) {
|
||||
@ -153,7 +154,7 @@ function cssToRuntime(css) {
|
||||
} else {
|
||||
const res = /:root:?(.*)?{(.*)/ig.exec(cssItem.replace(/[\r\n]+/ig, '').trim());
|
||||
if (res) {
|
||||
let pseudo;
|
||||
let pseudo: string | undefined;
|
||||
|
||||
if (res[1] && res[1].trim() && some(pseudoMap, pse => res[1].indexOf(pse) === 0)) {
|
||||
pseudo = res[1].trim();
|
||||
@ -161,8 +162,8 @@ function cssToRuntime(css) {
|
||||
pseudo = res[1];
|
||||
}
|
||||
|
||||
const s = {};
|
||||
res[2].split(';').reduce((prev, next) => {
|
||||
const s: Record<string, string> = {};
|
||||
res[2].split(';').reduce<string[]>((prev, next) => {
|
||||
if (next.indexOf('base64') > -1) {
|
||||
prev[prev.length - 1] += `;${next}`;
|
||||
} else {
|
||||
@ -173,8 +174,8 @@ function cssToRuntime(css) {
|
||||
if (item) {
|
||||
if (PROPS_REG.test(item)) {
|
||||
const props = item.match(PROPS_REG);
|
||||
const key = props[1];
|
||||
const value = props[2];
|
||||
const key = props?.[1];
|
||||
const value = props?.[2];
|
||||
if (key && value) {
|
||||
s[key.trim()] = value.trim();
|
||||
}
|
||||
@ -182,10 +183,7 @@ function cssToRuntime(css) {
|
||||
}
|
||||
});
|
||||
|
||||
if (!pseudo) {
|
||||
pseudo = 'default';
|
||||
}
|
||||
runtime[pseudo] = s;
|
||||
runtime[pseudo || 'default'] = s;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -23,7 +23,8 @@ export function isReactComponent(obj: any): obj is ComponentType<any> {
|
||||
export function wrapReactClass(view: FunctionComponent) {
|
||||
let ViewComponentClass = class extends Component {
|
||||
render() {
|
||||
return createElement(view, this.props);
|
||||
const { children, ...other } = this.props;
|
||||
return createElement(view, other, children);
|
||||
}
|
||||
} as any;
|
||||
ViewComponentClass = cloneEnumerableProperty(ViewComponentClass, view);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
// 仅使用类型
|
||||
import { IPublicModelNode } from '@alilc/lowcode-types';
|
||||
import { MouseEvent } from 'react';
|
||||
|
||||
export const getClosestNode = <Node extends IPublicModelNode = IPublicModelNode>(
|
||||
node: Node,
|
||||
@ -12,7 +13,7 @@ export const getClosestNode = <Node extends IPublicModelNode = IPublicModelNode>
|
||||
return node;
|
||||
} else {
|
||||
// @ts-ignore
|
||||
return getClosestNode(node.getParent(), until);
|
||||
return getClosestNode(node.parent, until);
|
||||
}
|
||||
};
|
||||
|
||||
@ -22,8 +23,8 @@ export const getClosestNode = <Node extends IPublicModelNode = IPublicModelNode>
|
||||
* @param {unknown} e 点击事件
|
||||
* @returns {boolean} 是否可点击,true表示可点击
|
||||
*/
|
||||
export function canClickNode<Node extends IPublicModelNode = IPublicModelNode>(node: Node, e: unknown): boolean {
|
||||
export function canClickNode<Node extends IPublicModelNode = IPublicModelNode>(node: Node, e: MouseEvent): boolean {
|
||||
const onClickHook = node.componentMeta?.advanced?.callbacks?.onClickHook;
|
||||
const canClick = typeof onClickHook === 'function' ? onClickHook(e as MouseEvent, node) : true;
|
||||
const canClick = typeof onClickHook === 'function' ? onClickHook(e, node) : true;
|
||||
return canClick;
|
||||
};
|
||||
}
|
||||
|
||||
@ -3,13 +3,17 @@ import {
|
||||
engineConfig, Setters as InnerSetters,
|
||||
Hotkey as InnerHotkey,
|
||||
commonEvent,
|
||||
IEngineConfig,
|
||||
IHotKey,
|
||||
} from '@alilc/lowcode-editor-core';
|
||||
import {
|
||||
Designer,
|
||||
ILowCodePluginContextApiAssembler,
|
||||
LowCodePluginManager,
|
||||
ILowCodePluginContextPrivate,
|
||||
Project as InnerProject,
|
||||
IProject,
|
||||
IDesigner,
|
||||
ILowCodePluginManager,
|
||||
} from '@alilc/lowcode-designer';
|
||||
import {
|
||||
Skeleton as InnerSkeleton,
|
||||
@ -29,40 +33,72 @@ import {
|
||||
} from '@alilc/lowcode-shell';
|
||||
import {
|
||||
IPluginPreferenceMananger,
|
||||
IPublicApiCanvas,
|
||||
IPublicApiCommon,
|
||||
IPublicApiEvent,
|
||||
IPublicApiWorkspace,
|
||||
IPublicApiHotkey,
|
||||
IPublicApiMaterial,
|
||||
IPublicApiPlugins,
|
||||
IPublicApiProject,
|
||||
IPublicApiSetters,
|
||||
IPublicApiSkeleton,
|
||||
IPublicModelPluginContext,
|
||||
IPublicTypePluginMeta,
|
||||
} from '@alilc/lowcode-types';
|
||||
import { getLogger } from '@alilc/lowcode-utils';
|
||||
import { Workspace as InnerWorkspace } from '../workspace';
|
||||
import { EditorWindow } from '../window';
|
||||
import { getLogger, Logger as InnerLogger } from '@alilc/lowcode-utils';
|
||||
import { IWorkspace } from '../workspace';
|
||||
import { IEditorWindow } from '../window';
|
||||
|
||||
export class BasicContext implements IPublicModelPluginContext {
|
||||
skeleton: Skeleton;
|
||||
plugins: Plugins;
|
||||
project: Project;
|
||||
setters: Setters;
|
||||
material: Material;
|
||||
common: Common;
|
||||
config;
|
||||
event;
|
||||
logger;
|
||||
hotkey: Hotkey;
|
||||
innerProject: InnerProject;
|
||||
export interface IBasicContext extends Omit<IPublicModelPluginContext, 'workspace'> {
|
||||
skeleton: IPublicApiSkeleton;
|
||||
plugins: IPublicApiPlugins;
|
||||
project: IPublicApiProject;
|
||||
setters: IPublicApiSetters;
|
||||
material: IPublicApiMaterial;
|
||||
common: IPublicApiCommon;
|
||||
config: IEngineConfig;
|
||||
event: IPublicApiEvent;
|
||||
logger: InnerLogger;
|
||||
hotkey: IPublicApiHotkey;
|
||||
innerProject: IProject;
|
||||
editor: Editor;
|
||||
designer: Designer;
|
||||
designer: IDesigner;
|
||||
registerInnerPlugins: () => Promise<void>;
|
||||
innerSetters: InnerSetters;
|
||||
innerSkeleton: InnerSkeleton;
|
||||
innerHotkey: InnerHotkey;
|
||||
innerPlugins: LowCodePluginManager;
|
||||
canvas: Canvas;
|
||||
innerHotkey: IHotKey;
|
||||
innerPlugins: ILowCodePluginManager;
|
||||
canvas: IPublicApiCanvas;
|
||||
pluginEvent: IPublicApiEvent;
|
||||
preference: IPluginPreferenceMananger;
|
||||
workspace: IPublicApiWorkspace;
|
||||
workspace: IWorkspace;
|
||||
}
|
||||
|
||||
constructor(innerWorkspace: InnerWorkspace, viewName: string, public editorWindow?: EditorWindow) {
|
||||
export class BasicContext implements IBasicContext {
|
||||
skeleton: IPublicApiSkeleton;
|
||||
plugins: IPublicApiPlugins;
|
||||
project: IPublicApiProject;
|
||||
setters: IPublicApiSetters;
|
||||
material: IPublicApiMaterial;
|
||||
common: IPublicApiCommon;
|
||||
config: IEngineConfig;
|
||||
event: IPublicApiEvent;
|
||||
logger: InnerLogger;
|
||||
hotkey: IPublicApiHotkey;
|
||||
innerProject: IProject;
|
||||
editor: Editor;
|
||||
designer: IDesigner;
|
||||
registerInnerPlugins: () => Promise<void>;
|
||||
innerSetters: InnerSetters;
|
||||
innerSkeleton: InnerSkeleton;
|
||||
innerHotkey: IHotKey;
|
||||
innerPlugins: ILowCodePluginManager;
|
||||
canvas: IPublicApiCanvas;
|
||||
pluginEvent: IPublicApiEvent;
|
||||
preference: IPluginPreferenceMananger;
|
||||
workspace: IWorkspace;
|
||||
|
||||
constructor(innerWorkspace: IWorkspace, viewName: string, public editorWindow?: IEditorWindow) {
|
||||
const editor = new Editor(viewName, true);
|
||||
|
||||
const innerSkeleton = new InnerSkeleton(editor, viewName);
|
||||
@ -110,7 +146,7 @@ export class BasicContext implements IPublicModelPluginContext {
|
||||
this.canvas = canvas;
|
||||
const common = new Common(editor, innerSkeleton);
|
||||
this.common = common;
|
||||
let plugins: any;
|
||||
let plugins: IPublicApiPlugins;
|
||||
|
||||
const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = {
|
||||
assembleApis: (context: ILowCodePluginContextPrivate, pluginName: string, meta: IPublicTypePluginMeta) => {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { computed, makeObservable, obx } from '@alilc/lowcode-editor-core';
|
||||
import { IPublicEditorViewConfig, IPublicTypeEditorView } from '@alilc/lowcode-types';
|
||||
import { flow } from 'mobx';
|
||||
import { Workspace as InnerWorkspace } from '../workspace';
|
||||
import { IWorkspace } from '../workspace';
|
||||
import { BasicContext } from './base-context';
|
||||
import { EditorWindow } from '../window';
|
||||
import { IEditorWindow } from '../window';
|
||||
import { getWebviewPlugin } from '../inner-plugins/webview';
|
||||
|
||||
export class Context extends BasicContext {
|
||||
@ -21,7 +21,7 @@ export class Context extends BasicContext {
|
||||
return this._activate;
|
||||
}
|
||||
|
||||
init = flow(function* (this: any) {
|
||||
init = flow(function* (this: Context) {
|
||||
if (this.viewType === 'webview') {
|
||||
const url = yield this.instance?.url?.();
|
||||
yield this.plugins.register(getWebviewPlugin(url, this.viewName));
|
||||
@ -33,7 +33,7 @@ export class Context extends BasicContext {
|
||||
this.isInit = true;
|
||||
});
|
||||
|
||||
constructor(public workspace: InnerWorkspace, public editorWindow: EditorWindow, public editorView: IPublicTypeEditorView, options: Object | undefined) {
|
||||
constructor(public workspace: IWorkspace, public editorWindow: IEditorWindow, public editorView: IPublicTypeEditorView, options: Object | undefined) {
|
||||
super(workspace, editorView.viewName, editorWindow);
|
||||
this.viewType = editorView.viewType || 'editor';
|
||||
this.viewName = editorView.viewName;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export { Workspace } from './workspace';
|
||||
export { Workspace, IWorkspace } from './workspace';
|
||||
export * from './window';
|
||||
export * from './layouts/workbench';
|
||||
export { Resource } from './resource';
|
||||
export { Resource, IResource } from './resource';
|
||||
|
||||
@ -1,6 +1,14 @@
|
||||
import { IPublicTypeResourceType } from '@alilc/lowcode-types';
|
||||
|
||||
export class ResourceType {
|
||||
export interface IResourceType extends Omit<IPublicTypeResourceType, 'resourceName' | 'resourceType'> {
|
||||
name: string;
|
||||
|
||||
type: 'editor' | 'webview';
|
||||
|
||||
resourceTypeModel: IPublicTypeResourceType;
|
||||
}
|
||||
|
||||
export class ResourceType implements IResourceType {
|
||||
constructor(readonly resourceTypeModel: IPublicTypeResourceType) {
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,31 @@
|
||||
import { IPublicTypeEditorView, IPublicModelResource, IPublicResourceData, IPublicResourceTypeConfig } from '@alilc/lowcode-types';
|
||||
import { IPublicTypeEditorView, IPublicResourceData, IPublicResourceTypeConfig, IBaseModelResource } from '@alilc/lowcode-types';
|
||||
import { Logger } from '@alilc/lowcode-utils';
|
||||
import { BasicContext } from './context/base-context';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { Workspace as InnerWorkSpace } from './workspace';
|
||||
import { BasicContext, IBasicContext } from './context/base-context';
|
||||
import { ResourceType, IResourceType } from './resource-type';
|
||||
import { IWorkspace } from './workspace';
|
||||
|
||||
const logger = new Logger({ level: 'warn', bizName: 'workspace:resource' });
|
||||
|
||||
export class Resource implements IPublicModelResource {
|
||||
private context: BasicContext;
|
||||
export interface IBaseResource<T> extends IBaseModelResource<T> {
|
||||
readonly resourceType: ResourceType;
|
||||
|
||||
get editorViews(): IPublicTypeEditorView[];
|
||||
|
||||
get defaultViewType(): string;
|
||||
|
||||
getEditorView(name: string): IPublicTypeEditorView | undefined;
|
||||
|
||||
import(schema: any): Promise<any>;
|
||||
|
||||
save(value: any): Promise<any>;
|
||||
|
||||
url(): Promise<string | undefined>;
|
||||
}
|
||||
|
||||
export type IResource = IBaseResource<IResource>;
|
||||
|
||||
export class Resource implements IResource {
|
||||
private context: IBasicContext;
|
||||
|
||||
resourceTypeInstance: IPublicResourceTypeConfig;
|
||||
|
||||
@ -49,13 +67,15 @@ export class Resource implements IPublicModelResource {
|
||||
return this.context.innerSkeleton;
|
||||
}
|
||||
|
||||
get children(): Resource[] {
|
||||
get children(): IResource[] {
|
||||
return this.resourceData?.children?.map(d => new Resource(d, this.resourceType, this.workspace)) || [];
|
||||
}
|
||||
|
||||
constructor(readonly resourceData: IPublicResourceData, readonly resourceType: ResourceType, readonly workspace: InnerWorkSpace) {
|
||||
constructor(readonly resourceData: IPublicResourceData, readonly resourceType: IResourceType, readonly workspace: IWorkspace) {
|
||||
this.context = new BasicContext(workspace, `resource-${resourceData.resourceName || resourceType.name}`);
|
||||
this.resourceTypeInstance = resourceType.resourceTypeModel(this.context, this.options);
|
||||
this.resourceTypeInstance = resourceType.resourceTypeModel(this.context.innerPlugins._getLowCodePluginContext({
|
||||
pluginName: '',
|
||||
}), this.options);
|
||||
this.init();
|
||||
if (this.resourceTypeInstance.editorViews) {
|
||||
this.resourceTypeInstance.editorViews.forEach((d: any) => {
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { uniqueId } from '@alilc/lowcode-utils';
|
||||
import { createModuleEventBus, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core';
|
||||
import { Context } from './context/view-context';
|
||||
import { Workspace } from './workspace';
|
||||
import { Resource } from './resource';
|
||||
import { IWorkspace } from './workspace';
|
||||
import { IResource } from './resource';
|
||||
import { IPublicTypeDisposable } from '../../types/es/shell/type/disposable';
|
||||
import { IPublicModelWindow } from '@alilc/lowcode-types';
|
||||
|
||||
interface IWindowCOnfig {
|
||||
title: string | undefined;
|
||||
@ -11,7 +12,13 @@ interface IWindowCOnfig {
|
||||
viewType?: string | undefined;
|
||||
}
|
||||
|
||||
export class EditorWindow {
|
||||
export interface IEditorWindow extends Omit<IPublicModelWindow<IResource>, 'changeViewType'> {
|
||||
readonly resource: IResource;
|
||||
|
||||
changeViewType: (name: string, ignoreEmit?: boolean) => void;
|
||||
}
|
||||
|
||||
export class EditorWindow implements IEditorWindow {
|
||||
id: string = uniqueId('window');
|
||||
icon: React.ReactElement | undefined;
|
||||
|
||||
@ -27,7 +34,7 @@ export class EditorWindow {
|
||||
|
||||
@obx initReady = false;
|
||||
|
||||
constructor(readonly resource: Resource, readonly workspace: Workspace, private config: IWindowCOnfig) {
|
||||
constructor(readonly resource: IResource, readonly workspace: IWorkspace, private config: IWindowCOnfig) {
|
||||
makeObservable(this);
|
||||
this.init();
|
||||
this.title = config.title;
|
||||
|
||||
@ -1,23 +1,33 @@
|
||||
import { Designer, LowCodePluginManager } from '@alilc/lowcode-designer';
|
||||
import { IDesigner, ILowCodePluginManager, LowCodePluginManager } from '@alilc/lowcode-designer';
|
||||
import { createModuleEventBus, Editor, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core';
|
||||
import { Plugins } from '@alilc/lowcode-shell';
|
||||
import { IPublicApiWorkspace, IPublicResourceList, IPublicTypeResourceType } from '@alilc/lowcode-types';
|
||||
import { IPublicApiPlugins, IPublicApiWorkspace, IPublicResourceList, IPublicTypeResourceType, IShellModelFactory } from '@alilc/lowcode-types';
|
||||
import { BasicContext } from './context/base-context';
|
||||
import { EditorWindow } from './window';
|
||||
import { Resource } from './resource';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { EditorWindow, IEditorWindow } from './window';
|
||||
import { IResource, Resource } from './resource';
|
||||
import { IResourceType, ResourceType } from './resource-type';
|
||||
|
||||
enum event {
|
||||
ChangeWindow = 'change_window',
|
||||
enum EVENT {
|
||||
CHANGE_WINDOW = 'change_window',
|
||||
|
||||
ChangeActiveWindow = 'change_active_window',
|
||||
CHANGE_ACTIVE_WINDOW = 'change_active_window',
|
||||
}
|
||||
|
||||
const CHANGE_EVENT = 'resource.list.change';
|
||||
|
||||
interface IWorkspace extends Omit<IPublicApiWorkspace<
|
||||
LowCodePluginManager
|
||||
>, 'resourceList'> {}
|
||||
export interface IWorkspace extends Omit<IPublicApiWorkspace<
|
||||
LowCodePluginManager,
|
||||
IEditorWindow
|
||||
>, 'resourceList' | 'plugins'> {
|
||||
readonly registryInnerPlugin: (designer: IDesigner, editor: Editor, plugins: IPublicApiPlugins) => Promise<void>;
|
||||
|
||||
readonly shellModelFactory: IShellModelFactory;
|
||||
|
||||
window: IEditorWindow;
|
||||
|
||||
plugins: ILowCodePluginManager;
|
||||
|
||||
getResourceList(): IResource[];
|
||||
}
|
||||
|
||||
export class Workspace implements IWorkspace {
|
||||
context: BasicContext;
|
||||
@ -28,7 +38,7 @@ export class Workspace implements IWorkspace {
|
||||
|
||||
private resourceTypeMap: Map<string, ResourceType> = new Map();
|
||||
|
||||
private resourceList: Resource[] = [];
|
||||
private resourceList: IResource[] = [];
|
||||
|
||||
get skeleton() {
|
||||
return this.context.innerSkeleton;
|
||||
@ -50,14 +60,14 @@ export class Workspace implements IWorkspace {
|
||||
return null;
|
||||
}
|
||||
|
||||
@obx.ref windows: EditorWindow[] = [];
|
||||
@obx.ref windows: IEditorWindow[] = [];
|
||||
|
||||
editorWindowMap: Map<string, EditorWindow> = new Map<string, EditorWindow>();
|
||||
editorWindowMap: Map<string, IEditorWindow> = new Map<string, IEditorWindow>();
|
||||
|
||||
@obx.ref window: EditorWindow;
|
||||
@obx.ref window: IEditorWindow;
|
||||
|
||||
constructor(
|
||||
readonly registryInnerPlugin: (designer: Designer, editor: Editor, plugins: Plugins) => Promise<void>,
|
||||
readonly registryInnerPlugin: (designer: IDesigner, editor: Editor, plugins: IPublicApiPlugins) => Promise<void>,
|
||||
readonly shellModelFactory: any,
|
||||
) {
|
||||
this.init();
|
||||
@ -74,7 +84,10 @@ export class Workspace implements IWorkspace {
|
||||
return;
|
||||
}
|
||||
const title = this.defaultResourceType.name;
|
||||
const resource = new Resource({}, this.defaultResourceType, this);
|
||||
const resource = new Resource({
|
||||
resourceName: title,
|
||||
options: {},
|
||||
}, this.defaultResourceType, this);
|
||||
this.window = new EditorWindow(resource, this, {
|
||||
title,
|
||||
});
|
||||
@ -113,7 +126,7 @@ export class Workspace implements IWorkspace {
|
||||
};
|
||||
}
|
||||
|
||||
getResourceType(resourceName: string): ResourceType {
|
||||
getResourceType(resourceName: string): IResourceType {
|
||||
return this.resourceTypeMap.get(resourceName)!;
|
||||
}
|
||||
|
||||
@ -139,7 +152,7 @@ export class Workspace implements IWorkspace {
|
||||
}
|
||||
|
||||
removeEditorWindow(resourceName: string) {
|
||||
const index = this.windows.findIndex(d => (d.resource.name === resourceName && d.title));
|
||||
const index = this.windows.findIndex(d => (d.resource?.name === resourceName && d.title));
|
||||
this.remove(index);
|
||||
}
|
||||
|
||||
@ -157,7 +170,7 @@ export class Workspace implements IWorkspace {
|
||||
console.error(`${name} resourceType is not available`);
|
||||
return;
|
||||
}
|
||||
const filterWindows = this.windows.filter(d => (d.resource.name === name && d.resource.title == title));
|
||||
const filterWindows = this.windows.filter(d => (d.resource?.name === name && d.resource.title == title));
|
||||
if (filterWindows && filterWindows.length) {
|
||||
this.window = filterWindows[0];
|
||||
this.emitChangeActiveWindow();
|
||||
@ -180,24 +193,24 @@ export class Workspace implements IWorkspace {
|
||||
}
|
||||
|
||||
onChangeWindows(fn: () => void) {
|
||||
this.emitter.on(event.ChangeWindow, fn);
|
||||
this.emitter.on(EVENT.CHANGE_WINDOW, fn);
|
||||
return () => {
|
||||
this.emitter.removeListener(event.ChangeWindow, fn);
|
||||
this.emitter.removeListener(EVENT.CHANGE_WINDOW, fn);
|
||||
};
|
||||
}
|
||||
|
||||
emitChangeWindow() {
|
||||
this.emitter.emit(event.ChangeWindow);
|
||||
this.emitter.emit(EVENT.CHANGE_WINDOW);
|
||||
}
|
||||
|
||||
emitChangeActiveWindow() {
|
||||
this.emitter.emit(event.ChangeActiveWindow);
|
||||
this.emitter.emit(EVENT.CHANGE_ACTIVE_WINDOW);
|
||||
}
|
||||
|
||||
onChangeActiveWindow(fn: () => void) {
|
||||
this.emitter.on(event.ChangeActiveWindow, fn);
|
||||
this.emitter.on(EVENT.CHANGE_ACTIVE_WINDOW, fn);
|
||||
return () => {
|
||||
this.emitter.removeListener(event.ChangeActiveWindow, fn);
|
||||
this.emitter.removeListener(EVENT.CHANGE_ACTIVE_WINDOW, fn);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user