@@ -179,7 +180,19 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
matched = true;
}
return (
- } key={field.name}>
+ }
+ key={field.name}
+ onClick={
+ () => {
+ editor?.emit('skeleton.settingsPane.change', {
+ name: field.name,
+ title: field.title,
+ });
+ }
+ }
+ >
{(skeleton) => {
if (skeleton) {
diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts
index 3adf939a2..a893700f4 100644
--- a/packages/engine/src/engine-core.ts
+++ b/packages/engine/src/engine-core.ts
@@ -178,7 +178,6 @@ export async function init(container?: Element, options?: EngineOptions) {
}
}
engineContainer.id = 'engine';
-
engineConfig.setConfig(engineOptions as any);
await plugins.init();
diff --git a/packages/plugin-outline-pane/src/icons/index.ts b/packages/plugin-outline-pane/src/icons/index.ts
new file mode 100644
index 000000000..4681aeb29
--- /dev/null
+++ b/packages/plugin-outline-pane/src/icons/index.ts
@@ -0,0 +1,2 @@
+export * from './lock';
+export * from './unlock';
diff --git a/packages/plugin-outline-pane/src/tree-node.ts b/packages/plugin-outline-pane/src/tree-node.ts
index e021d6b65..75e715e92 100644
--- a/packages/plugin-outline-pane/src/tree-node.ts
+++ b/packages/plugin-outline-pane/src/tree-node.ts
@@ -12,6 +12,7 @@ export default class TreeNode {
* 是否可以展开
*/
@computed get expandable(): boolean {
+ if (this.locked) return false;
return this.hasChildren() || this.hasSlots() || this.dropDetail?.index != null;
}
@@ -86,14 +87,14 @@ export default class TreeNode {
}
@computed get locked(): boolean {
- return this.node.getExtraProp('locked', false)?.getValue() === true;
+ return this.node.getExtraProp('isLocked', false)?.getValue() === true;
}
setLocked(flag: boolean) {
if (flag) {
- this.node.getExtraProp('locked', true)?.setValue(true);
+ this.node.getExtraProp('isLocked', true)?.setValue(true);
} else {
- this.node.getExtraProp('locked', false)?.remove();
+ this.node.getExtraProp('isLocked', false)?.remove();
}
}
@@ -140,7 +141,7 @@ export default class TreeNode {
return this.node.componentMeta.icon;
}
- @computed get parent() {
+ @computed get parent(): TreeNode | null {
const { parent } = this.node;
if (parent) {
return this.tree.getTreeNode(parent);
diff --git a/packages/plugin-outline-pane/src/tree.ts b/packages/plugin-outline-pane/src/tree.ts
index a34bdfd21..d7cd77291 100644
--- a/packages/plugin-outline-pane/src/tree.ts
+++ b/packages/plugin-outline-pane/src/tree.ts
@@ -12,7 +12,9 @@ export class Tree {
constructor(document: DocumentModel) {
this.document = document;
- this.root = this.getTreeNode(document.rootNode);
+ if (document.rootNode) {
+ this.root = this.getTreeNode(document.rootNode);
+ }
this.id = document.id;
}
diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx
index 165b88534..ea48ae684 100644
--- a/packages/plugin-outline-pane/src/views/tree-title.tsx
+++ b/packages/plugin-outline-pane/src/views/tree-title.tsx
@@ -1,6 +1,8 @@
import { Component, KeyboardEvent, FocusEvent, Fragment } from 'react';
import classNames from 'classnames';
import { observer, Title, Tip, globalContext, Editor } from '@ali/lowcode-editor-core';
+import { createIcon } from '@ali/lowcode-utils';
+
import { IconArrowRight } from '../icons/arrow-right';
import { IconEyeClose } from '../icons/eye-close';
import { intl, intlNode } from '../locale';
@@ -10,7 +12,8 @@ import { IconCond } from '../icons/cond';
import { IconLoop } from '../icons/loop';
import { IconRadioActive } from '../icons/radio-active';
import { IconRadio } from '../icons/radio';
-import { createIcon } from '@ali/lowcode-utils';
+import { IconLock, IconUnlock } from '../icons';
+
function emitOutlineEvent(type: string, treeNode: TreeNode, rest?: Record) {
const editor = globalContext.get(Editor);
@@ -83,6 +86,7 @@ export default class TreeTitle extends Component<{
const isCNode = !treeNode.isRoot();
const { node } = treeNode;
const isNodeParent = node.isParental();
+ const isContainer = node.isContainer();
let style: any;
if (isCNode) {
const { depth } = treeNode;
@@ -164,34 +168,34 @@ export default class TreeTitle extends Component<{
)}
{isCNode && isNodeParent && !isModal &&
}
- {/* isCNode && isNodeParent &&
*/}
+ {isContainer && isCNode && isNodeParent &&
}
);
}
}
-// @observer
-// class LockBtn extends Component<{ treeNode: TreeNode }> {
-// shouldComponentUpdate() {
-// return false;
-// }
+@observer
+class LockBtn extends Component<{ treeNode: TreeNode }> {
+ shouldComponentUpdate() {
+ return false;
+ }
-// render() {
-// const { treeNode } = this.props;
-// return (
-// {
-// e.stopPropagation();
-// treeNode.setLocked(!treeNode.locked);
-// }}
-// >
-// {treeNode.locked ? : }
-// {treeNode.locked ? intl('Unlock') : intl('Lock')}
-//
-// );
-// }
-// }
+ render() {
+ const { treeNode } = this.props;
+ return (
+ {
+ e.stopPropagation();
+ treeNode.setLocked(!treeNode.locked);
+ }}
+ >
+ {treeNode.locked ? : }
+ {treeNode.locked ? intl('Unlock') : intl('Lock')}
+
+ );
+ }
+}
@observer
class HideBtn extends Component<{ treeNode: TreeNode }> {
@@ -217,6 +221,7 @@ class HideBtn extends Component<{ treeNode: TreeNode }> {
}
}
+
@observer
class ExpandBtn extends Component<{ treeNode: TreeNode }> {
shouldComponentUpdate() {
diff --git a/packages/react-simulator-renderer/src/renderer-view.tsx b/packages/react-simulator-renderer/src/renderer-view.tsx
index 2b46c40e3..cf8186120 100644
--- a/packages/react-simulator-renderer/src/renderer-view.tsx
+++ b/packages/react-simulator-renderer/src/renderer-view.tsx
@@ -1,10 +1,12 @@
+import { ReactInstance, Fragment, Component, createElement } from 'react';
+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 { ReactInstance, Fragment, Component, createElement } from 'react';
import { observer } from '@recore/obx-react';
-import { isFromVC } from '@ali/lowcode-utils';
+import { isFromVC, getClosestNode } from '@ali/lowcode-utils';
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
-import { Router, Route, Switch } from 'react-router';
+
import './renderer.less';
const DEFAULT_SIMULATOR_LOCALE = 'zh-CN';
@@ -171,9 +173,16 @@ class Renderer extends Component<{
(children == null || (Array.isArray(children) && !children.length)) &&
(!viewProps.style || Object.keys(viewProps.style).length === 0)
) {
+ let defaultPlaceholder = '拖拽组件或模板到这里';
+ const lockedNode = getClosestNode(leaf, (node) => {
+ return node?.getExtraProp('isLocked')?.getValue() === true;
+ });
+ if (lockedNode) {
+ defaultPlaceholder = '锁定元素及子元素无法编辑';
+ }
children = (
-
- {viewProps.placeholder || '拖拽组件或模板到这里'}
+
+ {viewProps.placeholder || defaultPlaceholder}
);
}
diff --git a/packages/react-simulator-renderer/src/renderer.less b/packages/react-simulator-renderer/src/renderer.less
index aed023f1b..8f0119353 100644
--- a/packages/react-simulator-renderer/src/renderer.less
+++ b/packages/react-simulator-renderer/src/renderer.less
@@ -65,6 +65,10 @@ html.engine-cursor-ew-resize, html.engine-cursor-ew-resize * {
align-items: center;
justify-content: center;
font-size: 14px;
+
+ &.lc-container-locked {
+ background: #eccfcf;
+ }
}
body.engine-document {
@@ -87,3 +91,5 @@ body.engine-document {
#app {
height: 100vh;
}
+
+
diff --git a/packages/types/src/schema.ts b/packages/types/src/schema.ts
index 21856bc57..85f8521bd 100644
--- a/packages/types/src/schema.ts
+++ b/packages/types/src/schema.ts
@@ -22,6 +22,7 @@ export interface NodeSchema {
loop?: CompositeValue; // 循环数据
loopArgs?: [string, string]; // 循环迭代对象、索引名称 ["item", "index"]
children?: NodeData | NodeData[]; // 子节点
+ isLocked?: boolean; // 是否锁定
// ------- future support -----
conditionGroup?: string;
diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts
index ca211fd36..c79c8ddb9 100644
--- a/packages/utils/src/index.ts
+++ b/packages/utils/src/index.ts
@@ -22,3 +22,4 @@ export * from './build-components';
export * from './appHelper';
export * from './misc';
export * from './schema';
+export * from './node-helper';
diff --git a/packages/utils/src/node-helper.ts b/packages/utils/src/node-helper.ts
new file mode 100644
index 000000000..0b6b768ff
--- /dev/null
+++ b/packages/utils/src/node-helper.ts
@@ -0,0 +1,14 @@
+// 仅使用类型
+import { Node } from '@ali/lowcode-designer';
+
+export const getClosestNode = (node: Node, until: (node: Node) => boolean): Node | undefined => {
+ if (!node) {
+ return undefined;
+ }
+ if (until(node)) {
+ return node;
+ } else {
+ // @ts-ignore
+ return getClosestNode(node.getParent(), until);
+ }
+};