feat: parallel hover

This commit is contained in:
StyleZhang 2024-08-26 16:09:22 +08:00
parent 6c61776ee1
commit 1016db160e
6 changed files with 32 additions and 4 deletions

View File

@ -12,6 +12,7 @@ import type {
} from 'reactflow' } from 'reactflow'
import { import {
getConnectedEdges, getConnectedEdges,
getIncomers,
getOutgoers, getOutgoers,
useReactFlow, useReactFlow,
useStoreApi, useStoreApi,
@ -207,6 +208,20 @@ export const useNodesInteractions = () => {
}) })
}) })
setEdges(newEdges) setEdges(newEdges)
const incomesNodes = getIncomers(node, nodes, edges)
if (incomesNodes.length) {
const incomesNodesOutgoersId = incomesNodes.map(incomeNode => getOutgoers(incomeNode, nodes, edges)).flat().map(outgoer => outgoer.id)
if (incomesNodesOutgoersId.length > 1) {
const newNodes = produce(nodes, (draft) => {
draft.forEach((n) => {
if (incomesNodesOutgoersId.includes(n.id))
n.data._inParallelHovering = true
})
})
setNodes(newNodes)
}
}
}, [store, workflowStore, getNodesReadOnly]) }, [store, workflowStore, getNodesReadOnly])
const handleNodeLeave = useCallback<NodeMouseHandler>((_, node) => { const handleNodeLeave = useCallback<NodeMouseHandler>((_, node) => {
@ -229,6 +244,7 @@ export const useNodesInteractions = () => {
const newNodes = produce(getNodes(), (draft) => { const newNodes = produce(getNodes(), (draft) => {
draft.forEach((node) => { draft.forEach((node) => {
node.data._isEntering = false node.data._isEntering = false
node.data._inParallelHovering = false
}) })
}) })
setNodes(newNodes) setNodes(newNodes)

View File

@ -125,9 +125,8 @@ export const NodeSourceHandle = memo(({
}, []) }, [])
const handleHandleClick = useCallback((e: MouseEvent) => { const handleHandleClick = useCallback((e: MouseEvent) => {
e.stopPropagation() e.stopPropagation()
if (!connected) setOpen(v => !v)
setOpen(v => !v) }, [])
}, [connected])
const handleSelect = useCallback((type: BlockEnum, toolDefaultValue?: ToolDefaultValue) => { const handleSelect = useCallback((type: BlockEnum, toolDefaultValue?: ToolDefaultValue) => {
handleNodeAdd( handleNodeAdd(
{ {
@ -163,7 +162,7 @@ export const NodeSourceHandle = memo(({
onClick={handleHandleClick} onClick={handleHandleClick}
> >
{ {
!connected && isConnectable && !getNodesReadOnly() && ( isConnectable && !getNodesReadOnly() && (
<BlockSelector <BlockSelector
open={open} open={open}
onOpenChange={handleOpenChange} onOpenChange={handleOpenChange}

View File

@ -14,6 +14,7 @@ import {
RiErrorWarningLine, RiErrorWarningLine,
RiLoader2Line, RiLoader2Line,
} from '@remixicon/react' } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import type { NodeProps } from '../../types' import type { NodeProps } from '../../types'
import { import {
BlockEnum, BlockEnum,
@ -43,6 +44,7 @@ const BaseNode: FC<BaseNodeProps> = ({
data, data,
children, children,
}) => { }) => {
const { t } = useTranslation()
const nodeRef = useRef<HTMLDivElement>(null) const nodeRef = useRef<HTMLDivElement>(null)
const { nodesReadOnly } = useNodesReadOnly() const { nodesReadOnly } = useNodesReadOnly()
const { handleNodeIterationChildSizeChange } = useNodeIterationInteractions() const { handleNodeIterationChildSizeChange } = useNodeIterationInteractions()
@ -80,6 +82,7 @@ const BaseNode: FC<BaseNodeProps> = ({
className={cn( className={cn(
'flex border-[2px] rounded-2xl', 'flex border-[2px] rounded-2xl',
showSelectedBorder ? 'border-components-option-card-option-selected-border' : 'border-transparent', showSelectedBorder ? 'border-components-option-card-option-selected-border' : 'border-transparent',
!showSelectedBorder && data._inParallelHovering && 'border-workflow-block-border-highlight',
)} )}
ref={nodeRef} ref={nodeRef}
style={{ style={{
@ -100,6 +103,13 @@ const BaseNode: FC<BaseNodeProps> = ({
data._isBundled && '!shadow-lg', data._isBundled && '!shadow-lg',
)} )}
> >
{
data._inParallelHovering && (
<div className='absolute left-2 -top-2.5 top system-2xs-medium-uppercase text-text-tertiary z-10'>
{t('workflow.common.parallelRun')}
</div>
)
}
{ {
data._showAddVariablePopup && ( data._showAddVariablePopup && (
<AddVariablePopupWithPosition <AddVariablePopupWithPosition

View File

@ -54,6 +54,7 @@ export type CommonNodeType<T = {}> = {
_holdAddVariablePopup?: boolean _holdAddVariablePopup?: boolean
_iterationLength?: number _iterationLength?: number
_iterationIndex?: number _iterationIndex?: number
_inParallelHovering?: boolean
isIterationStart?: boolean isIterationStart?: boolean
isInIteration?: boolean isInIteration?: boolean
iteration_id?: string iteration_id?: string

View File

@ -77,6 +77,7 @@ const translation = {
overwriteAndImport: 'Overwrite and Import', overwriteAndImport: 'Overwrite and Import',
importFailure: 'Import failure', importFailure: 'Import failure',
importSuccess: 'Import success', importSuccess: 'Import success',
parallelRun: 'Parallel Run',
}, },
env: { env: {
envPanelTitle: 'Environment Variables', envPanelTitle: 'Environment Variables',

View File

@ -77,6 +77,7 @@ const translation = {
overwriteAndImport: '覆盖并导入', overwriteAndImport: '覆盖并导入',
importFailure: '导入失败', importFailure: '导入失败',
importSuccess: '导入成功', importSuccess: '导入成功',
parallelRun: '并行运行',
}, },
env: { env: {
envPanelTitle: '环境变量', envPanelTitle: '环境变量',