mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 09:58:04 +08:00
workflow store
This commit is contained in:
@ -1,31 +1,18 @@
|
||||
import type { FC } from 'react'
|
||||
import {
|
||||
memo,
|
||||
useCallback,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import { getOutgoers } from 'reactflow'
|
||||
import BlockIcon from '../../../block-icon'
|
||||
import type { Node } from '../../../types'
|
||||
import { BlockEnum } from '../../../types'
|
||||
import { useWorkflowContext } from '../../../context'
|
||||
import { useStore } from '../../../store'
|
||||
import BlockSelector from '../../../block-selector'
|
||||
import { Plus } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import Button from '@/app/components/base/button'
|
||||
|
||||
type NextStepProps = {
|
||||
selectedNode: Node
|
||||
}
|
||||
const NextStep: FC<NextStepProps> = ({
|
||||
selectedNode,
|
||||
}) => {
|
||||
const {
|
||||
nodes,
|
||||
edges,
|
||||
} = useWorkflowContext()
|
||||
const outgoers = useMemo(() => {
|
||||
return getOutgoers(selectedNode, nodes, edges)
|
||||
}, [selectedNode, nodes, edges])
|
||||
const NextStep = () => {
|
||||
const selectedNode = useStore(state => state.selectedNode)
|
||||
const outgoers: Node[] = []
|
||||
|
||||
const renderAddNextNodeTrigger = useCallback((open: boolean) => {
|
||||
return (
|
||||
@ -60,7 +47,7 @@ const NextStep: FC<NextStepProps> = ({
|
||||
return (
|
||||
<div className='flex py-1'>
|
||||
<div className='shrink-0 relative flex items-center justify-center w-9 h-9 bg-white rounded-lg border-[0.5px] border-gray-200 shadow-xs'>
|
||||
<BlockIcon type={selectedNode.data.type} />
|
||||
<BlockIcon type={selectedNode!.data.type} />
|
||||
</div>
|
||||
<div className='shrink-0 w-6'></div>
|
||||
<div className='grow'>
|
||||
@ -74,7 +61,7 @@ const NextStep: FC<NextStepProps> = ({
|
||||
type={outgoer.data.type}
|
||||
className='shrink-0 mr-1.5'
|
||||
/>
|
||||
<div className='grow'>{outgoer.data.name}</div>
|
||||
<div className='grow'>{outgoer.data.title}</div>
|
||||
<BlockSelector
|
||||
onSelect={() => {}}
|
||||
placement='top-end'
|
||||
@ -89,7 +76,7 @@ const NextStep: FC<NextStepProps> = ({
|
||||
))
|
||||
}
|
||||
{
|
||||
(!outgoers.length || selectedNode.data.type === BlockEnum.IfElse) && (
|
||||
(!outgoers.length || selectedNode!.data.type === BlockEnum.IfElse) && (
|
||||
<BlockSelector
|
||||
onSelect={() => {}}
|
||||
placement='top'
|
||||
|
||||
@ -5,13 +5,10 @@ import type {
|
||||
import {
|
||||
cloneElement,
|
||||
memo,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import type { NodeProps } from 'reactflow'
|
||||
import { useNodes } from 'reactflow'
|
||||
import { useStore } from '../../store'
|
||||
import type { NodeData } from '../../types'
|
||||
import BlockIcon from '../../block-icon'
|
||||
import { useWorkflow } from '../../hooks'
|
||||
import BlockSelector from '../../block-selector'
|
||||
import NodeControl from './components/node-control'
|
||||
|
||||
@ -25,27 +22,22 @@ const BaseNode: FC<BaseNodeProps> = ({
|
||||
selected,
|
||||
children,
|
||||
}) => {
|
||||
const nodes = useNodes<NodeData>()
|
||||
const selectedNodeId = useStore(state => state.selectedNodeId)
|
||||
const handleSelectedNodeId = useStore(state => state.handleSelectedNodeId)
|
||||
const currentNode = useMemo(() => {
|
||||
return nodes.find(node => node.id === nodeId)
|
||||
}, [nodeId, nodes])
|
||||
const { handleSelectNode } = useWorkflow()
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
group relative pb-2 w-[240px] bg-[#fcfdff] rounded-2xl shadow-xs
|
||||
hover:shadow-lg
|
||||
${selectedNodeId === nodeId ? 'border-[2px] border-primary-600' : 'border border-white'}
|
||||
${(data.selected && selected) ? 'border-[2px] border-primary-600' : 'border border-white'}
|
||||
`}
|
||||
onClick={() => handleSelectedNodeId(nodeId || '')}
|
||||
onClick={() => handleSelectNode({ id: nodeId, data })}
|
||||
>
|
||||
<NodeControl />
|
||||
<div className='flex items-center px-3 pt-3 pb-2'>
|
||||
<BlockIcon
|
||||
className='mr-2'
|
||||
type={currentNode!.data.type}
|
||||
type={data.type}
|
||||
size='md'
|
||||
/>
|
||||
<div className='text-[13px] font-semibold text-gray-700'>
|
||||
|
||||
@ -5,12 +5,10 @@ import type {
|
||||
import {
|
||||
cloneElement,
|
||||
memo,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import type { NodeProps } from 'reactflow'
|
||||
import { useWorkflowContext } from '../../context'
|
||||
import { useStore } from '../../store'
|
||||
import type { SelectedNode } from '../../types'
|
||||
import BlockIcon from '../../block-icon'
|
||||
import { useWorkflow } from '../../hooks'
|
||||
import NextStep from './components/next-step'
|
||||
import {
|
||||
DotsHorizontal,
|
||||
@ -20,21 +18,14 @@ import { GitBranch01 } from '@/app/components/base/icons/src/vender/line/develop
|
||||
|
||||
type BasePanelProps = {
|
||||
children: ReactElement
|
||||
} & Pick<NodeProps, 'id' | 'data'>
|
||||
} & SelectedNode
|
||||
|
||||
const BasePanel: FC<BasePanelProps> = ({
|
||||
id,
|
||||
data,
|
||||
children,
|
||||
}) => {
|
||||
const {
|
||||
nodes,
|
||||
} = useWorkflowContext()
|
||||
const selectedNodeId = useStore(state => state.selectedNodeId)
|
||||
const handleSelectedNodeId = useStore(state => state.handleSelectedNodeId)
|
||||
const selectedNode = useMemo(() => {
|
||||
return nodes.find(node => node.id === selectedNodeId)
|
||||
}, [nodes, selectedNodeId])
|
||||
const { handleSelectNode } = useWorkflow()
|
||||
|
||||
return (
|
||||
<div className='mr-2 w-[420px] h-full bg-white shadow-lg border-[0.5px] border-gray-200 rounded-2xl z-10 overflow-y-auto'>
|
||||
@ -42,7 +33,7 @@ const BasePanel: FC<BasePanelProps> = ({
|
||||
<div className='flex items-center px-4 pt-3'>
|
||||
<BlockIcon
|
||||
className='shrink-0 mr-2'
|
||||
type={selectedNode!.data.type}
|
||||
type={data.type}
|
||||
size='md'
|
||||
/>
|
||||
<div className='grow py-1 text-base text-gray-900 font-semibold '>{data.title}</div>
|
||||
@ -53,7 +44,7 @@ const BasePanel: FC<BasePanelProps> = ({
|
||||
<div className='mx-3 w-[1px] h-3.5 bg-gray-200' />
|
||||
<div
|
||||
className='flex items-center justify-center w-6 h-6 cursor-pointer'
|
||||
onClick={() => handleSelectedNodeId('')}
|
||||
onClick={() => handleSelectNode({ id, data }, true)}
|
||||
>
|
||||
<XClose className='w-4 h-4' />
|
||||
</div>
|
||||
@ -76,7 +67,7 @@ const BasePanel: FC<BasePanelProps> = ({
|
||||
<div className='mb-2 text-xs text-gray-400'>
|
||||
Add the next block in this workflow
|
||||
</div>
|
||||
<NextStep selectedNode={selectedNode!} />
|
||||
<NextStep />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user