feat: workspace mode supports webview type views

This commit is contained in:
liujuping 2022-12-27 18:24:10 +08:00 committed by 林熠
parent 1342481942
commit 1f8d91f85f
17 changed files with 119 additions and 26 deletions

View File

@ -16,8 +16,10 @@ sidebar_position: 12
### importSchema(schema: IPublicTypeNodeSchema)
当前窗口导入 schema
相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### changeViewType(viewName: string)
修改当前窗口视图类型
### async save
### async save()
调用当前窗口视图保存钩子

View File

@ -32,3 +32,5 @@ sidebar_position: 12
/** 注册资源 */
registerResourceType(resourceName: string, resourceType: 'editor', options: IPublicResourceOptions): void;
```
相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts)

View File

@ -7,6 +7,9 @@ import { Area } from '../area';
export default class LeftArea extends Component<{ area: Area }> {
render() {
const { area } = this.props;
if (area.isEmpty()) {
return null;
}
return (
<div className={classNames('lc-left-area', {
'lc-area-visible': area.visible,

View File

@ -8,6 +8,9 @@ import { Panel } from '../widget/panel';
export default class RightArea extends Component<{ area: Area<any, Panel> }> {
render() {
const { area } = this.props;
if (area.isEmpty()) {
return null;
}
return (
<div className={classNames('lc-right-area engine-tabpane', {
'lc-area-visible': area.visible,

View File

@ -7,6 +7,9 @@ import { Area } from '../area';
export default class TopArea extends Component<{ area: Area; itemClassName?: string }> {
render() {
const { area, itemClassName } = this.props;
if (area.isEmpty()) {
return null;
}
return (
<div className={classNames('lc-top-area engine-actionpane', {
'lc-area-visible': area.visible,

View File

@ -154,6 +154,7 @@ body {
&.active {
z-index: 999;
background: #edeff3;
}
}
}

View File

@ -15,19 +15,25 @@ import { SkeletonContext } from '../context';
import { EditorConfig, PluginClassSet } from '@alilc/lowcode-types';
@observer
export class Workbench extends Component<{ skeleton: Skeleton; config?: EditorConfig; components?: PluginClassSet; className?: string; topAreaItemClassName?: string }> {
export class Workbench extends Component<{
skeleton: Skeleton;
config?: EditorConfig;
components?: PluginClassSet;
className?: string;
topAreaItemClassName?: string;
}> {
constructor(props: any) {
super(props);
const { config, components, skeleton } = this.props;
skeleton.buildFromConfig(config, components);
}
// componentDidCatch(error: any) {
// globalContext.get(Editor).emit('editor.skeleton.workbench.error', error);
// }
render() {
const { skeleton, className, topAreaItemClassName } = this.props;
const {
skeleton,
className,
topAreaItemClassName,
} = this.props;
return (
<div className={classNames('lc-workbench', className)}>
<SkeletonContext.Provider value={this.props.skeleton}>

View File

@ -66,7 +66,7 @@ async function registryInnerPlugin(designer: Designer, editor: Editor, plugins:
await plugins.register(OutlinePlugin, {}, { autoInit: true });
await plugins.register(componentMetaParser(designer));
await plugins.register(setterRegistry, {}, { autoInit: true });
await plugins.register(defaultPanelRegistry(editor, designer));
await plugins.register(defaultPanelRegistry(editor));
await plugins.register(builtinHotkey);
}

View File

@ -3,7 +3,7 @@ import { SettingsPrimaryPane } from '@alilc/lowcode-editor-skeleton';
import DesignerPlugin from '@alilc/lowcode-plugin-designer';
// 注册默认的面板
export const defaultPanelRegistry = (editor: any, designer: any) => {
export const defaultPanelRegistry = (editor: any) => {
const fun = (ctx: IPublicModelPluginContext) => {
return {
init() {

View File

@ -8,7 +8,5 @@ export interface IPublicModelWindow {
changeViewType(viewName: string): void;
/** 调用当前窗口视图保存钩子 */
save(): Promise<{
[viewName: string]: IPublicTypeNodeSchema | any;
}>;
save(): Promise<any>;
}

View File

@ -8,6 +8,8 @@ export interface IPublicViewFunctions {
export interface IPublicEditorView {
/** 资源名字 */
viewName: string;
/** 资源类型 */
viewType?: 'editor' | 'webview';
(ctx: any): IPublicViewFunctions;
}
@ -25,8 +27,12 @@ export interface IPublicResourceOptions {
editorViews: IPublicEditorView[];
/** save 钩子 */
save?: () => Promise<void>;
save?: (schema: {
[viewName: string]: any;
}) => Promise<void>;
/** import 钩子 */
import?: () => Promise<void>;
import?: (schema: any) => Promise<{
[viewName: string]: any;
}>;
}

View File

@ -35,6 +35,7 @@ import {
import { getLogger } from '@alilc/lowcode-utils';
import { Workspace as InnerWorkspace } from './index';
import { EditorWindow } from './editor-window/context';
export class BasicContext {
skeleton: Skeleton;
plugins: Plugins;

View File

@ -1,16 +1,22 @@
import { makeObservable, obx } from '@alilc/lowcode-editor-core';
import { EditorViewOptions, EditorWindow, ViewFunctions } from '@alilc/lowcode-workspace';
import { IPublicEditorView, IPublicViewFunctions } from '@alilc/lowcode-types';
import { flow } from 'mobx';
import { Workspace as InnerWorkspace } from '../';
import { BasicContext } from '../base-context';
import { EditorWindow } from '../editor-window/context';
import { getWebviewPlugin } from '../inner-plugins/webview';
export class Context extends BasicContext {
name = 'editor-view';
viewName = 'editor-view';
instance: ViewFunctions;
instance: IPublicViewFunctions;
constructor(public workspace: any, public editorWindow: EditorWindow, public editorView: EditorViewOptions) {
viewType: 'editor' | 'webview';
constructor(public workspace: InnerWorkspace, public editorWindow: EditorWindow, public editorView: IPublicEditorView) {
super(workspace, editorView.viewName, editorWindow);
this.name = editorView.viewName;
this.viewType = editorView.viewType || 'editor';
this.viewName = editorView.viewName;
this.instance = editorView(this.innerPlugins._getLowCodePluginContext({
pluginName: 'any',
}));
@ -31,8 +37,13 @@ export class Context extends BasicContext {
@obx isInit: boolean = false;
init = flow(function* (this: any) {
if (this.viewType === 'webview') {
const url = yield this.instance?.url?.();
yield this.plugins.register(getWebviewPlugin(url, this.viewName));
} else {
yield this.registerInnerPlugins();
yield this.instance?.init();
}
yield this.instance?.init?.();
yield this.innerPlugins.init();
this.isInit = true;
});

View File

@ -3,11 +3,15 @@ import {
Workbench,
} from '@alilc/lowcode-editor-skeleton';
import { Component } from 'react';
import { Context } from './context';
export * from '../base-context';
@observer
export class EditorView extends Component<any, any> {
export class EditorView extends Component<{
editorView: Context;
active: boolean;
}, any> {
render() {
const { active } = this.props;
const editorView = this.props.editorView;

View File

@ -12,6 +12,10 @@ export class EditorWindow {
async importSchema(schema: any) {
const newSchema = await this.resource.import(schema);
if (!newSchema) {
return;
}
Object.keys(newSchema).forEach(key => {
const view = this.editorViews.get(key);
view?.project.importSchema(newSchema[key]);

View File

@ -0,0 +1,49 @@
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
function DesignerView(props: {
url: string;
viewName: string;
}) {
return (
<div className="lc-designer lowcode-plugin-designer">
<div className="lc-project">
<div className="lc-simulator-shell">
<iframe
name={`webview-view-${props.viewName}`}
className="lc-simulator-content-frame"
style={{
height: '100%',
width: '100%',
}}
src={props.url}
/>
</div>
</div>
</div>
);
}
export function getWebviewPlugin(url: string, viewName: string) {
function webviewPlugin(ctx: IPublicModelPluginContext) {
const { skeleton } = ctx;
return {
init() {
skeleton.add({
area: 'mainArea',
name: 'designer',
type: 'Widget',
content: DesignerView,
contentProps: {
ctx,
url,
viewName,
},
});
},
};
}
webviewPlugin.pluginName = '___webview_plugin___';
return webviewPlugin;
}

View File

@ -1,7 +1,7 @@
import { EditorViewOptions, ResourceOptions } from '.';
import { IPublicEditorView, IPublicResourceOptions } from '@alilc/lowcode-types';
export class Resource {
constructor(options: ResourceOptions) {
constructor(options: IPublicResourceOptions) {
if (options.editorViews) {
options.editorViews.forEach((d: any) => {
this.editorViewMap.set(d.viewName, d);
@ -11,9 +11,9 @@ export class Resource {
this.options = options;
}
options: ResourceOptions;
options: IPublicResourceOptions;
editorViewMap: Map<string, EditorViewOptions> = new Map<string, EditorViewOptions>();
editorViewMap: Map<string, IPublicEditorView> = new Map<string, IPublicEditorView>();
init(ctx: any) {
this.options.init(ctx);