Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 新增选中节点指定属性tab功能 #2542

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/designer/src/designer/designer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ export class Designer implements IDesigner {
this.selectionDispose = currentSelection.onSelectionChange(() => {
this.postEvent('selection.change', currentSelection);
});

currentSelection.onSelectionPropsTabChange((tabKey) => {
this.postEvent('selection.changePropsTab', currentSelection, tabKey);
});
}
};

Expand Down
15 changes: 15 additions & 0 deletions packages/designer/src/document/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ export class Selection implements ISelection {
this.emitter.emit('selectionchange', this._selected);
}

/**
* 选中元素属性的指定tab
* @param tabKey
*/
selectPropsTab(tabKey: string) {
this.emitter.emit('selectionPropsTabChange', tabKey);
}

/**
* 批量选中
*/
Expand Down Expand Up @@ -187,4 +195,11 @@ export class Selection implements ISelection {
this.emitter.removeListener('selectionchange', fn);
};
}

onSelectionPropsTabChange(fn: (tabKey: string) => void): () => void {
this.emitter.on('selectionPropsTabChange', fn);
return () => {
this.emitter.removeListener('selectionPropsTabChange', fn);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
this._activeKey = null;
}
});

editor.eventBus.on('designer.selection.changePropsTab', (selection, tabKey) => {
this._activeKey = tabKey;
});
}

