feat(select): only support shift key to trigger multi-select

This commit is contained in:
liuyangxing 2025-03-17 17:15:12 +08:00
parent dba6190e1a
commit 23fa16b80c
2 changed files with 24 additions and 23 deletions

View File

@ -57,7 +57,7 @@ export function useNodeRender(nodeFromProps?: WorkflowNodeEntity): NodeRenderRet
} }
isDragging.current = true; isDragging.current = true;
// 拖拽选中的节点 // 拖拽选中的节点
dragService.startDragSelectedNodes(e).finally(() => dragService.startDragSelectedNodes(e)?.finally(() =>
setTimeout(() => { setTimeout(() => {
isDragging.current = false; isDragging.current = false;
}) })
@ -75,7 +75,7 @@ export function useNodeRender(nodeFromProps?: WorkflowNodeEntity): NodeRenderRet
return; return;
} }
// 追加选择 // 追加选择
if (e.metaKey || e.shiftKey || e.ctrlKey) { if (e.shiftKey) {
selectionService.toggleSelect(node); selectionService.toggleSelect(node);
} else { } else {
selectionService.selectNode(node); selectionService.selectNode(node);

View File

@ -1,6 +1,17 @@
/* eslint-disable complexity */ /* eslint-disable complexity */
import { inject, injectable } from 'inversify'; import { inject, injectable } from 'inversify';
import { type IPoint } from '@flowgram.ai/utils';
import { SelectorBoxConfigEntity } from '@flowgram.ai/renderer'; import { SelectorBoxConfigEntity } from '@flowgram.ai/renderer';
import {
WorkflowDocument,
WorkflowDragService,
WorkflowHoverService,
WorkflowLineEntity,
WorkflowLinesManager,
WorkflowNodeEntity,
WorkflowSelectService,
} from '@flowgram.ai/free-layout-core';
import { WorkflowPortEntity } from '@flowgram.ai/free-layout-core';
import { FlowNodeTransformData } from '@flowgram.ai/document'; import { FlowNodeTransformData } from '@flowgram.ai/document';
import { import {
EditorState, EditorState,
@ -12,17 +23,6 @@ import {
observeEntityDatas, observeEntityDatas,
type LayerOptions, type LayerOptions,
} from '@flowgram.ai/core'; } from '@flowgram.ai/core';
import {
WorkflowDocument,
WorkflowDragService,
WorkflowHoverService,
WorkflowLineEntity,
WorkflowLinesManager,
WorkflowNodeEntity,
WorkflowSelectService,
} from '@flowgram.ai/free-layout-core';
import { WorkflowPortEntity } from '@flowgram.ai/free-layout-core';
import { type IPoint } from '@flowgram.ai/utils';
import { getSelectionBounds } from './selection-utils'; import { getSelectionBounds } from './selection-utils';
const PORT_BG_CLASS_NAME = 'workflow-port-bg'; const PORT_BG_CLASS_NAME = 'workflow-port-bg';
@ -79,9 +79,9 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
autorun(): void { autorun(): void {
const { activatedNode } = this.selectionService; const { activatedNode } = this.selectionService;
this.nodeTransformsWithSort = this.nodeTransforms this.nodeTransformsWithSort = this.nodeTransforms
.filter(n => n.entity.id !== 'root') .filter((n) => n.entity.id !== 'root')
.reverse() // 后创建的排在前面 .reverse() // 后创建的排在前面
.sort(n1 => (n1.entity === activatedNode ? -1 : 0)); .sort((n1) => (n1.entity === activatedNode ? -1 : 0));
} }
/** /**
@ -145,17 +145,18 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
const selectionBounds = getSelectionBounds( const selectionBounds = getSelectionBounds(
this.selectionService.selection, this.selectionService.selection,
// 这里只考虑多选模式,单选模式已经下沉到 use-node-render 中 // 这里只考虑多选模式,单选模式已经下沉到 use-node-render 中
true, true
); );
if (selectionBounds.width > 0 && selectionBounds.contains(mousePos.x, mousePos.y)) { if (selectionBounds.width > 0 && selectionBounds.contains(mousePos.x, mousePos.y)) {
/** /**
* *
*/ */
this.dragService.startDragSelectedNodes(e).then(dragSuccess => { this.dragService.startDragSelectedNodes(e)?.then((dragSuccess) => {
if (!dragSuccess) { if (!dragSuccess) {
// 拖拽没有成功触发了点击 // 拖拽没有成功触发了点击
if (hoveredNode && hoveredNode instanceof WorkflowNodeEntity) { if (hoveredNode && hoveredNode instanceof WorkflowNodeEntity) {
if (e.metaKey || e.shiftKey || e.ctrlKey) { // 追加选择
if (e.shiftKey) {
this.selectionService.toggleSelect(hoveredNode); this.selectionService.toggleSelect(hoveredNode);
} else { } else {
this.selectionService.selectNode(hoveredNode); this.selectionService.selectNode(hoveredNode);
@ -188,8 +189,8 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
const portHovered = this.linesManager.getPortFromMousePos(mousePos); const portHovered = this.linesManager.getPortFromMousePos(mousePos);
const lineDomNodes = this.playgroundNode.querySelectorAll(LINE_CLASS_NAME); const lineDomNodes = this.playgroundNode.querySelectorAll(LINE_CLASS_NAME);
const checkTargetFromLine = [...lineDomNodes].some(lineDom => const checkTargetFromLine = [...lineDomNodes].some((lineDom) =>
lineDom.contains(target as HTMLElement), lineDom.contains(target as HTMLElement)
); );
// 默认 只有 output 点位可以 hover // 默认 只有 output 点位可以 hover
if (portHovered) { if (portHovered) {
@ -212,13 +213,13 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
} }
const nodeHovered = nodeTransforms.find((trans: FlowNodeTransformData) => const nodeHovered = nodeTransforms.find((trans: FlowNodeTransformData) =>
trans.bounds.contains(mousePos.x, mousePos.y), trans.bounds.contains(mousePos.x, mousePos.y)
)?.entity as WorkflowNodeEntity; )?.entity as WorkflowNodeEntity;
// 判断当前鼠标位置所在元素是否在节点内部 // 判断当前鼠标位置所在元素是否在节点内部
const nodeDomNodes = this.playgroundNode.querySelectorAll(NODE_CLASS_NAME); const nodeDomNodes = this.playgroundNode.querySelectorAll(NODE_CLASS_NAME);
const checkTargetFromNode = [...nodeDomNodes].some(nodeDom => const checkTargetFromNode = [...nodeDomNodes].some((nodeDom) =>
nodeDom.contains(target as HTMLElement), nodeDom.contains(target as HTMLElement)
); );
if (nodeHovered || checkTargetFromNode) { if (nodeHovered || checkTargetFromNode) {