Commit 6e2611c8 authored by StyleZhang's avatar StyleZhang

node title desc

parent 7574107d
...@@ -8,7 +8,9 @@ import { ...@@ -8,7 +8,9 @@ import {
getConnectedEdges, getConnectedEdges,
useStoreApi, useStoreApi,
} from 'reactflow' } from 'reactflow'
import type { SelectedNode } from './types' import type {
SelectedNode,
} from './types'
import { useStore } from './store' import { useStore } from './store'
export const useWorkflow = () => { export const useWorkflow = () => {
...@@ -113,6 +115,19 @@ export const useWorkflow = () => { ...@@ -113,6 +115,19 @@ export const useWorkflow = () => {
setNodes(newNodes) setNodes(newNodes)
} }
}, [setSelectedNode, store]) }, [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 { return {
handleEnterNode, handleEnterNode,
...@@ -120,5 +135,6 @@ export const useWorkflow = () => { ...@@ -120,5 +135,6 @@ export const useWorkflow = () => {
handleEnterEdge, handleEnterEdge,
handleLeaveEdge, handleLeaveEdge,
handleSelectNode, handleSelectNode,
handleUpdateNodeData,
} }
} }
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> = ({ ...@@ -26,7 +26,7 @@ const BaseNode: FC<BaseNodeProps> = ({
return ( return (
<div <div
className={` 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 hover:shadow-lg
${(data.selected && selected) ? 'border-[2px] border-primary-600' : 'border border-white'} ${(data.selected && selected) ? 'border-[2px] border-primary-600' : 'border border-white'}
`} `}
...@@ -35,17 +35,26 @@ const BaseNode: FC<BaseNodeProps> = ({ ...@@ -35,17 +35,26 @@ const BaseNode: FC<BaseNodeProps> = ({
<NodeControl /> <NodeControl />
<div className='flex items-center px-3 pt-3 pb-2'> <div className='flex items-center px-3 pt-3 pb-2'>
<BlockIcon <BlockIcon
className='mr-2' className='shrink-0 mr-2'
type={data.type} type={data.type}
size='md' 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} {data.title}
</div> </div>
</div> </div>
{cloneElement(children, { id: nodeId, data })} {cloneElement(children, { id: nodeId, data })}
<div className='px-3 pt-1 pb-1 text-xs text-gray-500'> <div className='mt-1 pb-1'>
Define the initial parameters for launching a workflow {
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>
</div> </div>
) )
......
...@@ -5,11 +5,16 @@ import type { ...@@ -5,11 +5,16 @@ import type {
import { import {
cloneElement, cloneElement,
memo, memo,
useCallback,
} from 'react' } from 'react'
import type { SelectedNode } from '../../types' import type { SelectedNode } from '../../types'
import BlockIcon from '../../block-icon' import BlockIcon from '../../block-icon'
import { useWorkflow } from '../../hooks' import { useWorkflow } from '../../hooks'
import NextStep from './components/next-step' import NextStep from './components/next-step'
import {
DescriptionInput,
TitleInput,
} from './components/title-description-input'
import { import {
DotsHorizontal, DotsHorizontal,
XClose, XClose,
...@@ -25,18 +30,30 @@ const BasePanel: FC<BasePanelProps> = ({ ...@@ -25,18 +30,30 @@ const BasePanel: FC<BasePanelProps> = ({
data, data,
children, 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 ( 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 z-10 overflow-y-auto'>
<div className='sticky top-0 bg-white border-b-[0.5px] border-black/5'> <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 <BlockIcon
className='shrink-0 mr-2' className='shrink-0 mr-1'
type={data.type} type={data.type}
size='md' 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='shrink-0 flex items-center text-gray-500'>
<div className='flex items-center justify-center w-6 h-6 cursor-pointer'> <div className='flex items-center justify-center w-6 h-6 cursor-pointer'>
<DotsHorizontal className='w-4 h-4' /> <DotsHorizontal className='w-4 h-4' />
...@@ -51,9 +68,10 @@ const BasePanel: FC<BasePanelProps> = ({ ...@@ -51,9 +68,10 @@ const BasePanel: FC<BasePanelProps> = ({
</div> </div>
</div> </div>
<div className='p-2'> <div className='p-2'>
<div className='py-[5px] pl-1.5 pr-2 text-xs text-gray-400'> <DescriptionInput
Add description... value={data.desc || ''}
</div> onChange={handleDescriptionChange}
/>
</div> </div>
</div> </div>
<div className='py-2 border-b-[0.5px] border-black/5'> <div className='py-2 border-b-[0.5px] border-black/5'>
......
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