async setShouldIgnoreRoot() {
Expand Down
21 changes: 12 additions & 9 deletions packages/plugin-outline-pane/src/views/tree-branches.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PureComponent } from 'react';
import { MouseEvent as ReactMouseEvent, PureComponent } from 'react';
import classNames from 'classnames';
import TreeNode from '../controllers/tree-node';
import TreeNodeView from './tree-node';
Expand All @@ -9,6 +9,7 @@ export default class TreeBranches extends PureComponent<{
isModal?: boolean;
expanded: boolean;
treeChildren: TreeNode[] | null;
treeNodeClick?: (e: ReactMouseEvent, type?: string) => void;
}> {
state = {
filterWorking: false,
Expand Down Expand Up @@ -38,24 +39,24 @@ export default class TreeBranches extends PureComponent<{
}

render() {
const { treeNode, isModal, expanded } = this.props;
const { treeNode, isModal, expanded, treeNodeClick } = this.props;
const { filterWorking, matchChild } = this.state;
// 条件过滤生效时,如果命中了子节点,需要将该节点展开
const expandInFilterResult = filterWorking && matchChild;

if (!expandInFilterResult && !expanded) {
return null;
}

return (
<div className="tree-node-branches">
{
!isModal && <TreeNodeSlots treeNode={treeNode} />
!isModal && <TreeNodeSlots treeNode={treeNode} treeNodeClick={treeNodeClick} />
}
<TreeNodeChildren
treeNode={treeNode}
isModal={isModal || false}
treeChildren={this.props.treeChildren}
treeNodeClick={treeNodeClick}
/>
</div>
);
Expand All @@ -72,6 +73,7 @@ class TreeNodeChildren extends PureComponent<{
treeNode: TreeNode;
isModal?: boolean;
treeChildren: TreeNode[] | null;
treeNodeClick?: (e: ReactMouseEvent, type?: string) => void;
}, ITreeNodeChildrenState> {
state: ITreeNodeChildrenState = {
filterWorking: false,
Expand Down Expand Up @@ -114,7 +116,7 @@ class TreeNodeChildren extends PureComponent<{
}

render() {
const { isModal } = this.props;
const { isModal, treeNodeClick } = this.props;
const children: any = [];
let groupContents: any[] = [];
let currentGrp: IPublicModelExclusiveGroup;
Expand Down Expand Up @@ -169,12 +171,12 @@ class TreeNodeChildren extends PureComponent<{
children.push(insertion);
}
}
groupContents.push(<TreeNodeView key={child.nodeId} treeNode={child} isModal={isModal} />);
groupContents.push(<TreeNodeView key={child.nodeId} treeNode={child} isModal={isModal} treeNodeClick={treeNodeClick} />);
} else {
if (index === dropIndex) {
children.push(insertion);
}
children.push(<TreeNodeView key={child.nodeId} treeNode={child} isModal={isModal} />);
children.push(<TreeNodeView key={child.nodeId} treeNode={child} isModal={isModal} treeNodeClick={treeNodeClick} />);
}
});
endGroup();
Expand All @@ -189,9 +191,10 @@ class TreeNodeChildren extends PureComponent<{

class TreeNodeSlots extends PureComponent<{
treeNode: TreeNode;
treeNodeClick?: (e: ReactMouseEvent, type?: string) => void;
}> {
render() {
const { treeNode } = this.props;
const { treeNode, treeNodeClick } = this.props;
if (!treeNode.hasSlots()) {
return null;
}
Expand All @@ -208,7 +211,7 @@ class TreeNodeSlots extends PureComponent<{
<Title title={{ type: 'i18n', intl: this.props.treeNode.pluginContext.intlNode('Slots') }} />
</div>
{treeNode.slots.map(tnode => (
<TreeNodeView key={tnode.nodeId} treeNode={tnode} />
<TreeNodeView key={tnode.nodeId} treeNode={tnode} treeNodeClick={treeNodeClick} />
))}
</div>
);
Expand Down
11 changes: 9 additions & 2 deletions packages/plugin-outline-pane/src/views/tree-node.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PureComponent } from 'react';
import { MouseEvent as ReactMouseEvent, PureComponent } from 'react';
import classNames from 'classnames';
import TreeNode from '../controllers/tree-node';
import TreeTitle from './tree-title';
Expand All @@ -9,6 +9,7 @@ import { IOutlinePanelPluginContext } from '../controllers/tree-master';

class ModalTreeNodeView extends PureComponent<{
treeNode: TreeNode;
treeNodeClick?: (e: ReactMouseEvent, type?: string) => void;
}, {
treeChildren: TreeNode[] | null;
}> {
Expand Down Expand Up @@ -55,6 +56,7 @@ class ModalTreeNodeView extends PureComponent<{
render() {
const rootTreeNode = this.rootTreeNode;
const { expanded } = rootTreeNode;
const { treeNodeClick } = this.props;

const hasVisibleModalNode = !!this.modalNodesManager?.getVisibleModalNode();
return (
Expand All @@ -74,6 +76,7 @@ class ModalTreeNodeView extends PureComponent<{
treeChildren={this.state.treeChildren}
expanded={expanded}
isModal
treeNodeClick={treeNodeClick}
/>
</div>
</div>
Expand All @@ -85,6 +88,7 @@ export default class TreeNodeView extends PureComponent<{
treeNode: TreeNode;
isModal?: boolean;
isRootNode?: boolean;
treeNodeClick?: (e: ReactMouseEvent, type?: string) => void;
}> {
state: {
expanded: boolean;
Expand Down Expand Up @@ -195,7 +199,7 @@ export default class TreeNodeView extends PureComponent<{
}

render() {
const { treeNode, isModal, isRootNode } = this.props;
const { treeNode, isModal, isRootNode, treeNodeClick } = this.props;
const className = classNames('tree-node', {
// 是否展开
expanded: this.state.expanded,
Expand Down Expand Up @@ -234,17 +238,20 @@ export default class TreeNodeView extends PureComponent<{
hidden={this.state.hidden}
locked={this.state.locked}
expandable={this.state.expandable}
treeNodeClick={treeNodeClick}
/>
{shouldShowModalTreeNode &&
<ModalTreeNodeView
treeNode={treeNode}
treeNodeClick={treeNodeClick}
/>
}
<TreeBranches
treeNode={treeNode}
isModal={false}
expanded={this.state.expanded}
treeChildren={this.state.treeChildren}
treeNodeClick={treeNodeClick}
/>
</div>
);
Expand Down
14 changes: 11 additions & 3 deletions packages/plugin-outline-pane/src/views/tree-title.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KeyboardEvent, FocusEvent, Fragment, PureComponent } from 'react';
import { MouseEvent as ReactMouseEvent, KeyboardEvent, FocusEvent, Fragment, PureComponent } from 'react';
import classNames from 'classnames';
import { createIcon } from '@alilc/lowcode-utils';
import { IPublicApiEvent } from '@alilc/lowcode-types';
Expand All @@ -23,6 +23,7 @@ export default class TreeTitle extends PureComponent<{
hidden: boolean;
locked: boolean;
expandable: boolean;
treeNodeClick: (e: ReactMouseEvent, type?: string) => void;
}> {
state: {
editing: boolean;
Expand Down Expand Up @@ -106,6 +107,13 @@ export default class TreeTitle extends PureComponent<{
const { node } = treeNode;
treeNode.deleteNode(node);
};

treeTitleClick = (e: any, type: string) => {
const { treeNodeClick } = this.props;
treeNodeClick?.(e, type);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

treeNodeClick 可以放到 treeNode 里面,不用多个组件进行透传。

e.stopPropagation();
};

render() {
const { treeNode, isModal } = this.props;
const { pluginContext } = treeNode;
Expand Down Expand Up @@ -200,15 +208,15 @@ export default class TreeTitle extends PureComponent<{
</a>
)}
{node.hasLoop() && (
<a className="tree-node-tag loop">
<a className="tree-node-tag loop" onClick={(e) => { this.treeTitleClick(e, 'loop'); }}>
{/* todo: click todo something */}
<IconLoop />
{/* @ts-ignore */}
<Tip>{intlNode('Loop')}</Tip>
</a>
)}
{this.state.condition && (
<a className="tree-node-tag cond">
<a className="tree-node-tag cond" onClick={(e) => { this.treeTitleClick(e, 'condition'); }}>
{/* todo: click todo something */}
<IconCond />
{/* @ts-ignore */}
Expand Down
9 changes: 8 additions & 1 deletion packages/plugin-outline-pane/src/views/tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default class TreeView extends PureComponent<{
detecting?.capture(node as any);
}

private onClick = (e: ReactMouseEvent) => {
private onClick = (e: ReactMouseEvent, type?: string) => {
if (this.ignoreUpSelected) {
this.boostEvent = undefined;
return;
Expand Down Expand Up @@ -76,6 +76,12 @@ export default class TreeView extends PureComponent<{
}
} else {
selection?.select(id);
let tabKey;
// 点击条件渲染和循环图标,默认选中属性的高级面板
if (type === 'condition' || type === 'loop') {
tabKey = '#advanced';
}
tabKey && selection?.selectPropsTab(tabKey);
const selectedNode = selection?.getNodes()?.[0];
const npm = selectedNode?.componentMeta?.npm;
const selected =
Expand Down Expand Up @@ -213,6 +219,7 @@ export default class TreeView extends PureComponent<{
key={this.state.root?.id}
treeNode={this.state.root}
isRootNode
treeNodeClick={this.onClick}
/>
</div>
);
Expand Down
13 changes: 13 additions & 0 deletions packages/shell/src/model/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ export class Selection implements IPublicModelSelection {
this[selectionSymbol].select(id);
}

/**
* 选中指定属性Tab
* select tab of props with tabKey
* @param tabKey
*/
selectPropsTab(tabKey: string): void {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs/docs/api/model/selection.md

需要在这里补充一下 API 文档

this[selectionSymbol].selectPropsTab(tabKey);
}

/**
* 批量选中指定节点们
* @param ids
Expand Down Expand Up @@ -115,4 +124,8 @@ export class Selection implements IPublicModelSelection {
onSelectionChange(fn: (ids: string[]) => void): IPublicTypeDisposable {
return this[selectionSymbol].onSelectionChange(fn);
}

onSelectionPropsTabChange(fn: (tabKey: string) => void): IPublicTypeDisposable {
return this[selectionSymbol].onSelectionPropsTabChange(fn);
}
}
14 changes: 14 additions & 0 deletions packages/types/src/shell/model/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export interface IPublicModelSelection<
*/
select(id: string): void;

/**
* 选中指定属性Tab
* select tab of props with tabKey
* @param tabKey
*/
selectPropsTab(tabKey: string): void;

/**
* 批量选中指定节点们
* select node with ids, this will override current selection
Expand Down Expand Up @@ -82,4 +89,11 @@ export interface IPublicModelSelection<
* @since v1.1.0
*/
onSelectionChange(fn: (ids: string[]) => void): IPublicTypeDisposable;

/**
* 注册 selection 选中属性tab的事件回调
* set callback which will be called when selection is changed
* @since v1.1.0
*/
onSelectionPropsTabChange(fn: (tabKey: string) => void): IPublicTypeDisposable;
}
Loading