diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 391816d0d..8676972d0 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -59,6 +59,7 @@ export class DocumentModel { } private _modalNode?: NodeParent; + private _blank?: boolean; get modalNode() { return this._modalNode; } @@ -67,7 +68,7 @@ export class DocumentModel { return this.modalNode || this.rootNode; } - constructor(readonly project: Project, schema: RootSchema) { + constructor(readonly project: Project, schema?: RootSchema) { autorun(() => { this.nodes.forEach((item) => { if (item.parent == null && item !== this.rootNode) { @@ -75,7 +76,16 @@ export class DocumentModel { } }); }, true); - this.rootNode = this.createRootNode(schema); + + if (!schema) { + this._blank = true; + } + + this.rootNode = this.createRootNode(schema || { + componentName: 'Page', + fileName: '' + }); + this.history = new History( () => this.schema, (schema) => this.import(schema as RootSchema, true), @@ -83,6 +93,10 @@ export class DocumentModel { this.setupListenActiveNodes(); } + @computed isBlank() { + return this._blank && !this.isModified(); + } + readonly designer = this.project.designer; /** @@ -295,6 +309,7 @@ export class DocumentModel { } private mountSimulator(simulator: ISimulatorHost) { + // TODO: 多设备 simulator 支持 this._simulator = simulator; // TODO: emit simulator mounted } @@ -386,7 +401,8 @@ export class DocumentModel { * 从项目中移除 */ remove() { - // todo: + // this.project.removeDocument(this); + // todo: ... } purge() { diff --git a/packages/designer/src/locale/en-US.json b/packages/designer/src/locale/en-US.json index 9f5c5f234..69eb61330 100644 --- a/packages/designer/src/locale/en-US.json +++ b/packages/designer/src/locale/en-US.json @@ -1,5 +1,6 @@ { "copy": "Copy", "remove": "Remove", - "Condition Group": "Condition Group" + "Condition Group": "Condition Group", + "No opened document": "No opened document, open some document to editing" } diff --git a/packages/designer/src/locale/zh-CN.json b/packages/designer/src/locale/zh-CN.json index 39042c3af..cafba4f51 100644 --- a/packages/designer/src/locale/zh-CN.json +++ b/packages/designer/src/locale/zh-CN.json @@ -1,5 +1,6 @@ { "copy": "复制", "remove": "删除", - "Condition Group": "条件组" + "Condition Group": "条件组", + "No opened document": "没有打开的页面,请选择页面打开编辑" } diff --git a/packages/designer/src/project/project-view.tsx b/packages/designer/src/project/project-view.tsx index e1d23a00b..cfec45792 100644 --- a/packages/designer/src/project/project-view.tsx +++ b/packages/designer/src/project/project-view.tsx @@ -2,6 +2,7 @@ import { Component } from 'react'; import { observer } from '@ali/lowcode-globals'; import { Designer } from '../designer'; import { DocumentView } from '../document'; +import { intl } from '../locale'; import './project.less'; @observer @@ -9,14 +10,14 @@ export class ProjectView extends Component<{ designer: Designer }> { render() { const { designer } = this.props; // TODO: support splitview + const opens = designer.project.documents.filter((doc) => doc.opened); return (
- {designer.project.documents.map(doc => { - if (!doc.opened) { - return null; - } - return ; - })} + {opens.length > 0 ? ( + opens.map((doc) => ) + ) : ( +
{intl('No opened document')}
+ )}
); } diff --git a/packages/designer/src/project/project.less b/packages/designer/src/project/project.less index 673431498..fcfba65c8 100644 --- a/packages/designer/src/project/project.less +++ b/packages/designer/src/project/project.less @@ -4,6 +4,14 @@ right: 0; width: 100%; height: 100%; + .lc-project-empty { + width: 100%; + height: 100%; + font-size: 16px; + text-align: center; + background: transparent url(//img.alicdn.com/tfs/TB1xLKQAbj1gK0jSZFuXXcrHpXa-90-90.png) center 30% no-repeat; + padding-top: 50%; + } .lc-document { width: 100%; height: 100%; diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 795358ab7..25ce16956 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -14,11 +14,11 @@ export class Project { // TODO: 考虑项目级别 History constructor(readonly designer: Designer, schema?: ProjectSchema) { - this.setSchema(schema); + this.load(schema); } @computed get currentDocument() { - return this.documents.find(doc => doc.actived); + return this.documents.find((doc) => doc.actived); } /** @@ -27,30 +27,45 @@ export class Project { getSchema(): ProjectSchema { return { ...this.data, - componentsTree: this.documents.map(doc => doc.schema), + // todo: future change this filter + componentsTree: this.documents.filter((doc) => !doc.isBlank()).map((doc) => doc.schema), }; } /** * 整体设置项目 schema + * + * @param autoOpen true 自动打开文档 string 指定打开的文件 */ - setSchema(schema?: ProjectSchema) { + load(schema?: ProjectSchema, autoOpen?: boolean | string) { + this.unload(); + // load new document this.data = { version: '1.0.0', componentsMap: [], componentsTree: [], ...schema, }; - if (this.documents.length > 0) { - this.documents.forEach(doc => doc.purge()); - this.documents.length = 0; + + if (autoOpen) { + if (autoOpen === true) { + // auto open first document or open a blank page + this.open(this.data.componentsTree[0]); + } else { + // auto open should be string of fileName + this.open(autoOpen); + } } - this.open( - this.data.componentsTree[0] || { - componentName: 'Page', - fileName: '', - }, - ); + } + + /** + * 卸载当前项目数据 + */ + unload() { + if (this.documents.length < 1) { + return; + } + this.documents.forEach((doc) => doc.remove()); } /** @@ -86,14 +101,23 @@ export class Project { | string, ): any {} - open(doc: string | DocumentModel | RootSchema): void { + open(doc?: string | DocumentModel | RootSchema): void { + if (!doc) { + const got = this.documents.find((item) => item.isBlank()); + if (got) { + return got.open(); + } + doc = new DocumentModel(this); + this.documents.push(doc); + return doc.open(); + } if (typeof doc === 'string') { - const got = this.documents.find(item => item.fileName === doc); + const got = this.documents.find((item) => item.fileName === doc); if (got) { return got.open(); } - const data = this.data.componentsTree.find(data => data.fileName === doc); + const data = this.data.componentsTree.find((data) => data.fileName === doc); if (data) { doc = new DocumentModel(this, data); this.documents.push(doc); @@ -113,7 +137,7 @@ export class Project { } checkExclusive(actived: DocumentModel) { - this.documents.forEach(doc => { + this.documents.forEach((doc) => { if (doc !== actived) { doc.suspense(); } @@ -122,7 +146,7 @@ export class Project { } closeOthers(opened: DocumentModel) { - this.documents.forEach(doc => { + this.documents.forEach((doc) => { if (doc !== opened) { doc.close(); } diff --git a/packages/plugin-designer/src/index.tsx b/packages/plugin-designer/src/index.tsx index 825522aae..222ef7a91 100644 --- a/packages/plugin-designer/src/index.tsx +++ b/packages/plugin-designer/src/index.tsx @@ -214,7 +214,7 @@ export default class DesignerPlugin extends PureComponent