fix: fix workspace api ts defined

This commit is contained in:
liujuping 2023-03-20 14:48:59 +08:00 committed by 林熠
parent 12a22de169
commit 6d4ca29466
37 changed files with 348 additions and 219 deletions

View File

@ -52,6 +52,6 @@ module.exports = {
'error',
{ default: ['signature', 'field', 'constructor', 'method'] }
],
'no-unused-vars': ['error', { "destructuredArrayIgnorePattern": "^_" }]
'@typescript-eslint/no-unused-vars': ['error']
},
};

View File

@ -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;
}

View File

@ -47,26 +47,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 +164,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();
@ -217,7 +217,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 +559,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 +675,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 +741,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 +812,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
/**
* @see ISimulator
*/
setSuspense(suspended: boolean) {
setSuspense(/** _suspended: boolean */) {
return false;
// if (suspended) {
// /*
@ -897,7 +897,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 +1018,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 +1186,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 +1255,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
};
const locationData = {
target: container as INode,
target: container,
detail,
source: `simulator${document.id}`,
event: e,
@ -1279,12 +1280,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 +1342,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 +1471,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 +1489,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 +1515,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);

View File

@ -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>
);

View File

@ -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;

View File

@ -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,14 @@ 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> {
emitter: IEventBus;
}
@ -130,7 +130,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 +167,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 +264,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();

View File

@ -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;

View File

@ -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;
/**

View File

@ -6,7 +6,6 @@ import {
IPublicApiMaterial,
IPublicApiEvent,
IPublicApiCommon,
IPublicTypeCompositeObject,
IPublicApiPlugins,
IPublicTypePluginConfig,
IPublicApiLogger,
@ -16,6 +15,7 @@ import {
IPublicApiCanvas,
IPublicApiWorkspace,
IPublicTypePluginMeta,
IPublicTypePluginRegisterOptions,
} from '@alilc/lowcode-types';
export type PluginPreference = Map<string, Record<string, IPublicTypePreferenceValueType>>;
@ -72,7 +72,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;

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -1,4 +1,5 @@
import { Component } from 'react';
import ReactDOM from 'react-dom';
import { TipItem } from './tip-item';
import { tipHandler } from './tip-handler';
@ -25,11 +26,13 @@ export class TipContainer extends Component {
}
render() {
return window.ReactDOM.createPortal(
ReactDOM.createPortal(
<div className="lc-tips-container">
<TipItem />
</div>,
document.querySelector('body')!,
);
return null;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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[];

View File

@ -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>;

View File

@ -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>;

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -1,3 +1,4 @@
import { MouseEvent } from 'react';
import { IPublicTypePropType, IPublicTypeComponentAction } from './';
import { IPublicModelNode, IPublicModelProp, IPublicModelSettingField } from '../model';

View File

@ -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[];
}

View File

@ -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';
}

View File

@ -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;
}

View File

@ -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;
}
}
});

View File

@ -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);

View File

@ -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;
};
}

View File

@ -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) => {

View File

@ -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;

View File

@ -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';

View File

@ -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) {
}

View File

@ -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,13 @@ 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(), this.options);
this.init();
if (this.resourceTypeInstance.editorViews) {
this.resourceTypeInstance.editorViews.forEach((d: any) => {

View File

@ -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;

View File

@ -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);
};
}
}