mirror of https://github.com/langgenius/dify.git
node title desc
This commit is contained in:
parent
7574107d8c
commit
6e2611c86c
|
|
@ -8,7 +8,9 @@ import {
|
|||
getConnectedEdges,
|
||||
useStoreApi,
|
||||
} from 'reactflow'
|
||||
import type { SelectedNode } from './types'
|
||||
import type {
|
||||
SelectedNode,
|
||||
} from './types'
|
||||
import { useStore } from './store'
|
||||
|
||||
export const useWorkflow = () => {
|
||||
|
|
@ -113,6 +115,19 @@ export const useWorkflow = () => {
|
|||
setNodes(newNodes)
|
||||
}
|
||||
}, [setSelectedNode, store])
|
||||
const handleUpdateNodeData = useCallback(({ id, data }: SelectedNode) => {
|
||||
const {
|
||||
getNodes,
|
||||
setNodes,
|
||||
} = store.getState()
|
||||
const newNodes = produce(getNodes(), (draft) => {
|
||||
const currentNode = draft.find(n => n.id === id)
|
||||
if (currentNode)
|
||||
currentNode.data = { ...currentNode.data, ...data }
|
||||
})
|
||||
setNodes(newNodes)
|
||||
setSelectedNode({ id, data })
|
||||
}, [store, setSelectedNode])
|
||||
|
||||
return {
|
||||
handleEnterNode,
|
||||
|
|
@ -120,5 +135,6 @@ export const useWorkflow = () => {
|
|||
handleEnterEdge,
|
||||
handleLeaveEdge,
|
||||
handleSelectNode,
|
||||
handleUpdateNodeData,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
import {
|
||||
memo,
|
||||
useCallback,
|
||||
useState,
|
||||
} from 'react'
|
||||
import Textarea from 'rc-textarea'
|
||||
|
||||
type InputProps = {
|
||||
value: string
|
||||
onChange: (value: string) => void
|
||||
}
|
||||
|
||||
export const TitleInput = memo(({
|
||||
value,
|
||||
onChange,
|
||||
}: InputProps) => {
|
||||
return (
|
||||
<input
|
||||
value={value}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
className={`
|
||||
grow mr-2 px-1 h-6 text-base text-gray-900 font-semibold rounded-lg border border-transparent appearance-none outline-none
|
||||
hover:bg-gray-50
|
||||
focus:border-gray-300 focus:shadow-xs focus:bg-white
|
||||
`}
|
||||
placeholder='Add title...'
|
||||
/>
|
||||
)
|
||||
})
|
||||
TitleInput.displayName = 'TitleInput'
|
||||
|
||||
export const DescriptionInput = memo(({
|
||||
value,
|
||||
onChange,
|
||||
}: InputProps) => {
|
||||
const [focus, setFocus] = useState(false)
|
||||
const handleFocus = useCallback(() => {
|
||||
setFocus(true)
|
||||
}, [])
|
||||
const handleBlur = useCallback(() => {
|
||||
setFocus(false)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
group flex px-2 py-[5px] max-h-[60px] rounded-lg overflow-y-auto
|
||||
border border-transparent hover:bg-gray-50 leading-0
|
||||
${focus && '!border-gray-300 shadow-xs !bg-gray-50'}
|
||||
`}
|
||||
>
|
||||
<Textarea
|
||||
value={value}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
rows={1}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
className={`
|
||||
w-full text-xs text-gray-900 leading-[18px] bg-transparent
|
||||
appearance-none outline-none resize-none
|
||||
placeholder:text-gray-400
|
||||
`}
|
||||
placeholder='Add description...'
|
||||
autoSize
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
DescriptionInput.displayName = 'DescriptionInput'
|
||||
|
|
@ -26,7 +26,7 @@ const BaseNode: FC<BaseNodeProps> = ({
|
|||
return (
|
||||
<div
|
||||
className={`
|
||||
group relative pb-2 w-[240px] bg-[#fcfdff] rounded-2xl shadow-xs
|
||||
group relative w-[240px] bg-[#fcfdff] rounded-2xl shadow-xs
|
||||
hover:shadow-lg
|
||||
${(data.selected && selected) ? 'border-[2px] border-primary-600' : 'border border-white'}
|
||||
`}
|
||||
|
|
@ -35,17 +35,26 @@ const BaseNode: FC<BaseNodeProps> = ({
|
|||
<NodeControl />
|
||||
<div className='flex items-center px-3 pt-3 pb-2'>
|
||||
<BlockIcon
|
||||
className='mr-2'
|
||||
className='shrink-0 mr-2'
|
||||
type={data.type}
|
||||
size='md'
|
||||
/>
|
||||
<div className='text-[13px] font-semibold text-gray-700'>
|
||||
<div
|
||||
title={data.title}
|
||||
className='text-[13px] font-semibold text-gray-700 truncate'
|
||||
>
|
||||
{data.title}
|
||||
</div>
|
||||
</div>
|
||||
{cloneElement(children, { id: nodeId, data })}
|
||||
<div className='px-3 pt-1 pb-1 text-xs text-gray-500'>
|
||||
Define the initial parameters for launching a workflow
|
||||
<div className='mt-1 pb-1'>
|
||||
{
|
||||
data.desc && (
|
||||
<div className='px-3 pt-1 pb-2 text-xs leading-[18px] text-gray-500 whitespace-pre-line break-words'>
|
||||
{data.desc}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,11 +5,16 @@ import type {
|
|||
import {
|
||||
cloneElement,
|
||||
memo,
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import type { SelectedNode } from '../../types'
|
||||
import BlockIcon from '../../block-icon'
|
||||
import { useWorkflow } from '../../hooks'
|
||||
import NextStep from './components/next-step'
|
||||
import {
|
||||
DescriptionInput,
|
||||
TitleInput,
|
||||
} from './components/title-description-input'
|
||||
import {
|
||||
DotsHorizontal,
|
||||
XClose,
|
||||
|
|
@ -25,18 +30,30 @@ const BasePanel: FC<BasePanelProps> = ({
|
|||
data,
|
||||
children,
|
||||
}) => {
|
||||
const { handleSelectNode } = useWorkflow()
|
||||
const {
|
||||
handleSelectNode,
|
||||
handleUpdateNodeData,
|
||||
} = useWorkflow()
|
||||
const handleTitleChange = useCallback((title: string) => {
|
||||
handleUpdateNodeData({ id, data: { ...data, title } })
|
||||
}, [handleUpdateNodeData, id, data])
|
||||
const handleDescriptionChange = useCallback((desc: string) => {
|
||||
handleUpdateNodeData({ id, data: { ...data, desc } })
|
||||
}, [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='sticky top-0 bg-white border-b-[0.5px] border-black/5'>
|
||||
<div className='flex items-center px-4 pt-3'>
|
||||
<div className='flex items-center px-4 pt-4 pb-1'>
|
||||
<BlockIcon
|
||||
className='shrink-0 mr-2'
|
||||
className='shrink-0 mr-1'
|
||||
type={data.type}
|
||||
size='md'
|
||||
/>
|
||||
<div className='grow py-1 text-base text-gray-900 font-semibold '>{data.title}</div>
|
||||
<TitleInput
|
||||
value={data.title || ''}
|
||||
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' />
|
||||
|
|
@ -51,9 +68,10 @@ const BasePanel: FC<BasePanelProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
<div className='p-2'>
|
||||
<div className='py-[5px] pl-1.5 pr-2 text-xs text-gray-400'>
|
||||
Add description...
|
||||
</div>
|
||||
<DescriptionInput
|
||||
value={data.desc || ''}
|
||||
onChange={handleDescriptionChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='py-2 border-b-[0.5px] border-black/5'>
|
||||
|
|
|
|||
Loading…
Reference in New Issue