mirror of https://github.com/langgenius/dify.git
help line
This commit is contained in:
parent
f51f4a5843
commit
2b475b7916
|
|
@ -49,6 +49,7 @@ const NodeSelector: FC<NodeSelectorProps> = ({
|
|||
asChild,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [searchText, setSearchText] = useState('')
|
||||
const [localOpen, setLocalOpen] = useState(false)
|
||||
const open = openFromProps === undefined ? localOpen : openFromProps
|
||||
const handleOpenChange = useCallback((newOpen: boolean) => {
|
||||
|
|
@ -103,12 +104,17 @@ const NodeSelector: FC<NodeSelectorProps> = ({
|
|||
>
|
||||
<SearchLg className='shrink-0 ml-[1px] mr-[5px] w-3.5 h-3.5 text-gray-400' />
|
||||
<input
|
||||
value={searchText}
|
||||
className='grow px-0.5 py-[7px] text-[13px] bg-transparent appearance-none outline-none'
|
||||
placeholder={t('workflow.tabs.searchBlock') || ''}
|
||||
onChange={e => setSearchText(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Tabs onSelect={handleSelect} />
|
||||
<Tabs
|
||||
onSelect={handleSelect}
|
||||
searchText={searchText}
|
||||
/>
|
||||
</div>
|
||||
</PortalToFollowElemContent>
|
||||
</PortalToFollowElem>
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ import { TabsEnum } from './types'
|
|||
import Tools from './tools'
|
||||
|
||||
export type TabsProps = {
|
||||
searchText: string
|
||||
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
|
||||
}
|
||||
const Tabs: FC<TabsProps> = ({
|
||||
searchText,
|
||||
onSelect,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
|
@ -31,14 +33,16 @@ const Tabs: FC<TabsProps> = ({
|
|||
|
||||
return (
|
||||
<div onClick={e => e.stopPropagation()}>
|
||||
<div className='flex items-center px-3 h-[34px] border-b-[0.5px] border-b-black/5'>
|
||||
<div className='flex items-center px-3 border-b-[0.5px] border-b-black/5'>
|
||||
{
|
||||
tabs.map(tab => (
|
||||
<div
|
||||
key={tab.key}
|
||||
className={`
|
||||
mr-4 text-[13px] font-medium cursor-pointer
|
||||
${activeTab === tab.key ? 'text-gray-700' : 'text-gray-500'}
|
||||
relative mr-4 h-[34px] leading-[34px] text-[13px] font-medium cursor-pointer
|
||||
${activeTab === tab.key
|
||||
? 'text-gray-700 after:absolute after:bottom-0 after:left-0 after:h-0.5 after:w-full after:bg-primary-600'
|
||||
: 'text-gray-500'}
|
||||
`}
|
||||
onClick={() => setActiveTab(tab.key)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ const Item = ({
|
|||
onClick={() => onSelect(BlockEnum.Tool, {
|
||||
provider_id: data.id,
|
||||
provider_type: data.type,
|
||||
provider_name: data.name,
|
||||
tool_name: tool.name,
|
||||
title: tool.label[language],
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export type ToolsMap = Record<string, ToolInWorkflow[]>
|
|||
export type ToolDefaultValue = {
|
||||
provider_id: string
|
||||
provider_type: string
|
||||
provider_name: string
|
||||
tool_name: string
|
||||
title: string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ import { Mode } from '@/app/components/workflow/types'
|
|||
|
||||
const Header: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const appDetail = useAppStore(state => state.appDetail)
|
||||
const appDetail = useAppStore(s => s.appDetail)
|
||||
const appSidebarExpand = useAppStore(s => s.appSidebarExpand)
|
||||
const isChatMode = useIsChatMode()
|
||||
const mode = useStore(state => state.mode)
|
||||
const runTaskId = useStore(state => state.runTaskId)
|
||||
|
|
@ -35,7 +36,11 @@ const Header: FC = () => {
|
|||
}}
|
||||
>
|
||||
<div>
|
||||
<div className='text-xs font-medium text-gray-700'>{appDetail?.name}</div>
|
||||
{
|
||||
appSidebarExpand && (
|
||||
<div className='text-xs font-medium text-gray-700'>{appDetail?.name}</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
mode === Mode.Editing && !runTaskId && <EditingTitle />
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,72 @@
|
|||
import { memo } from 'react'
|
||||
import { useViewport } from 'reactflow'
|
||||
import { useStore } from '../store'
|
||||
import type { HelpLinePosition } from './types'
|
||||
import type {
|
||||
HelpLineHorizontalPosition,
|
||||
HelpLineVerticalPosition,
|
||||
} from './types'
|
||||
|
||||
const HelpLineBase = ({
|
||||
const HelpLineHorizontal = memo(({
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
left,
|
||||
}: HelpLinePosition) => {
|
||||
width,
|
||||
}: HelpLineHorizontalPosition) => {
|
||||
const { x, y, zoom } = useViewport()
|
||||
|
||||
return (
|
||||
<div
|
||||
className='absolute h-[1px] bg-primary-300 z-[9]'
|
||||
style={{
|
||||
top: top * zoom + y,
|
||||
left: left * zoom + x,
|
||||
width: width * zoom,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
})
|
||||
HelpLineHorizontal.displayName = 'HelpLineBase'
|
||||
|
||||
const HelpLineVertical = memo(({
|
||||
top,
|
||||
left,
|
||||
height,
|
||||
}: HelpLineVerticalPosition) => {
|
||||
const { x, y, zoom } = useViewport()
|
||||
|
||||
return (
|
||||
<div
|
||||
className='absolute w-[1px] bg-primary-300 z-[9]'
|
||||
style={{ top, right, bottom, left }}
|
||||
style={{
|
||||
top: top * zoom + y,
|
||||
left: left * zoom + x,
|
||||
height: height * zoom,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
})
|
||||
HelpLineVertical.displayName = 'HelpLineVertical'
|
||||
|
||||
const HelpLine = () => {
|
||||
const helpLine = useStore(state => state.helpLine)
|
||||
const helpLineHorizontal = useStore(s => s.helpLineHorizontal)
|
||||
const helpLineVertical = useStore(s => s.helpLineVertical)
|
||||
|
||||
if (!helpLineHorizontal && !helpLineVertical)
|
||||
return null
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
helpLine?.bottom && (
|
||||
<HelpLineBase {...helpLine} />
|
||||
helpLineHorizontal && (
|
||||
<HelpLineHorizontal {...helpLineHorizontal} />
|
||||
)
|
||||
}
|
||||
{
|
||||
helpLine?.right && (
|
||||
<HelpLineBase {...helpLine} />
|
||||
helpLineVertical && (
|
||||
<HelpLineVertical {...helpLineVertical} />
|
||||
)
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default HelpLine
|
||||
export default memo(HelpLine)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
export type HelpLinePosition = {
|
||||
export type HelpLineHorizontalPosition = {
|
||||
top: number
|
||||
right?: number
|
||||
bottom?: number
|
||||
left: number
|
||||
width: number
|
||||
}
|
||||
|
||||
export type HelpLineVerticalPosition = {
|
||||
top: number
|
||||
left: number
|
||||
height: number
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,37 +138,96 @@ export const useWorkflow = () => {
|
|||
getNodes,
|
||||
setNodes,
|
||||
} = store.getState()
|
||||
// const { setHelpLine } = useStore.getState()
|
||||
const {
|
||||
setHelpLineHorizontal,
|
||||
setHelpLineVertical,
|
||||
} = useStore.getState()
|
||||
e.stopPropagation()
|
||||
|
||||
const nodes = getNodes()
|
||||
|
||||
// const showVerticalHelpLineNodes = nodes.filter((n) => {
|
||||
// if (
|
||||
// n.position.x === node.position.x
|
||||
// || n.position.x + n.width! === node.position.x
|
||||
// || n.position.x === node.position.x + node.width!
|
||||
// )
|
||||
// return true
|
||||
const showHorizontalHelpLineNodes = nodes.filter((n) => {
|
||||
if (n.id === node.id)
|
||||
return false
|
||||
|
||||
// return false
|
||||
// })
|
||||
// const showHorizontalHelpLineNodes = nodes.filter((n) => {
|
||||
// if (
|
||||
// n.position.y === node.position.y
|
||||
// || n.position.y === node.position.y + node.height!
|
||||
// || n.position.y + n.height! === node.position.y
|
||||
// || n.position.y + n.height! === node.position.y + node.height!
|
||||
// )
|
||||
// return true
|
||||
const nY = Math.ceil(n.position.y)
|
||||
const nodeY = Math.ceil(node.position.y)
|
||||
|
||||
// return false
|
||||
// })
|
||||
if (nY - nodeY < 5 && nY - nodeY > -5)
|
||||
return true
|
||||
|
||||
return false
|
||||
}).sort((a, b) => a.position.x - b.position.x)
|
||||
const showHorizontalHelpLineNodesLength = showHorizontalHelpLineNodes.length
|
||||
if (showHorizontalHelpLineNodesLength > 0) {
|
||||
const first = showHorizontalHelpLineNodes[0]
|
||||
const last = showHorizontalHelpLineNodes[showHorizontalHelpLineNodesLength - 1]
|
||||
|
||||
const helpLine = {
|
||||
top: first.position.y,
|
||||
left: first.position.x,
|
||||
width: last.position.x + last.width! - first.position.x,
|
||||
}
|
||||
|
||||
if (node.position.x < first.position.x) {
|
||||
helpLine.left = node.position.x
|
||||
helpLine.width = first.position.x + first.width! - node.position.x
|
||||
}
|
||||
|
||||
if (node.position.x > last.position.x)
|
||||
helpLine.width = node.position.x + node.width! - first.position.x
|
||||
|
||||
setHelpLineHorizontal(helpLine)
|
||||
}
|
||||
else {
|
||||
setHelpLineHorizontal()
|
||||
}
|
||||
|
||||
const showVerticalHelpLineNodes = nodes.filter((n) => {
|
||||
if (n.id === node.id)
|
||||
return false
|
||||
|
||||
const nX = Math.ceil(n.position.x)
|
||||
const nodeX = Math.ceil(node.position.x)
|
||||
|
||||
if (nX - nodeX < 5 && nX - nodeX > -5)
|
||||
return true
|
||||
|
||||
return false
|
||||
}).sort((a, b) => a.position.x - b.position.x)
|
||||
const showVerticalHelpLineNodesLength = showVerticalHelpLineNodes.length
|
||||
|
||||
if (showVerticalHelpLineNodesLength > 0) {
|
||||
const first = showVerticalHelpLineNodes[0]
|
||||
const last = showVerticalHelpLineNodes[showVerticalHelpLineNodesLength - 1]
|
||||
|
||||
const helpLine = {
|
||||
top: first.position.y,
|
||||
left: first.position.x,
|
||||
height: last.position.y + last.height! - first.position.y,
|
||||
}
|
||||
|
||||
if (node.position.y < first.position.y) {
|
||||
helpLine.top = node.position.y
|
||||
helpLine.height = first.position.y + first.height! - node.position.y
|
||||
}
|
||||
|
||||
if (node.position.y > last.position.y)
|
||||
helpLine.height = node.position.y + node.height! - first.position.y
|
||||
|
||||
setHelpLineVertical(helpLine)
|
||||
}
|
||||
else {
|
||||
setHelpLineVertical()
|
||||
}
|
||||
|
||||
const newNodes = produce(nodes, (draft) => {
|
||||
const currentNode = draft.find(n => n.id === node.id)!
|
||||
|
||||
currentNode.position = node.position
|
||||
currentNode.position = {
|
||||
x: showVerticalHelpLineNodesLength > 0 ? showVerticalHelpLineNodes[0].position.x : node.position.x,
|
||||
y: showHorizontalHelpLineNodesLength > 0 ? showHorizontalHelpLineNodes[0].position.y : node.position.y,
|
||||
}
|
||||
})
|
||||
|
||||
setNodes(newNodes)
|
||||
|
|
@ -177,10 +236,12 @@ export const useWorkflow = () => {
|
|||
const handleNodeDragStop = useCallback<NodeDragHandler>(() => {
|
||||
const {
|
||||
setIsDragging,
|
||||
setHelpLine,
|
||||
setHelpLineHorizontal,
|
||||
setHelpLineVertical,
|
||||
} = useStore.getState()
|
||||
setIsDragging(false)
|
||||
setHelpLine()
|
||||
setHelpLineHorizontal()
|
||||
setHelpLineVertical()
|
||||
handleSyncWorkflowDraft()
|
||||
}, [handleSyncWorkflowDraft])
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { create } from 'zustand'
|
||||
import type { HelpLinePosition } from './help-line/types'
|
||||
import type {
|
||||
HelpLineHorizontalPosition,
|
||||
HelpLineVerticalPosition,
|
||||
} from './help-line/types'
|
||||
import type {
|
||||
CollectionWithExpanded,
|
||||
ToolInWorkflow,
|
||||
|
|
@ -13,7 +16,8 @@ type State = {
|
|||
showRunHistory: boolean
|
||||
showFeaturesPanel: boolean
|
||||
isDragging: boolean
|
||||
helpLine?: HelpLinePosition
|
||||
helpLineHorizontal?: HelpLineHorizontalPosition
|
||||
helpLineVertical?: HelpLineVerticalPosition
|
||||
toolsets: CollectionWithExpanded[]
|
||||
toolsMap: ToolsMap
|
||||
draftUpdatedAt: number
|
||||
|
|
@ -26,7 +30,8 @@ type Action = {
|
|||
setShowRunHistory: (showRunHistory: boolean) => void
|
||||
setShowFeaturesPanel: (showFeaturesPanel: boolean) => void
|
||||
setIsDragging: (isDragging: boolean) => void
|
||||
setHelpLine: (helpLine?: HelpLinePosition) => void
|
||||
setHelpLineHorizontal: (helpLineHorizontal?: HelpLineHorizontalPosition) => void
|
||||
setHelpLineVertical: (helpLineVertical?: HelpLineVerticalPosition) => void
|
||||
setToolsets: (toolsets: CollectionWithExpanded[]) => void
|
||||
setToolsMap: (toolsMap: Record<string, ToolInWorkflow[]>) => void
|
||||
setDraftUpdatedAt: (draftUpdatedAt: number) => void
|
||||
|
|
@ -44,8 +49,10 @@ export const useStore = create<State & Action>(set => ({
|
|||
setShowFeaturesPanel: showFeaturesPanel => set(() => ({ showFeaturesPanel })),
|
||||
isDragging: false,
|
||||
setIsDragging: isDragging => set(() => ({ isDragging })),
|
||||
helpLine: undefined,
|
||||
setHelpLine: helpLine => set(() => ({ helpLine })),
|
||||
helpLineHorizontal: undefined,
|
||||
setHelpLineHorizontal: helpLineHorizontal => set(() => ({ helpLineHorizontal })),
|
||||
helpLineVertical: undefined,
|
||||
setHelpLineVertical: helpLineVertical => set(() => ({ helpLineVertical })),
|
||||
toolsets: [],
|
||||
setToolsets: toolsets => set(() => ({ toolsets })),
|
||||
toolsMap: {},
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export type CommonNodeType<T = {}> = {
|
|||
title: string
|
||||
desc: string
|
||||
type: BlockEnum
|
||||
} & T & Partial<Pick<ToolDefaultValue, 'provider_id' | 'provider_type' | 'tool_name'>>
|
||||
} & T & Partial<Pick<ToolDefaultValue, 'provider_id' | 'provider_type' | 'provider_name' | 'tool_name'>>
|
||||
|
||||
export type CommonEdgeType = {
|
||||
_hovering: boolean
|
||||
|
|
|
|||
Loading…
Reference in New Issue