diff --git a/packages/plugin-outline-pane/src/controllers/tree-node.ts b/packages/plugin-outline-pane/src/controllers/tree-node.ts index 92bf374d8..34d06fee0 100644 --- a/packages/plugin-outline-pane/src/controllers/tree-node.ts +++ b/packages/plugin-outline-pane/src/controllers/tree-node.ts @@ -178,7 +178,9 @@ export default class TreeNode { this.node.lock(flag); this.event.emit(EVENT_NAMES.lockedChanged, flag); } - + deleteNode(node: IPublicModelNode) { + node && node.remove(); + } onFilterResultChanged(fn: () => void): IPublicTypeDisposable { this.event.on(EVENT_NAMES.filterResultChanged, fn); return () => { diff --git a/packages/plugin-outline-pane/src/icons/delete.tsx b/packages/plugin-outline-pane/src/icons/delete.tsx new file mode 100644 index 000000000..1f9360019 --- /dev/null +++ b/packages/plugin-outline-pane/src/icons/delete.tsx @@ -0,0 +1,11 @@ +import { SVGIcon, IconProps } from '@alilc/lowcode-utils'; + +export function IconDelete(props: IconProps) { + return ( + + + + ); +} + +IconDelete.displayName = 'IconDelete'; diff --git a/packages/plugin-outline-pane/src/icons/index.ts b/packages/plugin-outline-pane/src/icons/index.ts index ad9025081..d28f61dd2 100644 --- a/packages/plugin-outline-pane/src/icons/index.ts +++ b/packages/plugin-outline-pane/src/icons/index.ts @@ -9,3 +9,4 @@ export * from './loop'; export * from './radio-active'; export * from './radio'; export * from './setting'; +export * from './delete'; diff --git a/packages/plugin-outline-pane/src/locale/en-US.json b/packages/plugin-outline-pane/src/locale/en-US.json index b0f3d3e4a..9ade9e66f 100644 --- a/packages/plugin-outline-pane/src/locale/en-US.json +++ b/packages/plugin-outline-pane/src/locale/en-US.json @@ -18,5 +18,6 @@ "Locked": "Locked", "Hidden": "Hidden", "Modal View": "Modal View", - "Rename": "Rename" + "Rename": "Rename", + "Delete": "Delete" } diff --git a/packages/plugin-outline-pane/src/locale/zh-CN.json b/packages/plugin-outline-pane/src/locale/zh-CN.json index 8036688f2..9070d1771 100644 --- a/packages/plugin-outline-pane/src/locale/zh-CN.json +++ b/packages/plugin-outline-pane/src/locale/zh-CN.json @@ -18,5 +18,6 @@ "Locked": "已锁定", "Hidden": "已隐藏", "Modal View": "模态视图层", - "Rename": "重命名" + "Rename": "重命名", + "Delete": "删除" } diff --git a/packages/plugin-outline-pane/src/views/style.less b/packages/plugin-outline-pane/src/views/style.less index f343fba17..254b639d6 100644 --- a/packages/plugin-outline-pane/src/views/style.less +++ b/packages/plugin-outline-pane/src/views/style.less @@ -51,6 +51,7 @@ overflow: hidden; margin-bottom: @treeNodeHeight; user-select: none; + overflow-x: scroll; .tree-node-modal { margin: 5px; @@ -80,7 +81,8 @@ } } - .tree-node-modal-radio, .tree-node-modal-radio-active { + .tree-node-modal-radio, + .tree-node-modal-radio-active { margin-right: 4px; opacity: 0.8; position: absolute; @@ -139,7 +141,7 @@ content: ' '; z-index: 2; } - >.condition-group-title { + > .condition-group-title { text-align: center; background-color: #7b605b; height: 14px; @@ -167,7 +169,7 @@ content: ' '; z-index: 2; } - >.tree-node-slots-title { + > .tree-node-slots-title { text-align: center; background-color: rgb(144, 94, 190); height: 14px; @@ -183,7 +185,7 @@ &.insertion-at-slots { padding-bottom: @treeNodeHeight; border-bottom-color: rgb(182, 55, 55); - >.tree-node-slots-title { + > .tree-node-slots-title { background-color: rgb(182, 55, 55); } &::before { @@ -279,7 +281,10 @@ } } - .tree-node-hide-btn, .tree-node-lock-btn, .tree-node-rename-btn { + .tree-node-hide-btn, + .tree-node-lock-btn, + .tree-node-rename-btn, + .tree-node-delete-btn { opacity: 0; color: var(--color-text); line-height: 0; @@ -293,18 +298,26 @@ } } &:hover { - .tree-node-hide-btn, .tree-node-lock-btn, .tree-node-rename-btn { + .tree-node-hide-btn, + .tree-node-lock-btn, + .tree-node-rename-btn, + .tree-node-delete-btn { opacity: 0.5; } } html.lc-cursor-dragging & { // FIXME: only hide hover shows - .tree-node-hide-btn, .tree-node-lock-btn, .tree-node-rename-btn { + .tree-node-hide-btn, + .tree-node-lock-btn, + .tree-node-rename-btn { display: none; } } &.editing { - & > .tree-node-hide-btn, & >.tree-node-lock-btn, & >.tree-node-rename-btn { + & > .tree-node-hide-btn, + & > .tree-node-lock-btn, + & > .tree-node-rename-btn, + & > .tree-node-delete-btn { display: none; } } @@ -381,7 +394,8 @@ opacity: 0.8; } .tree-node-branches { - .tree-node-lock-btn, .tree-node-hide-btn { + .tree-node-lock-btn, + .tree-node-hide-btn { opacity: 0; } } diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 6686ea3cf..02ac94ae6 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import { createIcon } from '@alilc/lowcode-utils'; import { IPublicApiEvent } from '@alilc/lowcode-types'; import TreeNode from '../controllers/tree-node'; -import { IconLock, IconUnlock, IconArrowRight, IconEyeClose, IconEye, IconCond, IconLoop, IconRadioActive, IconRadio, IconSetting } from '../icons'; +import { IconLock, IconUnlock, IconArrowRight, IconEyeClose, IconEye, IconCond, IconLoop, IconRadioActive, IconRadio, IconSetting, IconDelete } from '../icons'; function emitOutlineEvent(event: IPublicApiEvent, type: string, treeNode: TreeNode, rest?: Record) { const node = treeNode?.node; @@ -100,7 +100,11 @@ export default class TreeTitle extends PureComponent<{ }); }); } - + deleteClick = () => { + const { treeNode } = this.props; + const { node } = treeNode; + treeNode.deleteNode(node); + }; render() { const { treeNode, isModal } = this.props; const { pluginContext } = treeNode; @@ -131,6 +135,7 @@ export default class TreeTitle extends PureComponent<{ const shouldShowHideBtn = isCNode && isNodeParent && !isModal && couldHide; const shouldShowLockBtn = config.get('enableCanvasLock', false) && isContainer && isCNode && isNodeParent && ((couldLock && !node.isLocked) || (couldUnlock && node.isLocked)); const shouldEditBtn = isCNode && isNodeParent; + const shouldDeleteBtn = isCNode && isNodeParent && node?.canPerformAction('remove'); return (
{shouldShowHideBtn &&
+ ); + } +} +class DeleteBtn extends PureComponent<{ + treeNode: TreeNode; + onClick: () => void; +}> { + render() { + const { intl, common } = this.props.treeNode.pluginContext; + const { Tip } = common.editorCabin; + return ( +
+ + {/* @ts-ignore */} + {intl('Delete')}
); } @@ -297,7 +322,6 @@ class ExpandBtn extends PureComponent<{ expanded: boolean; expandable: boolean; }> { - render() { const { treeNode, expanded, expandable } = this.props; if (!expandable) {