feat(workspace): add enableAutoOpenFirstWindow config and onWindowRendererReady function

This commit is contained in:
liujuping 2023-04-19 15:27:34 +08:00 committed by 林熠
parent dff06e70ac
commit 9b50bc700e
12 changed files with 101 additions and 23 deletions

View File

@ -145,6 +145,11 @@ const VALID_ENGINE_OPTIONS = {
type: 'function',
description: '配置指定节点为根组件',
},
enableAutoOpenFirstWindow: {
type: 'boolean',
description: '应用级设计模式下,自动打开第一个窗口',
default: true,
},
};
const getStrictModeValue = (engineOptions: IPublicTypeEngineOptions, defaultValue: boolean): boolean => {

View File

@ -9,12 +9,15 @@ import {
engineConfig,
Setters as InnerSetters,
Hotkey as InnerHotkey,
IEditor,
} from '@alilc/lowcode-editor-core';
import {
IPublicTypeEngineOptions,
IPublicModelDocumentModel,
IPublicTypePluginMeta,
IPublicTypeDisposable,
IPublicApiPlugins,
IPublicApiWorkspace,
} from '@alilc/lowcode-types';
import {
Designer,
@ -22,6 +25,7 @@ import {
ILowCodePluginContextPrivate,
ILowCodePluginContextApiAssembler,
PluginPreference,
IDesigner,
} from '@alilc/lowcode-designer';
import {
Skeleton as InnerSkeleton,
@ -30,6 +34,7 @@ import {
import {
Workspace as InnerWorkspace,
Workbench as WorkSpaceWorkbench,
IWorkspace,
} from '@alilc/lowcode-workspace';
import {
@ -61,7 +66,7 @@ export * from './modules/skeleton-types';
export * from './modules/designer-types';
export * from './modules/lowcode-types';
async function registryInnerPlugin(designer: Designer, editor: Editor, plugins: Plugins): Promise<IPublicTypeDisposable> {
async function registryInnerPlugin(designer: IDesigner, editor: IEditor, plugins: IPublicApiPlugins): Promise<IPublicTypeDisposable> {
// 注册一批内置插件
const componentMetaParserPlugin = componentMetaParser(designer);
const defaultPanelRegistryPlugin = defaultPanelRegistry(editor);
@ -83,8 +88,8 @@ async function registryInnerPlugin(designer: Designer, editor: Editor, plugins:
};
}
const innerWorkspace = new InnerWorkspace(registryInnerPlugin, shellModelFactory);
const workspace = new Workspace(innerWorkspace);
const innerWorkspace: IWorkspace = new InnerWorkspace(registryInnerPlugin, shellModelFactory);
const workspace: IPublicApiWorkspace = new Workspace(innerWorkspace);
const editor = new Editor();
globalContext.register(editor, Editor);
globalContext.register(editor, 'editor');
@ -207,7 +212,9 @@ export async function init(
}),
engineContainer,
);
innerWorkspace.enableAutoOpenFirstWindow = engineConfig.get('enableAutoOpenFirstWindow', true);
innerWorkspace.setActive(true);
innerWorkspace.initWindow();
innerHotkey.activate(false);
await innerWorkspace.plugins.init(pluginPreference);
return;

View File

@ -32,7 +32,7 @@ export class Project implements IPublicApiProject {
}
const workspace = globalContext.get('workspace');
if (workspace.isActive) {
if (!workspace.window.innerProject) {
if (!workspace.window?.innerProject) {
logger.error('project api 调用时机出现问题,请检查');
return this[innerProjectSymbol];
}

View File

@ -5,9 +5,12 @@ import {
} from '@alilc/lowcode-editor-skeleton';
import { skeletonSymbol } from '../symbols';
import { IPublicApiSkeleton, IPublicTypeDisposable, IPublicTypeSkeletonConfig, IPublicTypeWidgetConfigArea } from '@alilc/lowcode-types';
import { getLogger } from '@alilc/lowcode-utils';
const innerSkeletonSymbol = Symbol('skeleton');
const logger = getLogger({ level: 'warn', bizName: 'shell-skeleton' });
export class Skeleton implements IPublicApiSkeleton {
private readonly [innerSkeletonSymbol]: ISkeleton;
private readonly pluginName: string;
@ -18,6 +21,10 @@ export class Skeleton implements IPublicApiSkeleton {
}
const workspace = globalContext.get('workspace');
if (workspace.isActive) {
if (!workspace.window.innerSkeleton) {
logger.error('skeleton api 调用时机出现问题,请检查');
return this[innerSkeletonSymbol];
}
return workspace.window.innerSkeleton;
}

View File

@ -28,9 +28,16 @@ export class Workspace implements IPublicApiWorkspace {
}
get window() {
if (!this[workspaceSymbol].window) {
return null;
}
return new ShellWindow(this[workspaceSymbol].window);
}
onWindowRendererReady(fn: () => void): IPublicTypeDisposable {
return this[workspaceSymbol].onWindowRendererReady(fn);
}
registerResourceType(resourceTypeModel: IPublicTypeResourceType): void {
this[workspaceSymbol].registerResourceType(resourceTypeModel);
}

View File

@ -41,4 +41,8 @@ export class Window implements IPublicModelWindow {
async save() {
return await this[windowSymbol].save();
}
get plugins() {
return this[windowSymbol].plugins;
}
}

View File

@ -10,7 +10,7 @@ export interface IPublicApiWorkspace<
isActive: boolean;
/** 当前设计器窗口 */
window: ModelWindow;
window: ModelWindow | null;
plugins: Plugins;
@ -46,4 +46,10 @@ export interface IPublicApiWorkspace<
/** active 窗口变更事件 */
onChangeActiveWindow(fn: () => void): IPublicTypeDisposable;
/**
* window renderer ready
* @since v1.1.7
*/
onWindowRendererReady(fn: () => void): IPublicTypeDisposable;
}

View File

@ -2,6 +2,7 @@ import { RequestHandlersMap } from '@alilc/lowcode-datasource-types';
import { ComponentType } from 'react';
export interface IPublicTypeEngineOptions {
/**
* condition condition
* when this is true, node that configured as conditional not renderring
@ -136,8 +137,10 @@ export interface IPublicTypeEngineOptions {
* react-renderer appHelper https://lowcode-engine.cn/site/docs/guide/expand/runtime/renderer#apphelper
*/
appHelper?: {
/** 全局公共函数 */
utils?: Record<string, any>;
/** 全局常量 */
constants?: Record<string, any>;
};
@ -168,6 +171,12 @@ export interface IPublicTypeEngineOptions {
*
*/
enableWorkspaceMode?: boolean;
/**
* @default true
*
*/
enableAutoOpenFirstWindow?: boolean;
}
/**

View File

@ -17,10 +17,6 @@ export class Context extends BasicContext {
@obx isInit: boolean = false;
@computed get active() {
return this._activate;
}
init = flow(function* (this: Context) {
if (this.viewType === 'webview') {
const url = yield this.instance?.url?.();
@ -43,6 +39,18 @@ export class Context extends BasicContext {
makeObservable(this);
}
@computed get active() {
return this._activate;
}
onSimulatorRendererReady = (): Promise<void> => {
return new Promise((resolve) => {
this.project.onSimulatorRendererReady(() => {
resolve();
});
});
};
setActivate = (_activate: boolean) => {
this._activate = _activate;
this.innerHotkey.activate(this._activate);

View File

@ -47,7 +47,7 @@ export class Workbench extends Component<{
{
workspace.windows.map(d => (
<WindowView
active={d.id === workspace.window.id}
active={d.id === workspace.window?.id}
window={d}
key={d.id}
/>

View File

@ -82,6 +82,9 @@ export class EditorWindow implements IEditorWindow {
async init() {
await this.initViewTypes();
await this.execViewTypesInit();
Promise.all(Array.from(this.editorViews.values()).map((d) => d.onSimulatorRendererReady)).then(() => {
this.workspace.emitWindowRendererReady();
});
this.url = await this.resource.url();
this.setDefaultViewType();
this.initReady = true;
@ -182,6 +185,10 @@ export class EditorWindow implements IEditorWindow {
return this.editorView?.designer;
}
get plugins() {
return this.editorView?.plugins;
}
get innerPlugins() {
return this.editorView?.innerPlugins;
}

View File

@ -1,6 +1,6 @@
import { IDesigner, ILowCodePluginManager, LowCodePluginManager } from '@alilc/lowcode-designer';
import { createModuleEventBus, Editor, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core';
import { IPublicApiPlugins, IPublicApiWorkspace, IPublicResourceList, IPublicTypeResourceType, IShellModelFactory } from '@alilc/lowcode-types';
import { createModuleEventBus, Editor, IEditor, IEventBus, makeObservable, obx } from '@alilc/lowcode-editor-core';
import { IPublicApiPlugins, IPublicApiWorkspace, IPublicResourceList, IPublicTypeDisposable, IPublicTypeResourceType, IShellModelFactory } from '@alilc/lowcode-types';
import { BasicContext } from './context/base-context';
import { EditorWindow } from './window';
import type { IEditorWindow } from './window';
@ -11,6 +11,8 @@ enum EVENT {
CHANGE_WINDOW = 'change_window',
CHANGE_ACTIVE_WINDOW = 'change_active_window',
WINDOW_RENDER_READY = 'window_render_ready',
}
const CHANGE_EVENT = 'resource.list.change';
@ -19,10 +21,12 @@ export interface IWorkspace extends Omit<IPublicApiWorkspace<
LowCodePluginManager,
IEditorWindow
>, 'resourceList' | 'plugins'> {
readonly registryInnerPlugin: (designer: IDesigner, editor: Editor, plugins: IPublicApiPlugins) => Promise<void>;
readonly registryInnerPlugin: (designer: IDesigner, editor: Editor, plugins: IPublicApiPlugins) => Promise<IPublicTypeDisposable>;
readonly shellModelFactory: IShellModelFactory;
enableAutoOpenFirstWindow: boolean;
window: IEditorWindow;
plugins: ILowCodePluginManager;
@ -32,11 +36,19 @@ export interface IWorkspace extends Omit<IPublicApiWorkspace<
getResourceType(resourceName: string): IResourceType;
checkWindowQueue(): void;
emitWindowRendererReady(): void;
initWindow(): void;
setActive(active: boolean): void;
}
export class Workspace implements IWorkspace {
context: BasicContext;
enableAutoOpenFirstWindow: boolean;
private emitter: IEventBus = createModuleEventBus('workspace');
private _isActive = false;
@ -79,10 +91,10 @@ export class Workspace implements IWorkspace {
}[] = [];
constructor(
readonly registryInnerPlugin: (designer: IDesigner, editor: Editor, plugins: IPublicApiPlugins) => Promise<void>,
readonly registryInnerPlugin: (designer: IDesigner, editor: IEditor, plugins: IPublicApiPlugins) => Promise<IPublicTypeDisposable>,
readonly shellModelFactory: any,
) {
this.init();
this.context = new BasicContext(this, '');
makeObservable(this);
}
@ -97,13 +109,8 @@ export class Workspace implements IWorkspace {
}
}
init() {
this.initWindow();
this.context = new BasicContext(this, '');
}
initWindow() {
if (!this.defaultResourceType) {
if (!this.defaultResourceType || this.enableAutoOpenFirstWindow === false) {
return;
}
const resourceName = this.defaultResourceType.name;
@ -128,7 +135,7 @@ export class Workspace implements IWorkspace {
const resourceType = new ResourceType(resourceTypeModel);
this.resourceTypeMap.set(resourceTypeModel.resourceName, resourceType);
if (!this.window && this.defaultResourceType) {
if (!this.window && this.defaultResourceType && this._isActive) {
this.initWindow();
}
}
@ -149,6 +156,17 @@ export class Workspace implements IWorkspace {
};
}
onWindowRendererReady(fn: () => void): IPublicTypeDisposable {
this.emitter.on(EVENT.WINDOW_RENDER_READY, fn);
return () => {
this.emitter.off(EVENT.WINDOW_RENDER_READY, fn);
};
}
emitWindowRendererReady() {
this.emitter.emit(EVENT.WINDOW_RENDER_READY);
}
getResourceType(resourceName: string): IResourceType {
return this.resourceTypeMap.get(resourceName)!;
}
@ -188,7 +206,7 @@ export class Workspace implements IWorkspace {
}
openEditorWindow(name: string, title: string, options: Object, viewType?: string, sleep?: boolean) {
if (!this.window?.initReady && !sleep) {
if (this.window && !this.window?.initReady && !sleep) {
this.windowQueue.push({
name, title, options, viewType,
});