mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-13 12:13:10 +00:00
feat: outline-plugin-pane support overflow-x scroll & delete node (#2376)
This commit is contained in:
parent
4128654347
commit
15f5675ddd
@ -178,7 +178,9 @@ export default class TreeNode {
|
|||||||
this.node.lock(flag);
|
this.node.lock(flag);
|
||||||
this.event.emit(EVENT_NAMES.lockedChanged, flag);
|
this.event.emit(EVENT_NAMES.lockedChanged, flag);
|
||||||
}
|
}
|
||||||
|
deleteNode(node: IPublicModelNode) {
|
||||||
|
node && node.remove();
|
||||||
|
}
|
||||||
onFilterResultChanged(fn: () => void): IPublicTypeDisposable {
|
onFilterResultChanged(fn: () => void): IPublicTypeDisposable {
|
||||||
this.event.on(EVENT_NAMES.filterResultChanged, fn);
|
this.event.on(EVENT_NAMES.filterResultChanged, fn);
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
11
packages/plugin-outline-pane/src/icons/delete.tsx
Normal file
11
packages/plugin-outline-pane/src/icons/delete.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { SVGIcon, IconProps } from '@alilc/lowcode-utils';
|
||||||
|
|
||||||
|
export function IconDelete(props: IconProps) {
|
||||||
|
return (
|
||||||
|
<SVGIcon viewBox="0 0 1024 1024" {...props}>
|
||||||
|
<path d="M224 256v639.84A64 64 0 0 0 287.84 960h448.32A64 64 0 0 0 800 895.84V256h64a32 32 0 1 0 0-64H160a32 32 0 1 0 0 64h64zM384 96c0-17.664 14.496-32 31.904-32h192.192C625.696 64 640 78.208 640 96c0 17.664-14.496 32-31.904 32H415.904A31.872 31.872 0 0 1 384 96z m-96 191.744C288 270.208 302.4 256 320.224 256h383.552C721.6 256 736 270.56 736 287.744v576.512C736 881.792 721.6 896 703.776 896H320.224A32.224 32.224 0 0 1 288 864.256V287.744zM352 352c0-17.696 14.208-32.032 32-32.032 17.664 0 32 14.24 32 32v448c0 17.664-14.208 32-32 32-17.664 0-32-14.24-32-32V352z m128 0c0-17.696 14.208-32.032 32-32.032 17.664 0 32 14.24 32 32v448c0 17.664-14.208 32-32 32-17.664 0-32-14.24-32-32V352z m128 0c0-17.696 14.208-32.032 32-32.032 17.664 0 32 14.24 32 32v448c0 17.664-14.208 32-32 32-17.664 0-32-14.24-32-32V352z" />
|
||||||
|
</SVGIcon>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IconDelete.displayName = 'IconDelete';
|
||||||
@ -9,3 +9,4 @@ export * from './loop';
|
|||||||
export * from './radio-active';
|
export * from './radio-active';
|
||||||
export * from './radio';
|
export * from './radio';
|
||||||
export * from './setting';
|
export * from './setting';
|
||||||
|
export * from './delete';
|
||||||
|
|||||||
@ -18,5 +18,6 @@
|
|||||||
"Locked": "Locked",
|
"Locked": "Locked",
|
||||||
"Hidden": "Hidden",
|
"Hidden": "Hidden",
|
||||||
"Modal View": "Modal View",
|
"Modal View": "Modal View",
|
||||||
"Rename": "Rename"
|
"Rename": "Rename",
|
||||||
|
"Delete": "Delete"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,5 +18,6 @@
|
|||||||
"Locked": "已锁定",
|
"Locked": "已锁定",
|
||||||
"Hidden": "已隐藏",
|
"Hidden": "已隐藏",
|
||||||
"Modal View": "模态视图层",
|
"Modal View": "模态视图层",
|
||||||
"Rename": "重命名"
|
"Rename": "重命名",
|
||||||
|
"Delete": "删除"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-bottom: @treeNodeHeight;
|
margin-bottom: @treeNodeHeight;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
overflow-x: scroll;
|
||||||
|
|
||||||
.tree-node-modal {
|
.tree-node-modal {
|
||||||
margin: 5px;
|
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;
|
margin-right: 4px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -139,7 +141,7 @@
|
|||||||
content: ' ';
|
content: ' ';
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
>.condition-group-title {
|
> .condition-group-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #7b605b;
|
background-color: #7b605b;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
@ -167,7 +169,7 @@
|
|||||||
content: ' ';
|
content: ' ';
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
>.tree-node-slots-title {
|
> .tree-node-slots-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: rgb(144, 94, 190);
|
background-color: rgb(144, 94, 190);
|
||||||
height: 14px;
|
height: 14px;
|
||||||
@ -183,7 +185,7 @@
|
|||||||
&.insertion-at-slots {
|
&.insertion-at-slots {
|
||||||
padding-bottom: @treeNodeHeight;
|
padding-bottom: @treeNodeHeight;
|
||||||
border-bottom-color: rgb(182, 55, 55);
|
border-bottom-color: rgb(182, 55, 55);
|
||||||
>.tree-node-slots-title {
|
> .tree-node-slots-title {
|
||||||
background-color: rgb(182, 55, 55);
|
background-color: rgb(182, 55, 55);
|
||||||
}
|
}
|
||||||
&::before {
|
&::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;
|
opacity: 0;
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
@ -293,18 +298,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:hover {
|
&: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;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
html.lc-cursor-dragging & {
|
html.lc-cursor-dragging & {
|
||||||
// FIXME: only hide hover shows
|
// 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;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.editing {
|
&.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;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,7 +394,8 @@
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
.tree-node-branches {
|
.tree-node-branches {
|
||||||
.tree-node-lock-btn, .tree-node-hide-btn {
|
.tree-node-lock-btn,
|
||||||
|
.tree-node-hide-btn {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import classNames from 'classnames';
|
|||||||
import { createIcon } from '@alilc/lowcode-utils';
|
import { createIcon } from '@alilc/lowcode-utils';
|
||||||
import { IPublicApiEvent } from '@alilc/lowcode-types';
|
import { IPublicApiEvent } from '@alilc/lowcode-types';
|
||||||
import TreeNode from '../controllers/tree-node';
|
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<string, unknown>) {
|
function emitOutlineEvent(event: IPublicApiEvent, type: string, treeNode: TreeNode, rest?: Record<string, unknown>) {
|
||||||
const node = treeNode?.node;
|
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() {
|
render() {
|
||||||
const { treeNode, isModal } = this.props;
|
const { treeNode, isModal } = this.props;
|
||||||
const { pluginContext } = treeNode;
|
const { pluginContext } = treeNode;
|
||||||
@ -131,6 +135,7 @@ export default class TreeTitle extends PureComponent<{
|
|||||||
const shouldShowHideBtn = isCNode && isNodeParent && !isModal && couldHide;
|
const shouldShowHideBtn = isCNode && isNodeParent && !isModal && couldHide;
|
||||||
const shouldShowLockBtn = config.get('enableCanvasLock', false) && isContainer && isCNode && isNodeParent && ((couldLock && !node.isLocked) || (couldUnlock && node.isLocked));
|
const shouldShowLockBtn = config.get('enableCanvasLock', false) && isContainer && isCNode && isNodeParent && ((couldLock && !node.isLocked) || (couldUnlock && node.isLocked));
|
||||||
const shouldEditBtn = isCNode && isNodeParent;
|
const shouldEditBtn = isCNode && isNodeParent;
|
||||||
|
const shouldDeleteBtn = isCNode && isNodeParent && node?.canPerformAction('remove');
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames('tree-node-title', { editing })}
|
className={classNames('tree-node-title', { editing })}
|
||||||
@ -214,8 +219,28 @@ export default class TreeTitle extends PureComponent<{
|
|||||||
</div>
|
</div>
|
||||||
{shouldShowHideBtn && <HideBtn hidden={this.props.hidden} treeNode={treeNode} />}
|
{shouldShowHideBtn && <HideBtn hidden={this.props.hidden} treeNode={treeNode} />}
|
||||||
{shouldShowLockBtn && <LockBtn locked={this.props.locked} treeNode={treeNode} />}
|
{shouldShowLockBtn && <LockBtn locked={this.props.locked} treeNode={treeNode} />}
|
||||||
{shouldEditBtn && <RenameBtn treeNode={treeNode} onClick={this.enableEdit} /> }
|
{shouldEditBtn && <RenameBtn treeNode={treeNode} onClick={this.enableEdit} />}
|
||||||
|
{shouldDeleteBtn && <DeleteBtn treeNode={treeNode} onClick={this.deleteClick} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeleteBtn extends PureComponent<{
|
||||||
|
treeNode: TreeNode;
|
||||||
|
onClick: () => void;
|
||||||
|
}> {
|
||||||
|
render() {
|
||||||
|
const { intl, common } = this.props.treeNode.pluginContext;
|
||||||
|
const { Tip } = common.editorCabin;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="tree-node-delete-btn"
|
||||||
|
onClick={this.props.onClick}
|
||||||
|
>
|
||||||
|
<IconDelete />
|
||||||
|
{/* @ts-ignore */}
|
||||||
|
<Tip>{intl('Delete')}</Tip>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -297,7 +322,6 @@ class ExpandBtn extends PureComponent<{
|
|||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
expandable: boolean;
|
expandable: boolean;
|
||||||
}> {
|
}> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { treeNode, expanded, expandable } = this.props;
|
const { treeNode, expanded, expandable } = this.props;
|
||||||
if (!expandable) {
|
if (!expandable) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user