mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-12 17:08:14 +00:00
Merge commit 'f8584e101afb89b672fca8ea6a1836db7626c67e' into def_releases_2021091314071919_ali-lowcode_ali-lowcode-engine/1.0.67
This commit is contained in:
commit
6aea8224d7
@ -6,7 +6,7 @@ module.exports = {
|
||||
// // '^.+\\.(ts|tsx)$': 'ts-jest',
|
||||
// // '^.+\\.(js|jsx)$': 'babel-jest',
|
||||
// },
|
||||
// testMatch: ['**/node.test.ts'],
|
||||
// testMatch: ['**/prop.test.ts'],
|
||||
// testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
|
||||
transformIgnorePatterns: [
|
||||
`/node_modules/(?!${esModules})/`,
|
||||
|
||||
@ -46,10 +46,6 @@ export class BorderDetectingInstance extends PureComponent<{
|
||||
|
||||
@observer
|
||||
export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@computed get scale() {
|
||||
return this.props.host.viewport.scale;
|
||||
}
|
||||
|
||||
@ -28,10 +28,6 @@ export default class BoxResizing extends Component<{ host: BuiltinSimulatorHost
|
||||
return this.dragging ? selection.getTopNodes() : selection.getNodes();
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// this.hoveringCapture.setBoundary(this.outline);
|
||||
// this.willBind();
|
||||
@ -73,10 +69,6 @@ export class BoxResizingForNode extends Component<{ host: BuiltinSimulatorHost;
|
||||
return this.host.getComponentInstances(this.props.node);
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { instances } = this;
|
||||
const { node } = this.props;
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
ComponentType,
|
||||
} from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { observer, computed, Tip, globalContext, Editor } from '@ali/lowcode-editor-core';
|
||||
import { observer, computed, Tip, globalContext, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { createIcon, isReactComponent } from '@ali/lowcode-utils';
|
||||
import { ActionContentObject, isActionContentObject } from '@ali/lowcode-types';
|
||||
import { BuiltinSimulatorHost } from '../host';
|
||||
@ -62,10 +62,6 @@ export class BorderSelectingInstance extends Component<{
|
||||
|
||||
@observer
|
||||
class Toolbar extends Component<{ observed: OffsetObserver }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { observed } = this.props;
|
||||
const { height, width } = observed.viewport;
|
||||
@ -169,10 +165,6 @@ export class BorderSelectingForNode extends Component<{ host: BuiltinSimulatorHo
|
||||
return this.host.getComponentInstances(this.props.node);
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { instances } = this;
|
||||
const { node } = this.props;
|
||||
@ -217,10 +209,6 @@ export class BorderSelecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
return this.dragging ? selection.getTopNodes() : selection.getNodes();
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selecting } = this;
|
||||
if (!selecting || selecting.length < 1) {
|
||||
|
||||
@ -11,10 +11,6 @@ import './borders.less';
|
||||
|
||||
@observer
|
||||
export class BemTools extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { host } = this.props;
|
||||
const { designMode } = host;
|
||||
|
||||
@ -116,10 +116,6 @@ function processDetail({ target, detail, document }: DropLocation): InsertionDat
|
||||
|
||||
@observer
|
||||
export class InsertionView extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { host } = this.props;
|
||||
const loc = host.currentDocument?.dropLocation;
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
import {
|
||||
obx,
|
||||
autorun,
|
||||
reaction,
|
||||
computed,
|
||||
getPublicPath,
|
||||
hotkey,
|
||||
focusTracker,
|
||||
engineConfig,
|
||||
IReactionPublic,
|
||||
IReactionOptions,
|
||||
IReactionDisposer,
|
||||
makeObservable,
|
||||
} from '@ali/lowcode-editor-core';
|
||||
import { EventEmitter } from 'events';
|
||||
import {
|
||||
@ -164,16 +169,27 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
|
||||
readonly emitter: EventEmitter = new EventEmitter();
|
||||
|
||||
readonly componentsConsumer: ResourceConsumer;
|
||||
|
||||
readonly injectionConsumer: ResourceConsumer;
|
||||
|
||||
/**
|
||||
* 是否为画布自动渲染
|
||||
*/
|
||||
autoRender = true;
|
||||
|
||||
constructor(project: Project) {
|
||||
makeObservable(this);
|
||||
this.project = project;
|
||||
this.designer = project?.designer;
|
||||
this.scroller = this.designer.createScroller(this.viewport);
|
||||
this.autoRender = !engineConfig.get('disableAutoRender', false);
|
||||
this.componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
|
||||
this.injectionConsumer = new ResourceConsumer(() => {
|
||||
return {
|
||||
i18n: this.project.i18n,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
get currentDocument() {
|
||||
@ -256,22 +272,25 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
*/
|
||||
connect(
|
||||
renderer: BuiltinSimulatorRenderer,
|
||||
fn: (context: { dispose: () => void; firstRun: boolean }) => void,
|
||||
effect: (reaction: IReactionPublic) => void, options?: IReactionOptions,
|
||||
) {
|
||||
this._renderer = renderer;
|
||||
return autorun(fn as any, true);
|
||||
return autorun(effect, options);
|
||||
}
|
||||
|
||||
autorun(fn: (context: { dispose: () => void; firstRun: boolean }) => void) {
|
||||
return autorun(fn as any, true);
|
||||
reaction(expression: (reaction: IReactionPublic) => unknown, effect: (value: unknown, prev: unknown, reaction: IReactionPublic) => void,
|
||||
opts?: IReactionOptions | undefined): IReactionDisposer {
|
||||
return reaction(expression, effect, opts);
|
||||
}
|
||||
|
||||
autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions): IReactionDisposer {
|
||||
return autorun(effect, options);
|
||||
}
|
||||
|
||||
purge(): void {
|
||||
// todo
|
||||
}
|
||||
|
||||
readonly viewport = new Viewport();
|
||||
|
||||
mountViewport(viewport: Element | null) {
|
||||
this.viewport.mount(viewport);
|
||||
}
|
||||
@ -294,14 +313,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
return this._renderer;
|
||||
}
|
||||
|
||||
readonly componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
|
||||
|
||||
readonly injectionConsumer = new ResourceConsumer(() => {
|
||||
return {
|
||||
i18n: this.project.i18n,
|
||||
};
|
||||
});
|
||||
|
||||
readonly asyncLibraryMap: { [key: string]: {} } = {};
|
||||
|
||||
readonly libraryMap: { [key: string]: string } = {};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { Point, ScrollTarget } from '../designer';
|
||||
import { AutoFit, IViewport } from '../simulator';
|
||||
|
||||
@ -25,6 +25,10 @@ export default class Viewport implements IViewport {
|
||||
|
||||
private viewportElement?: HTMLElement;
|
||||
|
||||
constructor() {
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
mount(viewportElement: HTMLElement | null) {
|
||||
if (!viewportElement || this.viewportElement === viewportElement) {
|
||||
return;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ComponentType } from 'react';
|
||||
import { obx, computed, autorun } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, autorun, makeObservable, IReactionPublic, IReactionOptions, IReactionDisposer } from '@ali/lowcode-editor-core';
|
||||
import {
|
||||
ProjectSchema,
|
||||
ComponentMetadata,
|
||||
@ -71,6 +71,7 @@ export class Designer {
|
||||
}
|
||||
|
||||
constructor(props: DesignerProps) {
|
||||
makeObservable(this);
|
||||
const { editor } = props;
|
||||
this.editor = editor;
|
||||
this.setProps(props);
|
||||
@ -563,12 +564,12 @@ export class Designer {
|
||||
}
|
||||
}
|
||||
|
||||
autorun(action: (context: { firstRun: boolean }) => void, sync = false): () => void {
|
||||
return autorun(action, sync as true);
|
||||
autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions): IReactionDisposer {
|
||||
return autorun(effect, options);
|
||||
}
|
||||
|
||||
purge() {
|
||||
// todo:
|
||||
// TODO:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx } from '@ali/lowcode-editor-core';
|
||||
import { makeObservable, obx } from '@ali/lowcode-editor-core';
|
||||
import { Node, DocumentModel } from '../document';
|
||||
|
||||
export class Detecting {
|
||||
@ -19,6 +19,10 @@ export class Detecting {
|
||||
|
||||
@obx.ref private _current: Node | null = null;
|
||||
|
||||
constructor() {
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get current() {
|
||||
return this._current;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Component } from 'react';
|
||||
import { observer, obx, Title } from '@ali/lowcode-editor-core';
|
||||
import { observer, obx, Title, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { Designer } from '../designer';
|
||||
import { DragObject, isDragNodeObject, isDragNodeDataObject } from '../dragon';
|
||||
import { isSimulatorHost } from '../../simulator';
|
||||
@ -23,6 +23,7 @@ export default class DragGhost extends Component<{ designer: Designer }> {
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
this.dispose = [
|
||||
this.dragon.onDragstart(e => {
|
||||
if (e.originalEvent.type.substr(0, 4) === 'drag') {
|
||||
@ -52,10 +53,6 @@ export default class DragGhost extends Component<{ designer: Designer }> {
|
||||
];
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.dispose) {
|
||||
this.dispose.forEach(off => off());
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { obx } from '@ali/lowcode-editor-core';
|
||||
import { obx, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { NodeSchema } from '@ali/lowcode-types';
|
||||
import { setNativeSelection, cursor } from '@ali/lowcode-utils';
|
||||
import { DropLocation } from './location';
|
||||
@ -213,7 +213,9 @@ export class Dragon {
|
||||
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
constructor(readonly designer: Designer) {}
|
||||
constructor(readonly designer: Designer) {
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick listen a shell(container element) drag behavior
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { uniqueId } from '@ali/lowcode-utils';
|
||||
import { INodeSelector, IViewport } from '../simulator';
|
||||
import { isRootNode, Node } from '../document';
|
||||
@ -106,8 +106,9 @@ export class OffsetObserver {
|
||||
const doc = node.document;
|
||||
const host = doc.simulator!;
|
||||
const focusNode = doc.focusNode;
|
||||
this.isRoot = node.contains(focusNode);
|
||||
this.isRoot = node.contains(focusNode!);
|
||||
this.viewport = host.viewport;
|
||||
makeObservable(this);
|
||||
if (this.isRoot) {
|
||||
this.hasOffset = true;
|
||||
return;
|
||||
|
||||
@ -2,7 +2,7 @@ import { TitleContent, isDynamicSetter, SetterType, DynamicSetter, FieldExtraPro
|
||||
import { Transducer } from './utils';
|
||||
import { SettingPropEntry } from './setting-prop-entry';
|
||||
import { SettingEntry } from './setting-entry';
|
||||
import { computed, obx } from '@ali/lowcode-editor-core';
|
||||
import { computed, obx, makeObservable, action } from '@ali/lowcode-editor-core';
|
||||
import { cloneDeep } from '@ali/lowcode-utils';
|
||||
import { ISetValueOptions } from '../../types';
|
||||
|
||||
@ -63,7 +63,7 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
|
||||
|
||||
constructor(parent: SettingEntry, config: FieldConfig, settingFieldCollector?: (name: string | number, field: SettingField) => void) {
|
||||
super(parent, config.name, config.type);
|
||||
|
||||
makeObservable(this);
|
||||
const { title, items, setter, extraProps, ...rest } = config;
|
||||
this.parent = parent;
|
||||
this._config = config;
|
||||
@ -141,6 +141,7 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
|
||||
|
||||
private hotValue: any;
|
||||
|
||||
@action
|
||||
setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: ISetValueOptions) {
|
||||
if (isHotValue) {
|
||||
this.setHotValue(val, extraOptions);
|
||||
@ -162,6 +163,7 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
@action
|
||||
setMiniAppDataSourceValue(data: any, options?: any) {
|
||||
this.hotValue = data;
|
||||
const v = this.transducer.toNative(data);
|
||||
@ -174,6 +176,7 @@ export class SettingField extends SettingPropEntry implements SettingEntry {
|
||||
this.valueChange();
|
||||
}
|
||||
|
||||
@action
|
||||
setHotValue(data: any, options?: ISetValueOptions) {
|
||||
this.hotValue = data;
|
||||
const value = this.transducer.toNative(data);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable, runInAction } from '@ali/lowcode-editor-core';
|
||||
import { IEditor, isJSExpression } from '@ali/lowcode-types';
|
||||
import { uniqueId } from '@ali/lowcode-utils';
|
||||
import { SettingEntry } from './setting-entry';
|
||||
@ -53,6 +53,7 @@ export class SettingPropEntry implements SettingEntry {
|
||||
extraProps: any = {};
|
||||
|
||||
constructor(readonly parent: SettingEntry, name: string | number, type?: 'field' | 'group') {
|
||||
makeObservable(this);
|
||||
if (type == null) {
|
||||
const c = typeof name === 'string' ? name.substr(0, 1) : '';
|
||||
if (c === '#') {
|
||||
@ -120,34 +121,36 @@ export class SettingPropEntry implements SettingEntry {
|
||||
*/
|
||||
/* istanbul ignore next */
|
||||
@computed get valueState(): number {
|
||||
if (this.type !== 'field') {
|
||||
const { getValue } = this.extraProps;
|
||||
return getValue ? (getValue(this, undefined) === undefined ? 0 : 1) : 0;
|
||||
}
|
||||
const propName = this.path.join('.');
|
||||
const first = this.nodes[0].getProp(propName)!;
|
||||
let l = this.nodes.length;
|
||||
let state = 2;
|
||||
while (l-- > 1) {
|
||||
const next = this.nodes[l].getProp(propName, false);
|
||||
const s = first.compare(next);
|
||||
if (s > 1) {
|
||||
return -1;
|
||||
return runInAction(() => {
|
||||
if (this.type !== 'field') {
|
||||
const { getValue } = this.extraProps;
|
||||
return getValue ? (getValue(this, undefined) === undefined ? 0 : 1) : 0;
|
||||
}
|
||||
if (s === 1) {
|
||||
state = 1;
|
||||
const propName = this.path.join('.');
|
||||
const first = this.nodes[0].getProp(propName)!;
|
||||
let l = this.nodes.length;
|
||||
let state = 2;
|
||||
while (--l > 0) {
|
||||
const next = this.nodes[l].getProp(propName, false);
|
||||
const s = first.compare(next);
|
||||
if (s > 1) {
|
||||
return -1;
|
||||
}
|
||||
if (s === 1) {
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state === 2 && first.isUnset()) {
|
||||
return 0;
|
||||
}
|
||||
return state;
|
||||
if (state === 2 && first.isUnset()) {
|
||||
return 0;
|
||||
}
|
||||
return state;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前属性值
|
||||
*/
|
||||
@computed getValue(): any {
|
||||
getValue(): any {
|
||||
let val: any;
|
||||
if (this.type === 'field') {
|
||||
val = this.parent.getPropValue(this.name);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { computed, obx } from '@ali/lowcode-editor-core';
|
||||
import { computed, makeObservable, obx, action } from '@ali/lowcode-editor-core';
|
||||
import { NodeData, isJSExpression, isDOMText, NodeSchema, isNodeSchema, RootSchema, PageSchema } from '@ali/lowcode-types';
|
||||
import { EventEmitter } from 'events';
|
||||
import { Project } from '../project';
|
||||
@ -61,7 +61,7 @@ export class DocumentModel {
|
||||
|
||||
readonly designer: Designer;
|
||||
|
||||
@obx.val private nodes = new Set<Node>();
|
||||
@obx.shallow private nodes = new Set<Node>();
|
||||
|
||||
private seqId = 0;
|
||||
|
||||
@ -117,13 +117,7 @@ export class DocumentModel {
|
||||
private inited = false;
|
||||
|
||||
constructor(project: Project, schema?: RootSchema) {
|
||||
/*
|
||||
// TODO
|
||||
// use special purge process
|
||||
autorun(() => {
|
||||
console.info(this.willPurgeSpace);
|
||||
}, true);
|
||||
*/
|
||||
makeObservable(this);
|
||||
this.project = project;
|
||||
this.designer = this.project?.designer;
|
||||
this.emitter = new EventEmitter();
|
||||
@ -161,7 +155,7 @@ export class DocumentModel {
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
@obx.val private willPurgeSpace: Node[] = [];
|
||||
@obx.shallow private willPurgeSpace: Node[] = [];
|
||||
|
||||
get modalNode() {
|
||||
return this._modalNode;
|
||||
@ -182,7 +176,7 @@ export class DocumentModel {
|
||||
}
|
||||
}
|
||||
|
||||
@computed isBlank() {
|
||||
isBlank() {
|
||||
return this._blank && !this.isModified();
|
||||
}
|
||||
|
||||
@ -213,7 +207,7 @@ export class DocumentModel {
|
||||
return node ? !node.isPurged : false;
|
||||
}
|
||||
|
||||
@obx.val private activeNodes?: Node[];
|
||||
@obx.shallow private activeNodes?: Node[];
|
||||
|
||||
/**
|
||||
* 根据 schema 创建一个节点
|
||||
@ -362,6 +356,7 @@ export class DocumentModel {
|
||||
return this.rootNode?.schema as any;
|
||||
}
|
||||
|
||||
@action
|
||||
import(schema: RootSchema, checkId = false) {
|
||||
const drillDownNodeId = this._drillDownNode?.id;
|
||||
// TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除
|
||||
|
||||
@ -6,10 +6,6 @@ import { BuiltinSimulatorHostView } from '../builtin-simulator';
|
||||
|
||||
@observer
|
||||
export class DocumentView extends Component<{ document: DocumentModel }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { document } = this.props;
|
||||
const { simulatorProps } = document;
|
||||
|
||||
@ -31,20 +31,16 @@ export class History {
|
||||
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
private obx: Reaction;
|
||||
|
||||
private justWokeup = false;
|
||||
private asleep = false;
|
||||
|
||||
constructor(logger: () => any, private redoer: (data: NodeSchema) => void, private timeGap: number = 1000) {
|
||||
this.session = new Session(0, null, this.timeGap);
|
||||
this.records = [this.session];
|
||||
|
||||
this.obx = autorun(() => {
|
||||
autorun(() => {
|
||||
if (this.asleep) return;
|
||||
const data = logger();
|
||||
if (this.justWokeup) {
|
||||
this.justWokeup = false;
|
||||
return;
|
||||
}
|
||||
|
||||
untracked(() => {
|
||||
const log = currentSerialization.serialize(data);
|
||||
if (this.session.cursor === 0 && this.session.isActive()) {
|
||||
@ -68,7 +64,7 @@ export class History {
|
||||
}
|
||||
}
|
||||
});
|
||||
}, true).$obx;
|
||||
});
|
||||
}
|
||||
|
||||
get hotData() {
|
||||
@ -79,6 +75,14 @@ export class History {
|
||||
return this.point !== this.session.cursor;
|
||||
}
|
||||
|
||||
private sleep() {
|
||||
this.asleep = true;
|
||||
}
|
||||
|
||||
private wakeup() {
|
||||
this.asleep = false;
|
||||
}
|
||||
|
||||
go(cursor: number) {
|
||||
this.session.end();
|
||||
|
||||
@ -96,7 +100,7 @@ export class History {
|
||||
const session = this.records[cursor];
|
||||
const hotData = session.data;
|
||||
|
||||
this.obx.sleep();
|
||||
this.sleep();
|
||||
try {
|
||||
this.redoer(currentSerialization.unserialize(hotData));
|
||||
this.emitter.emit('cursor', hotData);
|
||||
@ -104,8 +108,7 @@ export class History {
|
||||
//
|
||||
}
|
||||
|
||||
this.justWokeup = true;
|
||||
this.obx.wakeup();
|
||||
this.wakeup();
|
||||
this.session = session;
|
||||
|
||||
this.emitter.emit('statechange', this.getState());
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { uniqueId } from '@ali/lowcode-utils';
|
||||
import { TitleContent } from '@ali/lowcode-types';
|
||||
import { Node } from './node';
|
||||
@ -11,7 +11,7 @@ export class ExclusiveGroup {
|
||||
|
||||
readonly id = uniqueId('exclusive');
|
||||
|
||||
@obx.val readonly children: Node[] = [];
|
||||
@obx.shallow readonly children: Node[] = [];
|
||||
|
||||
@obx private visibleIndex = 0;
|
||||
|
||||
@ -75,6 +75,7 @@ export class ExclusiveGroup {
|
||||
readonly title: TitleContent;
|
||||
|
||||
constructor(readonly name: string, title?: TitleContent) {
|
||||
makeObservable(this);
|
||||
this.title = title || {
|
||||
type: 'i18n',
|
||||
intl: intl('Condition Group'),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed, globalContext } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, globalContext, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { Node, ParentalNode } from './node';
|
||||
import { TransformStage } from './transform-stage';
|
||||
import { NodeData, isNodeSchema } from '@ali/lowcode-types';
|
||||
@ -8,11 +8,12 @@ import { foreachReverse } from '../../utils/tree';
|
||||
import { NodeRemoveOptions } from '../../types';
|
||||
|
||||
export class NodeChildren {
|
||||
@obx.val private children: Node[];
|
||||
@obx.shallow private children: Node[];
|
||||
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
constructor(readonly owner: ParentalNode, data: NodeData | NodeData[], options: any = {}) {
|
||||
makeObservable(this);
|
||||
this.children = (Array.isArray(data) ? data : [data]).map(child => {
|
||||
return this.owner.document.createNode(child, options.checkId);
|
||||
});
|
||||
@ -83,11 +84,11 @@ export class NodeChildren {
|
||||
/**
|
||||
* 是否空
|
||||
*/
|
||||
@computed isEmpty() {
|
||||
isEmpty() {
|
||||
return this.size < 1;
|
||||
}
|
||||
|
||||
@computed notEmpty() {
|
||||
notEmpty() {
|
||||
return this.size > 0;
|
||||
}
|
||||
|
||||
@ -387,7 +388,7 @@ export class NodeChildren {
|
||||
}
|
||||
|
||||
if (owner.parent && !owner.parent.isRoot()) {
|
||||
this.reportModified(node, owner.parent, { ...options, propagated: true, });
|
||||
this.reportModified(node, owner.parent, { ...options, propagated: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ReactElement } from 'react';
|
||||
import { EventEmitter } from 'events';
|
||||
import { obx, computed, autorun } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, autorun, makeObservable, runInAction, getObserverTree } from '@ali/lowcode-editor-core';
|
||||
import {
|
||||
isDOMText,
|
||||
isJSExpression,
|
||||
@ -160,6 +160,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
isInited = false;
|
||||
|
||||
constructor(readonly document: DocumentModel, nodeSchema: Schema, options: any = {}) {
|
||||
makeObservable(this);
|
||||
const { componentName, id, children, props, ...extras } = nodeSchema;
|
||||
this.id = document.nextId(id);
|
||||
this.componentName = componentName;
|
||||
@ -208,7 +209,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
this.autoruns = autoruns.map((item) => {
|
||||
return autorun(() => {
|
||||
item.autorun(this.props.get(item.name, true) as any);
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -382,7 +383,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
* 获取当前节点的锁定状态
|
||||
*/
|
||||
get isLocked(): boolean {
|
||||
return !!this.getExtraProp('isLocked', false)?.getValue();
|
||||
return !!this.getExtraProp('isLocked')?.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -417,9 +418,9 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
return this.props.export(TransformStage.Serilize).props || null;
|
||||
}
|
||||
|
||||
@obx.val _slots: Node[] = [];
|
||||
@obx.shallow _slots: Node[] = [];
|
||||
|
||||
@computed hasSlots() {
|
||||
hasSlots() {
|
||||
return this._slots.length > 0;
|
||||
}
|
||||
|
||||
@ -465,7 +466,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
@computed isConditionalVisible(): boolean | undefined {
|
||||
isConditionalVisible(): boolean | undefined {
|
||||
return this._conditionGroup?.isVisible(this);
|
||||
}
|
||||
|
||||
@ -474,7 +475,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
this._conditionGroup?.setVisible(this);
|
||||
}
|
||||
|
||||
@computed hasCondition() {
|
||||
hasCondition() {
|
||||
const v = this.getExtraProp('condition', false)?.getValue();
|
||||
return v != null && v !== '' && v !== true;
|
||||
}
|
||||
@ -483,7 +484,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
* has loop when 1. loop is validArray with length > 1 ; OR 2. loop is variable object
|
||||
* @return boolean, has loop config or not
|
||||
*/
|
||||
@computed hasLoop() {
|
||||
hasLoop() {
|
||||
const value = this.getExtraProp('loop', false)?.getValue();
|
||||
if (value === undefined || value === null) {
|
||||
return false;
|
||||
@ -550,12 +551,12 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
};
|
||||
}
|
||||
|
||||
getProp(path: string, stash = true): Prop | null {
|
||||
return this.props.query(path, stash as any) || null;
|
||||
getProp(path: string, createIfNone = true): Prop | null {
|
||||
return this.props.query(path, createIfNone) || null;
|
||||
}
|
||||
|
||||
getExtraProp(key: string, stash = true): Prop | null {
|
||||
return this.props.get(getConvertedExtraKey(key), stash) || null;
|
||||
getExtraProp(key: string, createIfNone = true): Prop | null {
|
||||
return this.props.get(getConvertedExtraKey(key), createIfNone) || null;
|
||||
}
|
||||
|
||||
setExtraProp(key: string, value: CompositeValue) {
|
||||
@ -647,7 +648,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
}
|
||||
|
||||
set schema(data: Schema) {
|
||||
this.import(data);
|
||||
runInAction(() => this.import(data));
|
||||
}
|
||||
|
||||
import(data: Schema, checkId = false) {
|
||||
@ -865,9 +866,6 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
return this.componentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
insert(node: Node, ref?: Node, useMutator = true) {
|
||||
this.insertAfter(node, ref, useMutator);
|
||||
}
|
||||
@ -918,7 +916,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
this.children?.mergeChildren(remover, adder, sorter);
|
||||
}
|
||||
|
||||
@obx.val status: NodeStatus = {
|
||||
@obx.shallow status: NodeStatus = {
|
||||
inPlaceEditing: false,
|
||||
locking: false,
|
||||
pseudo: false,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, autorun, untracked, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, autorun, untracked, computed, makeObservable, action } from '@ali/lowcode-editor-core';
|
||||
import { Prop, IPropParent, UNSET } from './prop';
|
||||
import { Props } from './props';
|
||||
import { Node } from '../node';
|
||||
@ -7,7 +7,7 @@ export type PendingItem = Prop[];
|
||||
export class PropStash implements IPropParent {
|
||||
readonly isPropStash = true;
|
||||
|
||||
@obx.val private space: Set<Prop> = new Set();
|
||||
@obx.shallow private space: Set<Prop> = new Set();
|
||||
|
||||
@computed private get maps(): Map<string | number, Prop> {
|
||||
const maps = new Map();
|
||||
@ -24,6 +24,7 @@ export class PropStash implements IPropParent {
|
||||
readonly owner: Node;
|
||||
|
||||
constructor(readonly props: Props, write: (item: Prop) => void) {
|
||||
makeObservable(this);
|
||||
this.owner = props.owner;
|
||||
this.willPurge = autorun(() => {
|
||||
if (this.space.size < 1) {
|
||||
@ -46,6 +47,7 @@ export class PropStash implements IPropParent {
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
get(key: string | number): Prop {
|
||||
let prop = this.maps.get(key);
|
||||
if (!prop) {
|
||||
@ -55,16 +57,19 @@ export class PropStash implements IPropParent {
|
||||
return prop;
|
||||
}
|
||||
|
||||
@action
|
||||
delete(prop: Prop) {
|
||||
this.space.delete(prop);
|
||||
prop.purge();
|
||||
}
|
||||
|
||||
@action
|
||||
clear() {
|
||||
this.space.forEach(item => item.purge());
|
||||
this.space.clear();
|
||||
}
|
||||
|
||||
@action
|
||||
purge() {
|
||||
this.willPurge();
|
||||
this.space.clear();
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { untracked, computed, obx, engineConfig } from '@ali/lowcode-editor-core';
|
||||
import { untracked, computed, obx, engineConfig, action, makeObservable, mobx } from '@ali/lowcode-editor-core';
|
||||
import { CompositeValue, FieldConfig, isJSExpression, isJSSlot, JSSlot, SlotSchema } from '@ali/lowcode-types';
|
||||
import { uniqueId, isPlainObject, hasOwnProperty, compatStage } from '@ali/lowcode-utils';
|
||||
import { PropStash } from './prop-stash';
|
||||
import { valueToSource } from './value-to-source';
|
||||
import { Props } from './props';
|
||||
import { SlotNode, Node } from '../node';
|
||||
import { TransformStage } from '../transform-stage';
|
||||
|
||||
const { set: mobxSet, isObservableArray } = mobx;
|
||||
export const UNSET = Symbol.for('unset');
|
||||
export type UNSET = typeof UNSET;
|
||||
|
||||
@ -24,8 +24,6 @@ export class Prop implements IPropParent {
|
||||
|
||||
readonly owner: Node;
|
||||
|
||||
private stash: PropStash | undefined;
|
||||
|
||||
/**
|
||||
* 键值
|
||||
*/
|
||||
@ -47,6 +45,7 @@ export class Prop implements IPropParent {
|
||||
spread = false,
|
||||
options = {},
|
||||
) {
|
||||
makeObservable(this);
|
||||
this.owner = parent.owner;
|
||||
this.props = parent.props;
|
||||
this.key = key;
|
||||
@ -59,6 +58,7 @@ export class Prop implements IPropParent {
|
||||
}
|
||||
|
||||
// TODO: 先用调用方式触发子 prop 的初始化,后续须重构
|
||||
@action
|
||||
private setupItems() {
|
||||
return this.items;
|
||||
}
|
||||
@ -66,6 +66,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* @see SettingTarget
|
||||
*/
|
||||
@action
|
||||
getPropValue(propName: string | number): any {
|
||||
return this.get(propName)!.getValue();
|
||||
}
|
||||
@ -73,6 +74,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* @see SettingTarget
|
||||
*/
|
||||
@action
|
||||
setPropValue(propName: string | number, value: any): void {
|
||||
this.set(propName, value);
|
||||
}
|
||||
@ -80,6 +82,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* @see SettingTarget
|
||||
*/
|
||||
@action
|
||||
clearPropValue(propName: string | number): void {
|
||||
this.get(propName, false)?.unset();
|
||||
}
|
||||
@ -95,7 +98,7 @@ export class Prop implements IPropParent {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
@obx.ref private _value: any = UNSET;
|
||||
@obx private _value: any = UNSET;
|
||||
|
||||
/**
|
||||
* 属性值
|
||||
@ -213,7 +216,7 @@ export class Prop implements IPropParent {
|
||||
this._code = code;
|
||||
}
|
||||
|
||||
@computed getAsString(): string {
|
||||
getAsString(): string {
|
||||
if (this.type === 'literal') {
|
||||
return this._value ? String(this._value) : '';
|
||||
}
|
||||
@ -223,6 +226,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* set value, val should be JSON Object
|
||||
*/
|
||||
@action
|
||||
setValue(val: CompositeValue) {
|
||||
if (val === this._value) return;
|
||||
const editor = this.owner.document?.designer.editor;
|
||||
@ -267,10 +271,11 @@ export class Prop implements IPropParent {
|
||||
}
|
||||
}
|
||||
|
||||
@computed getValue(): CompositeValue {
|
||||
getValue(): CompositeValue {
|
||||
return this.export(TransformStage.Serilize);
|
||||
}
|
||||
|
||||
@action
|
||||
private dispose() {
|
||||
const items = untracked(() => this._items);
|
||||
if (items) {
|
||||
@ -278,9 +283,6 @@ export class Prop implements IPropParent {
|
||||
}
|
||||
this._items = null;
|
||||
this._maps = null;
|
||||
if (this.stash) {
|
||||
this.stash.clear();
|
||||
}
|
||||
if (this._type !== 'slot' && this._slotNode) {
|
||||
this._slotNode.remove();
|
||||
this._slotNode = undefined;
|
||||
@ -293,6 +295,7 @@ export class Prop implements IPropParent {
|
||||
return this._slotNode;
|
||||
}
|
||||
|
||||
@action
|
||||
setAsSlot(data: JSSlot) {
|
||||
this._type = 'slot';
|
||||
const slotSchema: SlotSchema = {
|
||||
@ -315,6 +318,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 取消设置值
|
||||
*/
|
||||
@action
|
||||
unset() {
|
||||
this._type = 'unset';
|
||||
}
|
||||
@ -322,6 +326,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 是否未设置值
|
||||
*/
|
||||
@action
|
||||
isUnset() {
|
||||
return this._type === 'unset';
|
||||
}
|
||||
@ -352,9 +357,9 @@ export class Prop implements IPropParent {
|
||||
return this.code === other.code ? 0 : 2;
|
||||
}
|
||||
|
||||
@obx.val private _items: Prop[] | null = null;
|
||||
@obx.shallow private _items: Prop[] | null = null;
|
||||
|
||||
@obx.val private _maps: Map<string | number, Prop> | null = null;
|
||||
@obx.shallow private _maps: Map<string | number, Prop> | null = null;
|
||||
|
||||
get path(): string[] {
|
||||
return (this.parent.path || []).concat(this.key as string);
|
||||
@ -401,11 +406,12 @@ export class Prop implements IPropParent {
|
||||
|
||||
/**
|
||||
* 获取某个属性
|
||||
* @param stash 如果不存在,临时获取一个待写入
|
||||
* @param createIfNone 当没有的时候,是否创建一个
|
||||
*/
|
||||
get(path: string | number, stash = true): Prop | null {
|
||||
@action
|
||||
get(path: string | number, createIfNone = true): Prop | null {
|
||||
const type = this._type;
|
||||
if (type !== 'map' && type !== 'list' && type !== 'unset' && !stash) {
|
||||
if (type !== 'map' && type !== 'list' && type !== 'unset' && !createIfNone) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -434,20 +440,12 @@ export class Prop implements IPropParent {
|
||||
}
|
||||
|
||||
if (prop) {
|
||||
return nest ? prop.get(nest, stash) : prop;
|
||||
return nest ? prop.get(nest, createIfNone) : prop;
|
||||
}
|
||||
|
||||
if (stash) {
|
||||
if (!this.stash) {
|
||||
this.stash = new PropStash(this.props, (item) => {
|
||||
// item take effect
|
||||
if (item.key) {
|
||||
this.set(item.key, item, true);
|
||||
}
|
||||
item.parent = this;
|
||||
});
|
||||
}
|
||||
prop = this.stash.get(entry);
|
||||
if (createIfNone) {
|
||||
prop = new Prop(this, UNSET, entry);
|
||||
this.set(entry, prop, true);
|
||||
if (nest) {
|
||||
return prop.get(nest, true);
|
||||
}
|
||||
@ -461,6 +459,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 从父级移除本身
|
||||
*/
|
||||
@action
|
||||
remove() {
|
||||
this.parent.delete(this);
|
||||
}
|
||||
@ -468,6 +467,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 删除项
|
||||
*/
|
||||
@action
|
||||
delete(prop: Prop): void {
|
||||
if (this.items) {
|
||||
const i = this.items.indexOf(prop);
|
||||
@ -484,6 +484,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 删除 key
|
||||
*/
|
||||
@action
|
||||
deleteKey(key: string): void {
|
||||
if (this.maps) {
|
||||
const prop = this.maps.get(key);
|
||||
@ -505,6 +506,7 @@ export class Prop implements IPropParent {
|
||||
*
|
||||
* @param force 强制
|
||||
*/
|
||||
@action
|
||||
add(value: CompositeValue, force = false): Prop | null {
|
||||
const type = this._type;
|
||||
if (type !== 'list' && type !== 'unset' && !force) {
|
||||
@ -523,6 +525,7 @@ export class Prop implements IPropParent {
|
||||
*
|
||||
* @param force 强制
|
||||
*/
|
||||
@action
|
||||
set(key: string | number, value: CompositeValue | Prop, force = false) {
|
||||
const type = this._type;
|
||||
if (type !== 'map' && type !== 'list' && type !== 'unset' && !force) {
|
||||
@ -543,7 +546,11 @@ export class Prop implements IPropParent {
|
||||
if (!isValidArrayIndex(key)) {
|
||||
return null;
|
||||
}
|
||||
items[key] = prop;
|
||||
if (isObservableArray(items)) {
|
||||
mobxSet(items, key, prop);
|
||||
} else {
|
||||
items[key] = prop;
|
||||
}
|
||||
} else if (this.maps) {
|
||||
const { maps } = this;
|
||||
const orig = maps.get(key);
|
||||
@ -584,14 +591,12 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 回收销毁
|
||||
*/
|
||||
@action
|
||||
purge() {
|
||||
if (this.purged) {
|
||||
return;
|
||||
}
|
||||
this.purged = true;
|
||||
if (this.stash) {
|
||||
this.stash.purge();
|
||||
}
|
||||
if (this._items) {
|
||||
this._items.forEach((item) => item.purge());
|
||||
}
|
||||
@ -627,6 +632,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 遍历
|
||||
*/
|
||||
@action
|
||||
forEach(fn: (item: Prop, key: number | string | undefined) => void): void {
|
||||
const { items } = this;
|
||||
if (!items) {
|
||||
@ -641,6 +647,7 @@ export class Prop implements IPropParent {
|
||||
/**
|
||||
* 遍历
|
||||
*/
|
||||
@action
|
||||
map<T>(fn: (item: Prop, key: number | string | undefined) => T): T[] | null {
|
||||
const { items } = this;
|
||||
if (!items) {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { computed, obx } from '@ali/lowcode-editor-core';
|
||||
import { computed, makeObservable, obx, action } from '@ali/lowcode-editor-core';
|
||||
import { PropsMap, PropsList, CompositeValue } from '@ali/lowcode-types';
|
||||
import { uniqueId, compatStage } from '@ali/lowcode-utils';
|
||||
import { PropStash } from './prop-stash';
|
||||
import { Prop, IPropParent, UNSET } from './prop';
|
||||
import { Node } from '../node';
|
||||
import { TransformStage } from '../transform-stage';
|
||||
@ -23,7 +22,7 @@ export function getOriginalExtraKey(key: string): string {
|
||||
export class Props implements IPropParent {
|
||||
readonly id = uniqueId('props');
|
||||
|
||||
@obx.val private items: Prop[] = [];
|
||||
@obx.shallow private items: Prop[] = [];
|
||||
|
||||
@computed private get maps(): Map<string, Prop> {
|
||||
const maps = new Map();
|
||||
@ -45,8 +44,6 @@ export class Props implements IPropParent {
|
||||
|
||||
readonly owner: Node;
|
||||
|
||||
private stash: PropStash;
|
||||
|
||||
/**
|
||||
* 元素个数
|
||||
*/
|
||||
@ -57,11 +54,8 @@ export class Props implements IPropParent {
|
||||
@obx type: 'map' | 'list' = 'map';
|
||||
|
||||
constructor(owner: Node, value?: PropsMap | PropsList | null, extras?: object) {
|
||||
makeObservable(this);
|
||||
this.owner = owner;
|
||||
this.stash = new PropStash(this, prop => {
|
||||
this.items.push(prop);
|
||||
prop.parent = this;
|
||||
});
|
||||
if (Array.isArray(value)) {
|
||||
this.type = 'list';
|
||||
this.items = value.map(item => new Prop(this, item.value, item.name, item.spread));
|
||||
@ -75,8 +69,8 @@ export class Props implements IPropParent {
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
import(value?: PropsMap | PropsList | null, extras?: object) {
|
||||
this.stash.clear();
|
||||
const originItems = this.items;
|
||||
if (Array.isArray(value)) {
|
||||
this.type = 'list';
|
||||
@ -96,6 +90,7 @@ export class Props implements IPropParent {
|
||||
originItems.forEach(item => item.purge());
|
||||
}
|
||||
|
||||
@action
|
||||
merge(value: PropsMap, extras?: PropsMap) {
|
||||
Object.keys(value).forEach(key => {
|
||||
this.query(key, true)!.setValue(value[key]);
|
||||
@ -119,9 +114,6 @@ export class Props implements IPropParent {
|
||||
props = [];
|
||||
this.items.forEach(item => {
|
||||
let value = item.export(stage);
|
||||
if (value === UNSET) {
|
||||
value = undefined;
|
||||
}
|
||||
let name = item.key as string;
|
||||
if (name && typeof name === 'string' && name.startsWith(EXTRA_KEY_PREFIX)) {
|
||||
name = getOriginalExtraKey(name);
|
||||
@ -142,9 +134,6 @@ export class Props implements IPropParent {
|
||||
return;
|
||||
}
|
||||
let value = item.export(stage);
|
||||
if (value === UNSET) {
|
||||
value = undefined;
|
||||
}
|
||||
allProps[name] = value;
|
||||
});
|
||||
// compatible vision
|
||||
@ -187,53 +176,19 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 根据 path 路径查询属性
|
||||
*
|
||||
* @param stash 如果没有则临时生成一个
|
||||
* @param createIfNone 当没有的时候,是否创建一个
|
||||
*/
|
||||
query(path: string, stash = true): Prop | null {
|
||||
return this.get(path, stash);
|
||||
// todo: future support list search
|
||||
// let matchedLength = 0;
|
||||
// let firstMatched = null;
|
||||
// if (this.items) {
|
||||
// // target: a.b.c
|
||||
// // trys: a.b.c, a.b, a
|
||||
// let i = this.items.length;
|
||||
// while (i-- > 0) {
|
||||
// const expr = this.items[i];
|
||||
// if (!expr.key) {
|
||||
// continue;
|
||||
// }
|
||||
// const name = String(expr.key);
|
||||
// if (name === path) {
|
||||
// // completely match
|
||||
// return expr;
|
||||
// }
|
||||
|
||||
// // fisrt match
|
||||
// const l = name.length;
|
||||
// if (path.slice(0, l + 1) === `${name}.`) {
|
||||
// matchedLength = l;
|
||||
// firstMatched = expr;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// let ret = null;
|
||||
// if (firstMatched) {
|
||||
// ret = firstMatched.get(path.slice(matchedLength + 1), true);
|
||||
// }
|
||||
// if (!ret && stash) {
|
||||
// return this.stash.get(path);
|
||||
// }
|
||||
|
||||
// return ret;
|
||||
@action
|
||||
query(path: string, createIfNone = true): Prop | null {
|
||||
return this.get(path, createIfNone);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个属性, 如果不存在,临时获取一个待写入
|
||||
* @param stash 强制
|
||||
* @param createIfNone 当没有的时候,是否创建一个
|
||||
*/
|
||||
get(path: string, stash = false): Prop | null {
|
||||
@action
|
||||
get(path: string, createIfNone = false): Prop | null {
|
||||
let entry = path;
|
||||
let nest = '';
|
||||
const i = path.indexOf('.');
|
||||
@ -244,10 +199,14 @@ export class Props implements IPropParent {
|
||||
}
|
||||
}
|
||||
|
||||
const prop = this.maps.get(entry) || (stash && this.stash.get(entry)) || null;
|
||||
let prop = this.maps.get(entry);
|
||||
if (!prop && createIfNone) {
|
||||
prop = new Prop(this, UNSET, entry);
|
||||
this.items.push(prop);
|
||||
}
|
||||
|
||||
if (prop) {
|
||||
return nest ? prop.get(nest, stash) : prop;
|
||||
return nest ? prop.get(nest, createIfNone) : prop;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -256,6 +215,7 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 删除项
|
||||
*/
|
||||
@action
|
||||
delete(prop: Prop): void {
|
||||
const i = this.items.indexOf(prop);
|
||||
if (i > -1) {
|
||||
@ -267,6 +227,7 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 删除 key
|
||||
*/
|
||||
@action
|
||||
deleteKey(key: string): void {
|
||||
this.items = this.items.filter(item => {
|
||||
if (item.key === key) {
|
||||
@ -280,6 +241,7 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 添加值
|
||||
*/
|
||||
@action
|
||||
add(value: CompositeValue | null, key?: string | number, spread = false, options: any = {}): Prop {
|
||||
const prop = new Prop(this, value, key, spread, options);
|
||||
this.items.push(prop);
|
||||
@ -319,6 +281,7 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 遍历
|
||||
*/
|
||||
@action
|
||||
forEach(fn: (item: Prop, key: number | string | undefined) => void): void {
|
||||
this.items.forEach(item => {
|
||||
return fn(item, item.key);
|
||||
@ -328,12 +291,14 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 遍历
|
||||
*/
|
||||
@action
|
||||
map<T>(fn: (item: Prop, key: number | string | undefined) => T): T[] | null {
|
||||
return this.items.map(item => {
|
||||
return fn(item, item.key);
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
filter(fn: (item: Prop, key: number | string | undefined) => boolean) {
|
||||
return this.items.filter(item => {
|
||||
return fn(item, item.key);
|
||||
@ -345,22 +310,28 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 回收销毁
|
||||
*/
|
||||
@action
|
||||
purge() {
|
||||
if (this.purged) {
|
||||
return;
|
||||
}
|
||||
this.purged = true;
|
||||
this.stash.purge();
|
||||
this.items.forEach(item => item.purge());
|
||||
}
|
||||
|
||||
getProp(path: string, stash = true): Prop | null {
|
||||
return this.query(path, stash as any) || null;
|
||||
/**
|
||||
* 获取某个属性, 如果不存在,临时获取一个待写入
|
||||
* @param createIfNone 当没有的时候,是否创建一个
|
||||
*/
|
||||
@action
|
||||
getProp(path: string, createIfNone = true): Prop | null {
|
||||
return this.query(path, createIfNone) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个属性值
|
||||
*/
|
||||
@action
|
||||
getPropValue(path: string): any {
|
||||
return this.getProp(path, false)?.value;
|
||||
}
|
||||
@ -368,6 +339,7 @@ export class Props implements IPropParent {
|
||||
/**
|
||||
* 设置单个属性值
|
||||
*/
|
||||
@action
|
||||
setPropValue(path: string, value: any) {
|
||||
this.getProp(path, true)!.setValue(value);
|
||||
}
|
||||
@ -383,6 +355,7 @@ export class Props implements IPropParent {
|
||||
* @deprecated
|
||||
* 获取 props 对应的 node
|
||||
*/
|
||||
@action
|
||||
toData() {
|
||||
return this.export()?.props;
|
||||
}
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { obx } from '@ali/lowcode-editor-core';
|
||||
import { obx, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { Node, comparePosition, PositionNO } from './node/node';
|
||||
import { DocumentModel } from './document-model';
|
||||
|
||||
export class Selection {
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
@obx.val private _selected: string[] = [];
|
||||
@obx.shallow private _selected: string[] = [];
|
||||
|
||||
constructor(readonly doc: DocumentModel) {}
|
||||
constructor(readonly doc: DocumentModel) {
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 选中的节点 id
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { Component } from 'react';
|
||||
import { observer } from '@ali/lowcode-editor-core';
|
||||
import { observer, engineConfig } from '@ali/lowcode-editor-core';
|
||||
import { Designer } from '../designer';
|
||||
import { BuiltinSimulatorHostView } from '../builtin-simulator';
|
||||
import './project.less';
|
||||
|
||||
class Loading extends Component {
|
||||
class BuiltinLoading extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div id="engine-loading-wrapper">
|
||||
@ -29,6 +29,7 @@ export class ProjectView extends Component<{ designer: Designer }> {
|
||||
const { project } = designer;
|
||||
const { simulatorProps } = project;
|
||||
const Simulator = designer.simulatorComponent || BuiltinSimulatorHostView;
|
||||
const Loading = engineConfig.get('loadingComponent', BuiltinLoading);
|
||||
|
||||
return (
|
||||
<div className="lc-project">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable, action } from '@ali/lowcode-editor-core';
|
||||
import { Designer } from '../designer';
|
||||
import { DocumentModel, isDocumentModel, isPageSchema } from '../document';
|
||||
import { ProjectSchema, RootSchema } from '@ali/lowcode-types';
|
||||
@ -8,7 +8,7 @@ import { ISimulatorHost } from '../simulator';
|
||||
export class Project {
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
@obx.val readonly documents: DocumentModel[] = [];
|
||||
@obx.shallow readonly documents: DocumentModel[] = [];
|
||||
|
||||
private data: ProjectSchema = { version: '1.0.0', componentsMap: [], componentsTree: [], i18n: {} };
|
||||
|
||||
@ -24,6 +24,7 @@ export class Project {
|
||||
// TODO: 考虑项目级别 History
|
||||
|
||||
constructor(readonly designer: Designer, schema?: ProjectSchema) {
|
||||
makeObservable(this);
|
||||
this.load(schema);
|
||||
}
|
||||
|
||||
@ -76,6 +77,7 @@ export class Project {
|
||||
*
|
||||
* @param autoOpen true 自动打开文档 string 指定打开的文件
|
||||
*/
|
||||
@action
|
||||
load(schema?: ProjectSchema, autoOpen?: boolean | string) {
|
||||
this.unload();
|
||||
// load new document
|
||||
|
||||
@ -105,7 +105,7 @@ describe('Host 测试', () => {
|
||||
type: AssetType.CSSText,
|
||||
content: '.theme {font-size: 50px;}',
|
||||
});
|
||||
expect(host.componentsMap).toBe(designer.componentsMap);
|
||||
expect(host.componentsMap).toEqual(designer.componentsMap);
|
||||
expect(host.requestHandlersMap).toEqual({});
|
||||
|
||||
host.set('renderEnv', 'vue');
|
||||
|
||||
@ -85,7 +85,7 @@ describe('Prop 类测试', () => {
|
||||
|
||||
strProp.unset();
|
||||
strProp.add(2, true);
|
||||
strProp.set(1);
|
||||
strProp.set(0);
|
||||
|
||||
expect(numProp.set()).toBeNull();
|
||||
expect(numProp.has()).toBeFalsy();
|
||||
@ -391,7 +391,7 @@ describe('Prop 类测试', () => {
|
||||
prop.unset();
|
||||
prop.set(0, true);
|
||||
expect(prop.set('x', 'invalid')).toBeNull();
|
||||
expect(prop.get(0).getValue()).toBeTruthy();
|
||||
expect(prop.get(0).getValue()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('export', () => {
|
||||
|
||||
@ -50,10 +50,9 @@ describe('组件元数据处理', () => {
|
||||
expect(meta.availableActions[2].name).toBe('copy');
|
||||
|
||||
removeBuiltinComponentAction('remove');
|
||||
// availableActions 有 computed 缓存
|
||||
expect(meta.availableActions[0].name).toBe('remove');
|
||||
expect(meta.availableActions[1].name).toBe('hide');
|
||||
expect(meta.availableActions[2].name).toBe('copy');
|
||||
expect(meta.availableActions).toHaveLength(4);
|
||||
expect(meta.availableActions[0].name).toBe('hide');
|
||||
expect(meta.availableActions[1].name).toBe('copy');
|
||||
|
||||
addBuiltinComponentAction({
|
||||
name: 'new',
|
||||
@ -61,10 +60,9 @@ describe('组件元数据处理', () => {
|
||||
action() {},
|
||||
},
|
||||
});
|
||||
// availableActions 有 computed 缓存
|
||||
expect(meta.availableActions).toHaveLength(5);
|
||||
expect(meta.availableActions[0].name).toBe('remove');
|
||||
expect(meta.availableActions[1].name).toBe('hide');
|
||||
expect(meta.availableActions[2].name).toBe('copy');
|
||||
expect(meta.availableActions[0].name).toBe('hide');
|
||||
expect(meta.availableActions[1].name).toBe('copy');
|
||||
expect(meta.availableActions[4].name).toBe('new');
|
||||
});
|
||||
});
|
||||
|
||||
@ -16,8 +16,6 @@
|
||||
"@ali/lowcode-types": "1.0.66",
|
||||
"@ali/lowcode-utils": "1.0.66",
|
||||
"@alifd/next": "^1.19.16",
|
||||
"@recore/obx": "^1.0.9",
|
||||
"@recore/obx-react": "^1.0.8",
|
||||
"classnames": "^2.2.6",
|
||||
"debug": "^4.1.1",
|
||||
"intl-messageformat": "^9.3.1",
|
||||
@ -25,7 +23,9 @@
|
||||
"power-di": "^2.2.4",
|
||||
"react": "^16",
|
||||
"react-dom": "^16.7.0",
|
||||
"store": "^2.0.12"
|
||||
"store": "^2.0.12",
|
||||
"mobx": "^6.3.0",
|
||||
"mobx-react": "^7.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alib/build-scripts": "^0.1.18",
|
||||
|
||||
@ -39,7 +39,7 @@ export class Editor extends EventEmitter implements IEditor {
|
||||
/**
|
||||
* Ioc Container
|
||||
*/
|
||||
@obx.val private context = new Map<KeyType, any>();
|
||||
@obx.shallow private context = new Map<KeyType, any>();
|
||||
|
||||
get locale() {
|
||||
return globalLocale.getLocale();
|
||||
|
||||
@ -97,7 +97,8 @@ export function createIntl(
|
||||
getLocale(): string;
|
||||
setLocale(locale: string): void;
|
||||
} {
|
||||
const data = computed(() => {
|
||||
// TODO: make reactive
|
||||
const data = (() => {
|
||||
const locale = globalLocale.getLocale();
|
||||
if (typeof instance === 'string') {
|
||||
if ((window as any)[instance]) {
|
||||
@ -110,11 +111,11 @@ export function createIntl(
|
||||
return (instance as any)[locale] || {};
|
||||
}
|
||||
return {};
|
||||
});
|
||||
})();
|
||||
|
||||
function intl(key: string, params?: object): string {
|
||||
// TODO: tries lost language
|
||||
const str = data.value[key];
|
||||
const str = data[key];
|
||||
|
||||
if (str == null) {
|
||||
return `##intl@${key}##`;
|
||||
|
||||
@ -1,5 +1,24 @@
|
||||
import { observer } from '@recore/obx-react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { configure } from 'mobx';
|
||||
|
||||
export * from '@recore/obx';
|
||||
configure({ enforceActions: 'never' });
|
||||
|
||||
// 常用的直接导出,其他的以 mobx 命名空间导出
|
||||
export {
|
||||
observable as obx,
|
||||
observable,
|
||||
observe,
|
||||
autorun,
|
||||
makeObservable,
|
||||
makeAutoObservable,
|
||||
reaction,
|
||||
computed,
|
||||
action,
|
||||
runInAction,
|
||||
untracked,
|
||||
IReactionDisposer,
|
||||
IReactionPublic,
|
||||
IReactionOptions,
|
||||
} from 'mobx';
|
||||
export * as mobx from 'mobx';
|
||||
export { observer };
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import WidgetContainer from './widget/widget-container';
|
||||
import { Skeleton } from './skeleton';
|
||||
import { IWidget } from './widget/widget';
|
||||
@ -24,10 +24,11 @@ export default class Area<C extends IWidgetBaseConfig = 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) {
|
||||
makeObservable(this);
|
||||
this.container = skeleton.createContainer(name, handle, exclusive, () => this.visible, defaultSetCurrent);
|
||||
}
|
||||
|
||||
@computed isEmpty(): boolean {
|
||||
isEmpty(): boolean {
|
||||
return this.container.items.length < 1;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, Fragment } from 'react';
|
||||
import { Icon, Button, Message } from '@alifd/next';
|
||||
import { Title } from '@ali/lowcode-editor-core';
|
||||
import { Title, runInAction } from '@ali/lowcode-editor-core';
|
||||
import { SetterType, FieldConfig, SetterConfig } from '@ali/lowcode-types';
|
||||
import { SettingField } from '@ali/lowcode-designer';
|
||||
import { createSettingFieldView } from '../settings/settings-pane';
|
||||
@ -60,9 +60,11 @@ export class ListSetter extends Component<ArraySetterProps, ArraySetterState> {
|
||||
itemsMap,
|
||||
}, () => {
|
||||
// setValue 会触发onItemChange,需要在items被设值之后才能调用
|
||||
value && value.map((item, index) => {
|
||||
items[index].setValue(item);
|
||||
return item;
|
||||
runInAction(() => {
|
||||
value && value.map((item, index) => {
|
||||
items[index].setValue(item);
|
||||
return item;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { Node, Designer, Selection, SettingTopEntry } from '@ali/lowcode-designer';
|
||||
import { Editor, obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { executePendingFn } from '@ali/lowcode-utils';
|
||||
import { Editor, obx, computed, makeObservable, action } from '@ali/lowcode-editor-core';
|
||||
|
||||
function generateSessionId(nodes: Node[]) {
|
||||
return nodes
|
||||
@ -34,6 +33,7 @@ export class SettingsMain {
|
||||
private designer?: Designer;
|
||||
|
||||
constructor(readonly editor: Editor) {
|
||||
makeObservable(this);
|
||||
this.init();
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ export class SettingsMain {
|
||||
setupSelection(designer.currentSelection);
|
||||
}
|
||||
|
||||
@action
|
||||
private setup(nodes: Node[]) {
|
||||
// check nodes change
|
||||
const sessionId = generateSessionId(nodes);
|
||||
|
||||
@ -158,10 +158,6 @@ class SettingFieldView extends Component<{ field: SettingField }> {
|
||||
class SettingGroupView extends Component<{ field: SettingField }> {
|
||||
static contextType = SkeletonContext;
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { field } = this.props;
|
||||
const { extraProps } = field;
|
||||
@ -227,12 +223,7 @@ export type SettingsPaneProps = {
|
||||
export class SettingsPane extends Component<SettingsPaneProps> {
|
||||
static contextType = SkeletonContext;
|
||||
|
||||
@obx
|
||||
private currentStage?: Stage;
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
@obx private currentStage?: Stage;
|
||||
|
||||
private popupPipe = new PopupPipe();
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Tab, Breadcrumb } from '@alifd/next';
|
||||
import { Title, observer, Editor, obx, globalContext, engineConfig } from '@ali/lowcode-editor-core';
|
||||
import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { Node, isSettingField, SettingField, Designer } from '@ali/lowcode-designer';
|
||||
import { SettingsMain } from './main';
|
||||
import { SettingsPane } from './settings-pane';
|
||||
@ -16,8 +16,9 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
|
||||
|
||||
@obx.ref private _activeKey?: any;
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
constructor(props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -62,8 +63,8 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
|
||||
);
|
||||
}
|
||||
|
||||
const editor = globalContext.get(Editor);
|
||||
const designer = editor.get(Designer);
|
||||
const editor = globalContext.get('editor');
|
||||
const designer = editor.get('designer');
|
||||
const current = designer?.currentSelection?.getNodes()?.[0];
|
||||
let node: Node | null = settings.first;
|
||||
const focusNode = node.document.focusNode;
|
||||
@ -229,6 +230,7 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
|
||||
|
||||
return (
|
||||
<div className="lc-settings-main">
|
||||
{ this.renderBreadcrumb() }
|
||||
<Tab
|
||||
activeKey={activeKey}
|
||||
onChange={(tabKey) => {
|
||||
@ -238,7 +240,6 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
|
||||
animation={false}
|
||||
excessMode="dropdown"
|
||||
contentClassName="lc-settings-tabs-content"
|
||||
extra={this.renderBreadcrumb()}
|
||||
>
|
||||
{tabs}
|
||||
</Tab>
|
||||
|
||||
@ -157,10 +157,6 @@ export class DraggableLineView extends Component<{ panel: Panel }> {
|
||||
|
||||
@observer
|
||||
export class TitledPanelView extends Component<{ panel: Panel; area?: string }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
}
|
||||
@ -218,10 +214,6 @@ export class PanelView extends Component<{
|
||||
hideOperationRow?: boolean;
|
||||
hideDragLine?: boolean;
|
||||
}> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
}
|
||||
@ -333,10 +325,6 @@ class PanelTitle extends Component<{ panel: Panel; className?: string }> {
|
||||
|
||||
@observer
|
||||
export class WidgetView extends Component<{ widget: IWidget }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.checkVisible();
|
||||
this.checkDisabled();
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
import { Component, Fragment } from 'react';
|
||||
import { Button, Icon } from '@alifd/next';
|
||||
import { action, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { IconFix } from '../../icons/fix';
|
||||
import { IconFloat } from '../../icons/float';
|
||||
import Panel from '../../widget/panel';
|
||||
|
||||
export default class PanelOperationRow extends Component<{ panel: Panel }> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
// fix or float
|
||||
@action
|
||||
setDisplay() {
|
||||
const { panel } = this.props;
|
||||
const current = panel;
|
||||
|
||||
@ -6,10 +6,6 @@ import Panel from '../widget/panel';
|
||||
|
||||
@observer
|
||||
export default class BottomArea extends Component<{ area: Area<any, Panel> }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { area } = this.props;
|
||||
if (area.isEmpty()) {
|
||||
|
||||
@ -25,7 +25,7 @@ class Contents extends Component<{ area: Area }> {
|
||||
const { area } = this.props;
|
||||
const top: any[] = [];
|
||||
const bottom: any[] = [];
|
||||
area.container.items.sort((a, b) => {
|
||||
area.container.items.slice().sort((a, b) => {
|
||||
const index1 = a.config?.index || 0;
|
||||
const index2 = b.config?.index || 0;
|
||||
return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1);
|
||||
|
||||
@ -4,17 +4,12 @@ import { observer } from '@ali/lowcode-editor-core';
|
||||
import Area from '../area';
|
||||
import { PanelConfig } from '../types';
|
||||
import Panel from '../widget/panel';
|
||||
import { Designer } from '@ali/lowcode-designer';
|
||||
|
||||
@observer
|
||||
export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// FIXME: dirty fix, need deep think
|
||||
this.props.area.skeleton.editor.get(Designer)?.touchOffsetObserver();
|
||||
this.props.area.skeleton.editor.get('designer')?.touchOffsetObserver();
|
||||
}
|
||||
|
||||
|
||||
@ -42,10 +37,6 @@ export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, P
|
||||
|
||||
@observer
|
||||
class Contents extends Component<{ area: Area<PanelConfig, Panel> }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { area } = this.props;
|
||||
return <Fragment>{area.container.items.map((panel) => panel.content)}</Fragment>;
|
||||
|
||||
@ -6,11 +6,6 @@ import Panel from '../widget/panel';
|
||||
|
||||
@observer
|
||||
export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> {
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private dispose?: () => void;
|
||||
|
||||
private focusing?: Focusable;
|
||||
@ -118,10 +113,6 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }>
|
||||
|
||||
@observer
|
||||
class Contents extends Component<{ area: Area<any, Panel> }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { area } = this.props;
|
||||
return (
|
||||
|
||||
@ -7,10 +7,6 @@ import Widget from '../widget/widget';
|
||||
|
||||
@observer
|
||||
export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { area } = this.props;
|
||||
return (
|
||||
|
||||
@ -6,10 +6,6 @@ import Panel from '../widget/panel';
|
||||
|
||||
@observer
|
||||
export default class RightArea extends Component<{ area: Area<any, Panel> }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { area } = this.props;
|
||||
return (
|
||||
|
||||
@ -25,7 +25,7 @@ class Contents extends Component<{ area: Area, itemClassName?: string }> {
|
||||
const left: any[] = [];
|
||||
const center: any[] = [];
|
||||
const right: any[] = [];
|
||||
area.container.items.sort((a, b) => {
|
||||
area.container.items.slice().sort((a, b) => {
|
||||
const index1 = a.config?.index || 0;
|
||||
const index2 = b.config?.index || 0;
|
||||
return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1);
|
||||
|
||||
@ -22,10 +22,6 @@ export class Workbench extends Component<{ skeleton: Skeleton; config?: EditorCo
|
||||
skeleton.buildFromConfig(config, components);
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// componentDidCatch(error: any) {
|
||||
// globalContext.get(Editor).emit('editor.skeleton.workbench.error', error);
|
||||
// }
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ReactNode, createElement } from 'react';
|
||||
import { obx } from '@ali/lowcode-editor-core';
|
||||
import { makeObservable, obx } from '@ali/lowcode-editor-core';
|
||||
import { uniqueId, createContent } from '@ali/lowcode-utils';
|
||||
import { DockConfig } from '../types';
|
||||
import { Skeleton } from '../skeleton';
|
||||
@ -59,6 +59,7 @@ export default class Dock implements IWidget {
|
||||
}
|
||||
|
||||
constructor(readonly skeleton: Skeleton, readonly config: DockConfig) {
|
||||
makeObservable(this);
|
||||
const { props = {}, name } = config;
|
||||
this.name = name;
|
||||
this.align = props.align;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { uniqueId } from '@ali/lowcode-utils';
|
||||
import { createElement, ReactNode, ReactInstance } from 'react';
|
||||
import { Skeleton } from '../skeleton';
|
||||
@ -77,6 +77,7 @@ export default class PanelDock implements IWidget {
|
||||
}
|
||||
|
||||
constructor(readonly skeleton: Skeleton, readonly config: PanelDockConfig) {
|
||||
makeObservable(this);
|
||||
const { content, contentProps, panelProps, name, props } = config;
|
||||
this.name = name;
|
||||
this.id = uniqueId(`dock:${name}$`);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { createElement, ReactNode } from 'react';
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { uniqueId, createContent } from '@ali/lowcode-utils';
|
||||
import { TitleContent } from '@ali/lowcode-types';
|
||||
import WidgetContainer from './widget-container';
|
||||
@ -24,7 +24,7 @@ export default class Panel implements IWidget {
|
||||
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
get actived(): boolean {
|
||||
@computed get actived(): boolean {
|
||||
return this._actived;
|
||||
}
|
||||
|
||||
@ -81,6 +81,7 @@ export default class Panel implements IWidget {
|
||||
private parent?: WidgetContainer;
|
||||
|
||||
constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) {
|
||||
makeObservable(this);
|
||||
const { name, content, props = {} } = config;
|
||||
const { hideTitleBar, title, icon, description, help } = props;
|
||||
this.name = name;
|
||||
@ -160,13 +161,13 @@ export default class Panel implements IWidget {
|
||||
return;
|
||||
}
|
||||
if (flag) {
|
||||
this._actived = true;
|
||||
this.parent?.active(this);
|
||||
if (this.parent.name === 'leftFloatArea') {
|
||||
this.skeleton.leftFixedArea.container.unactiveAll();
|
||||
} else if (this.parent.name === 'leftFixedArea') {
|
||||
this.skeleton.leftFloatArea.container.unactiveAll();
|
||||
}
|
||||
this._actived = true;
|
||||
this.parent?.active(this);
|
||||
if (!this.inited) {
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { isPanel } from './panel';
|
||||
import { obx, computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { hasOwnProperty } from '@ali/lowcode-utils';
|
||||
import { isPanel } from './panel';
|
||||
|
||||
export interface WidgetItem {
|
||||
name: string;
|
||||
@ -15,7 +15,7 @@ function isActiveable(obj: any): obj is Activeable {
|
||||
}
|
||||
|
||||
export default class WidgetContainer<T extends WidgetItem = any, G extends WidgetItem = any> {
|
||||
@obx.val items: T[] = [];
|
||||
@obx.shallow items: T[] = [];
|
||||
|
||||
private maps: { [name: string]: T } = {};
|
||||
|
||||
@ -32,8 +32,9 @@ export default class WidgetContainer<T extends WidgetItem = any, G extends Widge
|
||||
private exclusive: boolean = false,
|
||||
private checkVisible: () => boolean = () => true,
|
||||
private defaultSetCurrent: boolean = false,
|
||||
// eslint-disable-next-line no-empty-function
|
||||
) {}
|
||||
) {
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@computed get visible() {
|
||||
return this.checkVisible();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ReactNode, createElement } from 'react';
|
||||
import { obx } from '@ali/lowcode-editor-core';
|
||||
import { makeObservable, obx } from '@ali/lowcode-editor-core';
|
||||
import { createContent, uniqueId } from '@ali/lowcode-utils';
|
||||
import { WidgetConfig, IWidgetBaseConfig } from '../types';
|
||||
import { Skeleton } from '../skeleton';
|
||||
@ -71,6 +71,7 @@ export default class Widget implements IWidget {
|
||||
readonly title: TitleContent;
|
||||
|
||||
constructor(readonly skeleton: Skeleton, readonly config: WidgetConfig) {
|
||||
makeObservable(this);
|
||||
const { props = {}, name } = config;
|
||||
this.name = name;
|
||||
this.align = props.align;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { computed, obx } from '@ali/lowcode-editor-core';
|
||||
import { computed, makeObservable, obx } from '@ali/lowcode-editor-core';
|
||||
import {
|
||||
Designer,
|
||||
ISensor,
|
||||
@ -17,12 +17,12 @@ import {
|
||||
contains,
|
||||
Node,
|
||||
} from '@ali/lowcode-designer';
|
||||
import { uniqueId } from '@ali/lowcode-utils';
|
||||
import { IEditor } from '@ali/lowcode-types';
|
||||
import TreeNode from './tree-node';
|
||||
import { IndentTrack } from './helper/indent-track';
|
||||
import DwellTimer from './helper/dwell-timer';
|
||||
import { uniqueId } from '@ali/lowcode-utils';
|
||||
import { Backup } from './views/backup-pane';
|
||||
import { IEditor } from '@ali/lowcode-types';
|
||||
import { ITreeBoard, TreeMaster, getTreeMaster } from './tree-master';
|
||||
|
||||
export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
|
||||
@ -51,6 +51,7 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
|
||||
readonly at: string | symbol;
|
||||
|
||||
constructor(editor: IEditor, at: string | symbol) {
|
||||
makeObservable(this);
|
||||
this.editor = editor;
|
||||
this.at = at;
|
||||
let inited = false;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { computed, obx } from '@ali/lowcode-editor-core';
|
||||
import { computed, makeObservable, obx } from '@ali/lowcode-editor-core';
|
||||
import { Designer, isLocationChildrenDetail } from '@ali/lowcode-designer';
|
||||
import TreeNode from './tree-node';
|
||||
import { Tree } from './tree';
|
||||
@ -14,6 +14,7 @@ export class TreeMaster {
|
||||
readonly designer: Designer;
|
||||
|
||||
constructor(designer: Designer) {
|
||||
makeObservable(this);
|
||||
this.designer = designer;
|
||||
let startTime: any;
|
||||
designer.dragon.onDragstart(() => {
|
||||
@ -71,7 +72,7 @@ export class TreeMaster {
|
||||
}
|
||||
}
|
||||
|
||||
@obx.val private boards = new Set<ITreeBoard>();
|
||||
@obx.shallow private boards = new Set<ITreeBoard>();
|
||||
|
||||
addBoard(board: ITreeBoard) {
|
||||
this.boards.add(board);
|
||||
@ -81,7 +82,7 @@ export class TreeMaster {
|
||||
this.boards.delete(board);
|
||||
}
|
||||
|
||||
@computed hasVisibleTreeBoard() {
|
||||
hasVisibleTreeBoard() {
|
||||
for (const item of this.boards) {
|
||||
if (item.visible && item.at !== Backup) {
|
||||
return true;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { TitleContent, isI18nData } from '@ali/lowcode-types';
|
||||
import { computed, obx, intl } from '@ali/lowcode-editor-core';
|
||||
import { computed, obx, intl, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import { Node, DocumentModel, isLocationChildrenDetail, LocationChildrenDetail, Designer } from '@ali/lowcode-designer';
|
||||
import { Tree } from './tree';
|
||||
|
||||
@ -35,7 +35,7 @@ export default class TreeNode {
|
||||
/**
|
||||
* 是否是响应投放区
|
||||
*/
|
||||
@computed isResponseDropping(): boolean {
|
||||
isResponseDropping(): boolean {
|
||||
const loc = this.node.document.dropLocation;
|
||||
if (!loc) {
|
||||
return false;
|
||||
@ -43,7 +43,7 @@ export default class TreeNode {
|
||||
return loc.target === this.node;
|
||||
}
|
||||
|
||||
@computed isFocusingNode(): boolean {
|
||||
isFocusingNode(): boolean {
|
||||
const loc = this.node.document.dropLocation;
|
||||
if (!loc) {
|
||||
return false;
|
||||
@ -218,6 +218,7 @@ export default class TreeNode {
|
||||
readonly tree: Tree;
|
||||
|
||||
constructor(tree: Tree, node: Node) {
|
||||
makeObservable(this);
|
||||
this.tree = tree;
|
||||
this.document = node.document;
|
||||
this.designer = this.document.designer;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { DocumentModel, Node } from '@ali/lowcode-designer';
|
||||
import { computed } from '@ali/lowcode-editor-core';
|
||||
import { computed, makeObservable } from '@ali/lowcode-editor-core';
|
||||
import TreeNode from './tree-node';
|
||||
|
||||
export class Tree {
|
||||
@ -15,6 +15,7 @@ export class Tree {
|
||||
}
|
||||
|
||||
constructor(readonly document: DocumentModel) {
|
||||
makeObservable(this);
|
||||
this.id = document.id;
|
||||
}
|
||||
|
||||
|
||||
@ -10,10 +10,6 @@ import { IEditor } from '@ali/lowcode-types';
|
||||
export class OutlinePane extends Component<{ config: any; editor: IEditor }> {
|
||||
private main = new OutlineMain(this.props.editor, this.props.config.name || this.props.config.pluginKey);
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.main.purge();
|
||||
}
|
||||
|
||||
@ -18,10 +18,6 @@ class ModalTreeNodeView extends Component<{ treeNode: TreeNode }> {
|
||||
this.modalNodesManager = props.treeNode.document.modalNodesManager;
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
hideAllNodes() {
|
||||
this.modalNodesManager.hideModalNodes();
|
||||
}
|
||||
@ -57,10 +53,6 @@ class ModalTreeNodeView extends Component<{ treeNode: TreeNode }> {
|
||||
|
||||
@observer
|
||||
export default class RootTreeNodeView extends Component<{ treeNode: TreeNode }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode } = this.props;
|
||||
const className = classNames('tree-node', {
|
||||
|
||||
@ -11,10 +11,6 @@ export default class TreeBranches extends Component<{
|
||||
treeNode: TreeNode;
|
||||
isModal?: boolean;
|
||||
}> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode, isModal } = this.props;
|
||||
const { expanded } = treeNode;
|
||||
@ -39,10 +35,6 @@ class TreeNodeChildren extends Component<{
|
||||
treeNode: TreeNode;
|
||||
isModal?: boolean;
|
||||
}> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode, isModal } = this.props;
|
||||
const children: any = [];
|
||||
@ -112,10 +104,6 @@ class TreeNodeChildren extends Component<{
|
||||
class TreeNodeSlots extends Component<{
|
||||
treeNode: TreeNode;
|
||||
}> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode } = this.props;
|
||||
if (!treeNode.hasSlots()) {
|
||||
|
||||
@ -10,10 +10,6 @@ export default class TreeNodeView extends Component<{
|
||||
treeNode: TreeNode;
|
||||
isModal?: boolean;
|
||||
}> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode, isModal } = this.props;
|
||||
const className = classNames('tree-node', {
|
||||
|
||||
@ -176,10 +176,6 @@ export default class TreeTitle extends Component<{
|
||||
|
||||
@observer
|
||||
class LockBtn extends Component<{ treeNode: TreeNode }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode } = this.props;
|
||||
return (
|
||||
@ -199,10 +195,6 @@ class LockBtn extends Component<{ treeNode: TreeNode }> {
|
||||
|
||||
@observer
|
||||
class HideBtn extends Component<{ treeNode: TreeNode }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode } = this.props;
|
||||
return (
|
||||
@ -224,10 +216,6 @@ class HideBtn extends Component<{ treeNode: TreeNode }> {
|
||||
|
||||
@observer
|
||||
class ExpandBtn extends Component<{ treeNode: TreeNode }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { treeNode } = this.props;
|
||||
if (!treeNode.expandable) {
|
||||
|
||||
@ -17,7 +17,8 @@
|
||||
"@ali/lowcode-utils": "1.0.66",
|
||||
"@ali/recore-rax": "^1.2.4",
|
||||
"@ali/vu-css-style": "^1.0.2",
|
||||
"@recore/obx": "^1.0.8",
|
||||
"mobx": "^6.3.0",
|
||||
"mobx-react": "^7.2.0",
|
||||
"classnames": "^2.2.6",
|
||||
"driver-universal": "^3.1.3",
|
||||
"history": "^5.0.0",
|
||||
@ -30,7 +31,6 @@
|
||||
"devDependencies": {
|
||||
"@alib/build-scripts": "^0.1.18",
|
||||
"@babel/plugin-transform-react-jsx": "^7.10.4",
|
||||
"@recore/obx": "^1.0.8",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/node": "^13.7.1",
|
||||
"@types/rax": "^1.0.0",
|
||||
|
||||
@ -2,7 +2,7 @@ import { BuiltinSimulatorRenderer, Component, DocumentModel, Node, NodeInstance
|
||||
import { ComponentSchema, NodeSchema, NpmInfo, RootSchema, TransformStage } from '@ali/lowcode-types';
|
||||
import { Asset, compatibleLegaoSchema, cursor, isElement, isESModule, isPlainObject, isReactComponent, setNativeSelection } from '@ali/lowcode-utils';
|
||||
import LowCodeRenderer from '@ali/lowcode-rax-renderer';
|
||||
import { computed, obx } from '@recore/obx';
|
||||
import { computed, observable as obx, untracked, makeObservable, configure } from 'mobx';
|
||||
import DriverUniversal from 'driver-universal';
|
||||
import { EventEmitter } from 'events';
|
||||
import { createMemoryHistory, MemoryHistory } from 'history';
|
||||
@ -17,6 +17,7 @@ import { getClientRects } from './utils/get-client-rects';
|
||||
import loader from './utils/loader';
|
||||
import { parseQuery, withQueryParams } from './utils/url';
|
||||
|
||||
configure({ enforceActions: 'never' });
|
||||
const { Instance } = shared;
|
||||
|
||||
export interface LibraryMap {
|
||||
@ -110,6 +111,7 @@ export class DocumentInstance {
|
||||
private dispose?: () => void;
|
||||
|
||||
constructor(readonly container: SimulatorRendererContainer, readonly document: DocumentModel) {
|
||||
makeObservable(this);
|
||||
this.dispose = host.autorun(() => {
|
||||
// sync schema
|
||||
this._schema = document.export(TransformStage.Render);
|
||||
@ -270,7 +272,8 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
});
|
||||
const documentInstanceMap = new Map<string, DocumentInstance>();
|
||||
let initialEntry = '/';
|
||||
host.autorun(({ firstRun }) => {
|
||||
let firstRun = true;
|
||||
host.autorun(() => {
|
||||
this._documentInstances = host.project.documents.map((doc) => {
|
||||
let inst = documentInstanceMap.get(doc.id);
|
||||
if (!inst) {
|
||||
@ -283,6 +286,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
const path = host.project.currentDocument ? documentInstanceMap.get(host.project.currentDocument.id)!.path : '/';
|
||||
if (firstRun) {
|
||||
initialEntry = path;
|
||||
firstRun = false;
|
||||
} else {
|
||||
if (this.history.location.pathname !== path) {
|
||||
this.history.replace(path);
|
||||
|
||||
@ -22,7 +22,9 @@
|
||||
"@recore/obx-react": "^1.0.7",
|
||||
"classnames": "^2.2.6",
|
||||
"react": "^16",
|
||||
"react-dom": "^16.7.0"
|
||||
"react-dom": "^16.7.0",
|
||||
"mobx": "^6.3.0",
|
||||
"mobx-react": "^7.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alib/build-scripts": "^0.1.18",
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { runInAction } from 'mobx';
|
||||
import renderer from './renderer';
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
@ -5,10 +6,12 @@ if (typeof window !== 'undefined') {
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
(window as any).LCSimulatorHost = null;
|
||||
renderer.dispose?.();
|
||||
(window as any).SimulatorRenderer = null;
|
||||
(window as any).ReactDOM.unmountComponentAtNode(document.getElementById('app'));
|
||||
runInAction(() => {
|
||||
(window as any).LCSimulatorHost = null;
|
||||
renderer.dispose?.();
|
||||
(window as any).SimulatorRenderer = null;
|
||||
(window as any).ReactDOM.unmountComponentAtNode(document.getElementById('app'));
|
||||
});
|
||||
});
|
||||
|
||||
export default renderer;
|
||||
|
||||
@ -3,7 +3,7 @@ import { Router, Route, Switch } from 'react-router';
|
||||
import cn from 'classnames';
|
||||
import { Node } from '@ali/lowcode-designer';
|
||||
import LowCodeRenderer from '@ali/lowcode-react-renderer';
|
||||
import { observer } from '@recore/obx-react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { isFromVC, getClosestNode } from '@ali/lowcode-utils';
|
||||
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
|
||||
|
||||
@ -99,10 +99,6 @@ function getDeviceView(view: any, device: string, mode: string) {
|
||||
|
||||
@observer
|
||||
class Layout extends Component<{ rendererContainer: SimulatorRendererContainer }> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { rendererContainer, children } = this.props;
|
||||
const { layout } = rendererContainer;
|
||||
@ -133,10 +129,6 @@ class Renderer extends Component<{
|
||||
rendererContainer: SimulatorRendererContainer,
|
||||
documentInstance: DocumentInstance,
|
||||
}> {
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { documentInstance, rendererContainer: renderer } = this.props;
|
||||
const { container } = documentInstance;
|
||||
|
||||
@ -2,7 +2,7 @@ import React, { createElement, ReactInstance } from 'react';
|
||||
import { render as reactRender } from 'react-dom';
|
||||
import { host } from './host';
|
||||
import SimulatorRendererView from './renderer-view';
|
||||
import { computed, obx, untracked } from '@recore/obx';
|
||||
import { computed, observable as obx, untracked, makeObservable, configure } from 'mobx';
|
||||
import { getClientRects } from './utils/get-client-rects';
|
||||
import { reactFindDOMNodes, FIBER_KEY } from './utils/react-find-dom-nodes';
|
||||
import {
|
||||
@ -28,7 +28,10 @@ import Leaf from './builtin-components/leaf';
|
||||
import { withQueryParams, parseQuery } from './utils/url';
|
||||
import { supportsQuickPropSetting, getUppermostPropKey, setInstancesProp } from './utils/misc';
|
||||
const loader = new AssetLoader();
|
||||
const DELAY_THRESHOLD = 10;
|
||||
const FULL_RENDER_THRESHOLD = 500;
|
||||
configure({ enforceActions: 'never' });
|
||||
|
||||
export class DocumentInstance {
|
||||
public instancesMap = new Map<string, ReactInstance[]>();
|
||||
|
||||
@ -40,9 +43,18 @@ export class DocumentInstance {
|
||||
private disposeFunctions: Array<() => void> = [];
|
||||
|
||||
constructor(readonly container: SimulatorRendererContainer, readonly document: DocumentModel) {
|
||||
const documentExportDisposer = host.autorun(() => {
|
||||
this._schema = document.export(TransformStage.Render);
|
||||
});
|
||||
makeObservable(this);
|
||||
// 标识当前文档导出的状态,用来控制 reaction effect 是否执行
|
||||
let asleep = false;
|
||||
const setDocSchema = (value?: any) => {
|
||||
this._schema = value || document.export(TransformStage.Render);
|
||||
};
|
||||
const documentExportDisposer = host.reaction(() => {
|
||||
return document.export(TransformStage.Render);
|
||||
}, (value) => {
|
||||
if (asleep) return;
|
||||
setDocSchema(value);
|
||||
}, { delay: DELAY_THRESHOLD, fireImmediately: true });
|
||||
this.disposeFunctions.push(documentExportDisposer);
|
||||
let tid: NodeJS.Timeout;
|
||||
this.disposeFunctions.push(host.onActivityEvent((data: ActivityData, ctx: any) => {
|
||||
@ -53,7 +65,7 @@ export class DocumentInstance {
|
||||
|
||||
if (tid) clearTimeout(tid);
|
||||
// 临时关闭全量计算 schema 的逻辑,在增量计算结束后,来一次全量计算
|
||||
documentExportDisposer.$obx.sleep();
|
||||
asleep = true;
|
||||
if (data.type === ActivityType.MODIFIED) {
|
||||
// 对于修改场景,优先判断是否能走「快捷设置」逻辑
|
||||
if (supportsQuickPropSetting(data, this)) {
|
||||
@ -69,7 +81,10 @@ export class DocumentInstance {
|
||||
// FIXME: 待补充逻辑
|
||||
}
|
||||
|
||||
tid = setTimeout(() => documentExportDisposer.$obx.wakeup(true), FULL_RENDER_THRESHOLD);
|
||||
tid = setTimeout(() => {
|
||||
asleep = false;
|
||||
setDocSchema();
|
||||
}, FULL_RENDER_THRESHOLD);
|
||||
// TODO: 调试增量模式,打开以下代码
|
||||
// this._deltaData = data;
|
||||
// this._deltaMode = true;
|
||||
@ -246,6 +261,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
}
|
||||
|
||||
constructor() {
|
||||
makeObservable(this);
|
||||
this.autoRender = host.autoRender;
|
||||
|
||||
this.disposeFunctions.push(host.connect(this, () => {
|
||||
@ -272,7 +288,8 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
}));
|
||||
const documentInstanceMap = new Map<string, DocumentInstance>();
|
||||
let initialEntry = '/';
|
||||
this.disposeFunctions.push(host.autorun(({ firstRun }) => {
|
||||
let firstRun = true;
|
||||
this.disposeFunctions.push(host.autorun(() => {
|
||||
this._documentInstances = host.project.documents.map((doc) => {
|
||||
let inst = documentInstanceMap.get(doc.id);
|
||||
if (!inst) {
|
||||
@ -286,6 +303,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
|
||||
: '/';
|
||||
if (firstRun) {
|
||||
initialEntry = path;
|
||||
firstRun = false;
|
||||
} else if (this.history.location.pathname !== path) {
|
||||
this.history.replace(path);
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ interface ILiteralObject {
|
||||
}
|
||||
|
||||
export class Env {
|
||||
@obx.val envs: ILiteralObject = {};
|
||||
@obx.shallow envs: ILiteralObject = {};
|
||||
|
||||
private emitter: EventEmitter;
|
||||
|
||||
|
||||
@ -102,8 +102,8 @@ export class AccordionField extends VEField {
|
||||
constructor(props: IVEFieldProps) {
|
||||
super(props);
|
||||
this._generateClassNames(props);
|
||||
if (this.props.onExpandChange) {
|
||||
this.willDetach = this.props.onExpandChange(() => this.forceUpdate());
|
||||
if (props.onExpandChange) {
|
||||
this.willDetach = props.onExpandChange(() => this.forceUpdate());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ class DocItem {
|
||||
constructor(parent, doc, unInitial) {
|
||||
this.parent = parent;
|
||||
const { use, ...strings } = doc;
|
||||
this.doc = obx.val({
|
||||
this.doc = obx({
|
||||
type: 'i18n',
|
||||
...strings,
|
||||
});
|
||||
|
||||
@ -6,3 +6,4 @@ export * from './remove-empty-prop-reducer';
|
||||
export * from './style-reducer';
|
||||
export * from './upgrade-reducer';
|
||||
export * from './node-top-fixed-reducer';
|
||||
export * from './reset-loop-default-value-reducer';
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
// 讲loop=[]的情况处理成loop=false
|
||||
export function resetLoopDefaultValueReducer(props: any) {
|
||||
if (props.loop && Array.isArray(props.loop) && props.loop.length === 0) {
|
||||
return {
|
||||
...props,
|
||||
loop: undefined,
|
||||
};
|
||||
}
|
||||
return props;
|
||||
}
|
||||
@ -14,6 +14,7 @@ import {
|
||||
initNodeReducer,
|
||||
liveLifecycleReducer,
|
||||
nodeTopFixedReducer,
|
||||
resetLoopDefaultValueReducer,
|
||||
} from './props-reducers';
|
||||
|
||||
const { LiveEditing, TransformStage } = designerCabin;
|
||||
@ -57,3 +58,6 @@ designer.addPropsReducer(removeEmptyPropsReducer, TransformStage.Save);
|
||||
|
||||
designer.addPropsReducer(nodeTopFixedReducer, TransformStage.Render);
|
||||
designer.addPropsReducer(nodeTopFixedReducer, TransformStage.Save);
|
||||
|
||||
// loop的默认值处理
|
||||
designer.addPropsReducer(resetLoopDefaultValueReducer, TransformStage.Save);
|
||||
|
||||
@ -31,9 +31,9 @@
|
||||
// skip type checking of declaration files
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": "./packages",
|
||||
"useDefineForClassFields": true,
|
||||
"paths": {
|
||||
"@ali/lowcode-*": ["./*/src"],
|
||||
"@ali/visualengine": ["./vision-preset/src"]
|
||||
"@ali/lowcode-*": ["./*/src"]
|
||||
},
|
||||
"outDir": "lib"
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user