@ -1,5 +1,5 @@
import type { MouseEvent } from 'react'
import { useCallback , useRef } from 'react'
import { useCallback , useRef , useState } from 'react'
import { useTranslation } from 'react-i18next'
import produce from 'immer'
import type {
@ -61,6 +61,7 @@ import {
} from './use-workflow'
import { WorkflowHistoryEvent , useWorkflowHistory } from './use-workflow-history'
import useInspectVarsCrud from './use-inspect-vars-crud'
import { getNodeUsedVars } from '../nodes/_base/components/variable/utils'
export const useNodesInteractions = ( ) = > {
const { t } = useTranslation ( )
@ -1530,6 +1531,139 @@ export const useNodesInteractions = () => {
setNodes ( nodes )
} , [ redo , store , workflowHistoryStore , getNodesReadOnly , getWorkflowReadOnly ] )
const [ isDimming , setIsDimming ] = useState ( false )
/** 让除 nodeId 以外的节点都加上 opacity-30 */
const dimOtherNodes = useCallback ( ( ) = > {
if ( isDimming )
return
const { getNodes , setNodes , edges , setEdges } = store . getState ( )
const nodes = getNodes ( )
const selectedNode = nodes . find ( n = > n . data . selected )
if ( ! selectedNode )
return
setIsDimming ( true )
// const workflowNodes = useStore(s => s.getNodes())
const workflowNodes = nodes
const usedVars = getNodeUsedVars ( selectedNode )
const dependencyNodes : Node [ ] = [ ]
usedVars . forEach ( ( valueSelector ) = > {
const node = workflowNodes . find ( node = > node . id === valueSelector ? . [ 0 ] )
if ( node ) {
if ( ! dependencyNodes . includes ( node ) )
dependencyNodes . push ( node )
}
} )
const outgoers = getOutgoers ( selectedNode as Node , nodes as Node [ ] , edges )
for ( let currIdx = 0 ; currIdx < outgoers . length ; currIdx ++ ) {
const node = outgoers [ currIdx ]
const outgoersForNode = getOutgoers ( node , nodes as Node [ ] , edges )
outgoersForNode . forEach ( ( item ) = > {
const existed = outgoers . some ( v = > v . id === item . id )
if ( ! existed )
outgoers . push ( item )
} )
}
const dependentNodes : Node [ ] = [ ]
outgoers . forEach ( ( node ) = > {
const usedVars = getNodeUsedVars ( node )
const used = usedVars . some ( v = > v ? . [ 0 ] === selectedNode . id )
if ( used ) {
const existed = dependentNodes . some ( v = > v . id === node . id )
if ( ! existed )
dependentNodes . push ( node )
}
} )
const dimNodes = [ . . . dependencyNodes , . . . dependentNodes , selectedNode ]
const newNodes = produce ( nodes , ( draft ) = > {
console . log ( '==========selecteds: ' )
draft . forEach ( ( n ) = > {
const dimNode = dimNodes . find ( v = > v . id === n . id )
if ( ! dimNode )
n . data . _dimmed = true
} )
console . log ( '====================end of selecteds' )
} )
setNodes ( newNodes )
/* == ② 生成临时连线 == */
const tempEdges : Edge [ ] = [ ]
dependencyNodes . forEach ( ( n ) = > {
tempEdges . push ( {
id : ` tmp_ ${ n . id } -source- ${ selectedNode . id } -target ` ,
type : CUSTOM_EDGE , // 复用自定义 Edge, 也可以写一个 DIM_EDGE
source : n.id , // 依赖 → 选中
sourceHandle : 'source_tmp' ,
target : selectedNode.id ,
targetHandle : 'target_tmp' ,
animated : true ,
data : {
sourceType : n.data.type ,
targetType : selectedNode.data.type ,
_isTemp : true ,
_connectedNodeIsHovering : true ,
} ,
} )
} )
dependentNodes . forEach ( ( n ) = > {
tempEdges . push ( {
id : ` tmp_ ${ selectedNode . id } -source- ${ n . id } -target ` ,
type : CUSTOM_EDGE , // 复用自定义 Edge, 也可以写一个 DIM_EDGE
source : selectedNode.id , // 依赖 → 选中
sourceHandle : 'source_tmp' ,
target : n.id ,
targetHandle : 'target_tmp' ,
animated : true ,
data : {
sourceType : selectedNode.data.type ,
targetType : n.data.type ,
_isTemp : true ,
_connectedNodeIsHovering : true ,
} ,
} )
} )
const newEdges = produce ( edges , ( draft ) = > {
draft . forEach ( ( e ) = > {
e . data . _dimmed = true
} )
draft . push ( . . . tempEdges )
} )
setEdges ( newEdges )
} , [ isDimming , store ] )
/** 把所有节点恢复为不透明 */
const undimAllNodes = useCallback ( ( ) = > {
const { getNodes , setNodes , edges , setEdges } = store . getState ( )
const nodes = getNodes ( )
setIsDimming ( false )
const newNodes = produce ( nodes , ( draft ) = > {
draft . forEach ( ( n ) = > {
n . data . _dimmed = false
// handleNodeLeave(null as unknown as MouseEvent, n)
} )
} )
setNodes ( newNodes )
const newEdges = produce ( edges . filter ( e = > ! e . data . _isTemp ) , ( draft ) = > {
draft . forEach ( ( e ) = > {
e . data . _dimmed = false
} )
} )
setEdges ( newEdges )
} , [ store ] )
return {
handleNodeDragStart ,
handleNodeDrag ,
@ -1554,5 +1688,7 @@ export const useNodesInteractions = () => {
handleNodeDisconnect ,
handleHistoryBack ,
handleHistoryForward ,
dimOtherNodes ,
undimAllNodes ,
}
}