workflow store

This commit is contained in:
StyleZhang
2024-02-23 14:15:43 +08:00
parent 7ba0bfffa2
commit f6c07c996b
11 changed files with 127 additions and 275 deletions

View File

@ -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'

View File

@ -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'>

View File

@ -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>
)