panel-operator

This commit is contained in:
StyleZhang
2024-02-28 18:29:12 +08:00
parent 510f0593e9
commit d2d6904c9b
15 changed files with 178 additions and 138 deletions

View File

@ -7,14 +7,17 @@ import {
} from 'reactflow'
import BlockIcon from '../../../../block-icon'
import type { Node } from '../../../../types'
import { useStore } from '../../../../store'
import Add from './add'
import Item from './item'
import Line from './line'
const NextStep = () => {
type NextStepProps = {
selectedNode: Node
}
const NextStep = ({
selectedNode,
}: NextStepProps) => {
const store = useStoreApi()
const selectedNode = useStore(state => state.selectedNode)
const branches = selectedNode?.data.branches
const edges = useEdges()
const outgoers = getOutgoers(selectedNode as Node, store.getState().getNodes(), edges)

View File

@ -0,0 +1,77 @@
import {
memo,
useState,
} from 'react'
import { useWorkflow } from '../../../hooks'
import { DotsHorizontal } from '@/app/components/base/icons/src/vender/line/general'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
type PanelOperatorProps = {
nodeId: string
}
const PanelOperator = ({
nodeId,
}: PanelOperatorProps) => {
const { handleDeleteNode } = useWorkflow()
const [open, setOpen] = useState(false)
return (
<PortalToFollowElem
placement='bottom-end'
offset={{
mainAxis: 4,
crossAxis: 53,
}}
open={open}
onOpenChange={setOpen}
>
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
<div
className={`
flex items-center justify-center w-6 h-6 rounded-md cursor-pointer
hover:bg-black/5
${open && 'bg-black/5'}
`}
>
<DotsHorizontal className='w-4 h-4 text-gray-700' />
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[11]'>
<div className='w-[240px] border-[0.5px] border-gray-200 rounded-2xl shadow-xl bg-white'>
<div className='p-1'>
<div className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>Change Block</div>
<div className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>Help Link</div>
</div>
<div className='h-[1px] bg-gray-100'></div>
<div className='p-1'>
<div
className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'
onClick={() => handleDeleteNode(nodeId)}
>
Delete
</div>
</div>
<div className='h-[1px] bg-gray-100'></div>
<div className='p-1'>
<div className='px-3 py-2 text-xs text-gray-500'>
<div className='flex items-center mb-1 h-[22px] font-medium'>
ABOUT
</div>
<div className='text-gray-500 leading-[18px]'>A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.</div>
<div className='my-2 h-[0.5px] bg-black/5'></div>
<div className='leading-[18px]'>
Created By Dify
</div>
</div>
</div>
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default memo(PanelOperator)

View File

@ -16,8 +16,9 @@ type BaseNodeProps = {
} & NodeProps
const BaseNode: FC<BaseNodeProps> = ({
id: nodeId,
id,
data,
selected,
children,
}) => {
const { handleSelectNode } = useWorkflow()
@ -27,10 +28,9 @@ const BaseNode: FC<BaseNodeProps> = ({
className={`
group relative w-[240px] bg-[#fcfdff] rounded-2xl shadow-xs
hover:shadow-lg
${data.hidden && 'opacity-0'}
${data.selected ? 'border-[2px] border-primary-600' : 'border border-white'}
${selected ? 'border-[2px] border-primary-600' : 'border border-white'}
`}
onClick={() => handleSelectNode({ id: nodeId, data })}
onClick={() => handleSelectNode(id)}
>
<NodeControl />
<div className='flex items-center px-3 pt-3 pb-2'>
@ -49,7 +49,7 @@ const BaseNode: FC<BaseNodeProps> = ({
{
children && (
<div className='mb-1'>
{cloneElement(children, { id: nodeId, data })}
{cloneElement(children, { id, data })}
</div>
)
}

View File

@ -7,23 +7,23 @@ import {
memo,
useCallback,
} from 'react'
import type { SelectedNode } from '../../types'
import type { Node } from '../../types'
import BlockIcon from '../../block-icon'
import { useWorkflow } from '../../hooks'
import NextStep from './components/next-step'
import PanelOperator from './components/panel-operator'
import {
DescriptionInput,
TitleInput,
} from './components/title-description-input'
import {
DotsHorizontal,
XClose,
} from '@/app/components/base/icons/src/vender/line/general'
import { GitBranch01 } from '@/app/components/base/icons/src/vender/line/development'
type BasePanelProps = {
children: ReactElement
} & SelectedNode
} & Node
const BasePanel: FC<BasePanelProps> = ({
id,
@ -42,7 +42,7 @@ const BasePanel: FC<BasePanelProps> = ({
}, [handleUpdateNodeData, id, data])
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'>
<div className='mr-2 w-[420px] h-full bg-white shadow-lg border-[0.5px] border-gray-200 rounded-2xl overflow-y-auto'>
<div className='sticky top-0 bg-white border-b-[0.5px] border-black/5'>
<div className='flex items-center px-4 pt-4 pb-1'>
<BlockIcon
@ -55,13 +55,11 @@ const BasePanel: FC<BasePanelProps> = ({
onChange={handleTitleChange}
/>
<div className='shrink-0 flex items-center text-gray-500'>
<div className='flex items-center justify-center w-6 h-6 cursor-pointer'>
<DotsHorizontal className='w-4 h-4' />
</div>
<PanelOperator nodeId={id} />
<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={() => handleSelectNode({ id, data }, true)}
onClick={() => handleSelectNode(id, true)}
>
<XClose className='w-4 h-4' />
</div>
@ -85,7 +83,7 @@ const BasePanel: FC<BasePanelProps> = ({
<div className='mb-2 text-xs text-gray-400'>
Add the next block in this workflow
</div>
<NextStep />
<NextStep selectedNode={{ id, data } as Node} />
</div>
</div>
)