Commit 16abcf08 authored by StyleZhang's avatar StyleZhang

node control

parent 173336f2
...@@ -368,6 +368,7 @@ export const useWorkflow = () => { ...@@ -368,6 +368,7 @@ export const useWorkflow = () => {
x: currentNode.position.x, x: currentNode.position.x,
y: currentNode.position.y, y: currentNode.position.y,
}, },
targetPosition: Position.Left,
} }
const newNodes = produce(nodes, (draft) => { const newNodes = produce(nodes, (draft) => {
const index = draft.findIndex(node => node.id === currentNodeId) const index = draft.findIndex(node => node.id === currentNodeId)
......
...@@ -9,8 +9,6 @@ import { useKeyPress } from 'ahooks' ...@@ -9,8 +9,6 @@ import { useKeyPress } from 'ahooks'
import ReactFlow, { import ReactFlow, {
Background, Background,
ReactFlowProvider, ReactFlowProvider,
useEdgesState,
useNodesState,
useOnViewportChange, useOnViewportChange,
} from 'reactflow' } from 'reactflow'
import type { Viewport } from 'reactflow' import type { Viewport } from 'reactflow'
...@@ -56,13 +54,11 @@ type WorkflowProps = { ...@@ -56,13 +54,11 @@ type WorkflowProps = {
viewport?: Viewport viewport?: Viewport
} }
const Workflow: FC<WorkflowProps> = memo(({ const Workflow: FC<WorkflowProps> = memo(({
nodes: initialNodes, nodes,
edges: initialEdges, edges,
viewport, viewport,
}) => { }) => {
const showFeaturesPanel = useStore(state => state.showFeaturesPanel) const showFeaturesPanel = useStore(state => state.showFeaturesPanel)
const [nodes] = useNodesState(initialNodes)
const [edges] = useEdgesState(initialEdges)
const { const {
handleSyncWorkflowDraft, handleSyncWorkflowDraft,
......
...@@ -21,7 +21,7 @@ const NodeControl: FC<NodeControlProps> = ({ ...@@ -21,7 +21,7 @@ const NodeControl: FC<NodeControlProps> = ({
const { handleNodeDataUpdate } = useWorkflow() const { handleNodeDataUpdate } = useWorkflow()
return ( return (
<div className='absolute right-0 -top-7 flex items-center px-0.5 h-6 bg-white rounded-lg border-[0.5px] border-gray-100 shadow-xs text-gray-500'> <div className='flex items-center px-0.5 h-6 bg-white rounded-lg border-[0.5px] border-gray-100 shadow-xs text-gray-500'>
{ {
isRunning && ( isRunning && (
<div className='flex items-center px-1 h-5 rounded-md bg-primary-50 text-xs font-medium text-primary-600'> <div className='flex items-center px-1 h-5 rounded-md bg-primary-50 text-xs font-medium text-primary-600'>
......
...@@ -8,10 +8,12 @@ import { ...@@ -8,10 +8,12 @@ import {
} from 'react' } from 'react'
import type { NodeProps } from '../../types' import type { NodeProps } from '../../types'
import { BlockEnum } from '../../types' import { BlockEnum } from '../../types'
import { canRunBySingle } from '../../utils'
import { import {
NodeSourceHandle, NodeSourceHandle,
NodeTargetHandle, NodeTargetHandle,
} from './components/node-handle' } from './components/node-handle'
import NodeControl from './components/node-control'
import BlockIcon from '@/app/components/workflow/block-icon' import BlockIcon from '@/app/components/workflow/block-icon'
type BaseNodeProps = { type BaseNodeProps = {
...@@ -26,55 +28,73 @@ const BaseNode: FC<BaseNodeProps> = ({ ...@@ -26,55 +28,73 @@ const BaseNode: FC<BaseNodeProps> = ({
return ( return (
<div <div
className={` className={`
group relative w-[240px] bg-[#fcfdff] rounded-2xl shadow-xs flex border-[2px] rounded-2xl
hover:shadow-lg ${data._selected ? 'border-primary-600' : 'border-transparent'}
${data._selected ? 'border-[2px] border-primary-600' : 'border border-white'}
`} `}
> >
{ <div
data.type !== BlockEnum.VariableAssigner && ( className={`
<NodeTargetHandle group relative w-[240px] bg-[#fcfdff] shadow-xs
id={id} border border-transparent rounded-[15px]
data={data} hover:shadow-lg
handleClassName='!top-[17px] !-left-2' `}
handleId='target' >
{
data.type !== BlockEnum.VariableAssigner && (
<NodeTargetHandle
id={id}
data={data}
handleClassName='!top-4 !-left-[9px]'
handleId='target'
/>
)
}
{
data.type !== BlockEnum.IfElse && data.type !== BlockEnum.QuestionClassifier && (
<NodeSourceHandle
id={id}
data={data}
handleClassName='!top-4 !-right-[9px]'
handleId='source'
/>
)
}
{
canRunBySingle(data.type)
&& (
<div className='hidden group-hover:flex pb-1 absolute right-0 -top-7 h-7'>
<NodeControl
nodeId={id}
isRunning={data._isSingleRun}
/>
</div>
)
}
<div className='flex items-center px-3 pt-3 pb-2'>
<BlockIcon
className='shrink-0 mr-2'
type={data.type}
size='md'
icon={data._icon}
/> />
) <div
} title={data.title}
{ className='grow text-[13px] font-semibold text-gray-700 truncate'
data.type !== BlockEnum.IfElse && data.type !== BlockEnum.QuestionClassifier && ( >
<NodeSourceHandle {data.title}
id={id} </div>
data={data}
handleClassName='!top-[17px] !-right-2'
handleId='source'
/>
)
}
<div className='flex items-center px-3 pt-3 pb-2'>
<BlockIcon
className='shrink-0 mr-2'
type={data.type}
size='md'
icon={data._icon}
/>
<div
title={data.title}
className='grow text-[13px] font-semibold text-gray-700 truncate'
>
{data.title}
</div> </div>
<div className='mb-1'>
{cloneElement(children, { id, data })}
</div>
{
data.desc && (
<div className='px-3 pt-s1 pb-2 text-xs leading-[18px] text-gray-500 whitespace-pre-line break-words'>
{data.desc}
</div>
)
}
</div> </div>
<div className='mb-1'>
{cloneElement(children, { id, data })}
</div>
{
data.desc && (
<div className='px-3 pt-s1 pb-2 text-xs leading-[18px] text-gray-500 whitespace-pre-line break-words'>
{data.desc}
</div>
)
}
</div> </div>
) )
} }
......
import { memo } from 'react' import { memo } from 'react'
import type { NodeProps } from 'reactflow' import type { NodeProps } from 'reactflow'
import type { Node } from '../types' import type { Node } from '../types'
import { canRunBySingle } from '../utils'
import { import {
NodeComponentMap, NodeComponentMap,
PanelComponentMap, PanelComponentMap,
} from './constants' } from './constants'
import BaseNode from './_base/node' import BaseNode from './_base/node'
import BasePanel from './_base/panel' import BasePanel from './_base/panel'
import NodeControl from './_base/components/node-control'
const CustomNode = memo((props: NodeProps) => { const CustomNode = memo((props: NodeProps) => {
const nodeId = props.id
const nodeData = props.data const nodeData = props.data
const NodeComponent = NodeComponentMap[nodeData.type] const NodeComponent = NodeComponentMap[nodeData.type]
return ( return (
<> <BaseNode { ...props }>
<BaseNode { ...props }> <NodeComponent />
<NodeComponent /> </BaseNode>
</BaseNode>
{
nodeData._selected
&& canRunBySingle(nodeData.type)
&& (
<NodeControl
nodeId={nodeId}
isRunning={nodeData._isSingleRun}
/>
)
}
</>
) )
}) })
CustomNode.displayName = 'CustomNode' CustomNode.displayName = 'CustomNode'
......
...@@ -27,7 +27,6 @@ export type Branch = { ...@@ -27,7 +27,6 @@ export type Branch = {
export type CommonNodeType<T = {}> = { export type CommonNodeType<T = {}> = {
_selected?: boolean _selected?: boolean
_hovering?: boolean
_targetBranches?: Branch[] _targetBranches?: Branch[]
_isSingleRun?: boolean _isSingleRun?: boolean
_icon?: Collection['icon'] _icon?: Collection['icon']
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment