Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
671654da
Commit
671654da
authored
Feb 21, 2024
by
StyleZhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add node
parent
31490417
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
223 additions
and
62 deletions
+223
-62
context.tsx
web/app/components/workflow/block-selector/context.tsx
+16
-2
hooks.ts
...ponents/workflow/nodes/_base/components/add-node/hooks.ts
+40
-0
index.tsx
...onents/workflow/nodes/_base/components/add-node/index.tsx
+116
-0
next-step.tsx
.../components/workflow/nodes/_base/components/next-step.tsx
+30
-29
node.tsx
web/app/components/workflow/nodes/_base/node.tsx
+21
-31
No files found.
web/app/components/workflow/block-selector/context.tsx
View file @
671654da
...
...
@@ -22,6 +22,7 @@ type UpdateParams = {
from
?:
string
placement
?:
Placement
offset
?:
OffsetOptions
open
?:
boolean
className
?:
string
callback
?:
OnSelect
}
...
...
@@ -30,6 +31,9 @@ export type BlockSelectorContextValue = {
open
:
boolean
setOpen
:
(
open
:
boolean
)
=>
void
referenceRef
:
any
floatingRef
:
any
floatingStyles
:
React
.
CSSProperties
getFloatingProps
:
any
handleToggle
:
(
v
:
UpdateParams
)
=>
void
}
...
...
@@ -38,6 +42,9 @@ export const BlockSelectorContext = createContext<BlockSelectorContextValue>({
open
:
false
,
setOpen
:
()
=>
{},
referenceRef
:
null
,
floatingRef
:
null
,
floatingStyles
:
{},
getFloatingProps
:
()
=>
{},
handleToggle
:
()
=>
{},
})
export
const
useBlockSelectorContext
=
()
=>
useContext
(
BlockSelectorContext
)
...
...
@@ -73,12 +80,16 @@ export const BlockSelectorContextProvider = ({
const
handleToggle
=
useCallback
(({
from
,
open
,
placement
,
offset
,
className
,
callback
,
}:
UpdateParams
)
=>
{
setFrom
(
from
||
'node'
)
if
(
open
!==
undefined
)
setOpen
(
open
)
else
setOpen
(
v
=>
!
v
)
setPlacement
(
placement
||
'top'
)
setOffsetValue
(
offset
||
0
)
...
...
@@ -99,10 +110,13 @@ export const BlockSelectorContextProvider = ({
setOpen
,
handleToggle
,
referenceRef
:
refs
.
setReference
,
floatingRef
:
refs
.
setFloating
,
floatingStyles
,
getFloatingProps
,
}
}
>
{
children
}
{
open
&&
(
open
&&
(
from
===
'node'
||
from
===
'panel'
)
&&
(
<
FloatingPortal
>
<
div
ref=
{
refs
.
setFloating
}
...
...
web/app/components/workflow/nodes/_base/components/add-node/hooks.ts
0 → 100644
View file @
671654da
import
{
useState
}
from
'react'
import
{
flip
,
offset
,
shift
,
useDismiss
,
useFloating
,
useInteractions
,
}
from
'@floating-ui/react'
export
const
useAddBranch
=
()
=>
{
const
[
isOpen
,
setIsOpen
]
=
useState
(
false
)
const
[
dismissEnable
,
setDismissEnable
]
=
useState
(
true
)
const
{
refs
,
floatingStyles
,
context
}
=
useFloating
({
placement
:
'bottom'
,
strategy
:
'fixed'
,
open
:
isOpen
,
onOpenChange
:
setIsOpen
,
middleware
:
[
flip
(),
shift
(),
offset
(
4
),
],
})
const
dismiss
=
useDismiss
(
context
,
{
enabled
:
dismissEnable
,
})
const
{
getFloatingProps
}
=
useInteractions
([
dismiss
,
])
return
{
refs
,
floatingStyles
,
getFloatingProps
,
isOpen
,
setIsOpen
,
setDismissEnable
,
}
}
web/app/components/workflow/nodes/_base/components/add-node/index.tsx
0 → 100644
View file @
671654da
import
type
{
FC
,
MouseEvent
}
from
'react'
import
{
memo
,
useMemo
,
}
from
'react'
import
{
FloatingPortal
}
from
'@floating-ui/react'
import
{
useBlockSelectorContext
}
from
'../../../../block-selector/context'
import
type
{
BlockEnum
,
Node
,
}
from
'../../../../types'
import
{
useAddBranch
}
from
'./hooks'
import
{
Plus02
}
from
'@/app/components/base/icons/src/vender/line/general'
type
AddNodeProps
=
{
outgoers
:
Node
[]
onAddNextNode
:
(
type
:
BlockEnum
)
=>
void
branches
?:
{
id
:
string
;
name
:
string
}[]
}
const
AddNode
:
FC
<
AddNodeProps
>
=
({
onAddNextNode
,
branches
,
})
=>
{
const
{
refs
,
isOpen
,
setIsOpen
,
setDismissEnable
,
floatingStyles
,
getFloatingProps
,
}
=
useAddBranch
()
const
{
from
,
open
,
referenceRef
,
handleToggle
,
}
=
useBlockSelectorContext
()
const
hasBranches
=
branches
&&
!!
branches
.
length
const
handleAdd
=
(
e
:
MouseEvent
<
HTMLDivElement
>
)
=>
{
e
.
stopPropagation
()
if
(
hasBranches
)
return
setIsOpen
(
v
=>
!
v
)
handleToggle
({
placement
:
'right'
,
offset
:
6
,
callback
:
onAddNextNode
,
})
}
const
buttonRef
=
useMemo
(()
=>
{
if
(
hasBranches
)
return
refs
.
setReference
if
(
from
===
'node'
)
return
referenceRef
return
null
},
[
from
,
hasBranches
,
referenceRef
,
refs
.
setReference
])
const
buttonShouldShow
=
useMemo
(()
=>
{
if
(
hasBranches
&&
isOpen
)
return
true
return
open
&&
from
===
'node'
},
[
from
,
hasBranches
,
isOpen
,
open
])
return
(
<>
<
div
ref=
{
buttonRef
}
onClick=
{
handleAdd
}
className=
{
`
hidden absolute -bottom-2 left-1/2 -translate-x-1/2 items-center justify-center
w-4 h-4 rounded-full bg-primary-600 cursor-pointer z-10 group-hover:flex
${buttonShouldShow && '!flex'}
`
}
>
<
Plus02
className=
'w-2.5 h-2.5 text-white'
/>
</
div
>
{
isOpen
&&
hasBranches
&&
(
<
FloatingPortal
>
<
div
ref=
{
refs
.
setFloating
}
style=
{
floatingStyles
}
{
...
getFloatingProps
()}
className=
'p-1 w-[108px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg'
>
{
branches
.
map
(
branch
=>
(
<
div
key=
{
branch
.
id
}
className=
'flex items-center px-3 pr-2 h-[30px] text-[13px] font-medium text-gray-700 cursor-pointer rounded-lg hover:bg-gray-50'
onClick=
{
()
=>
{
setDismissEnable
(
false
)
handleToggle
({
open
:
true
,
placement
:
'right'
,
offset
:
6
,
callback
:
onAddNextNode
,
})
}
}
>
{
branch
.
name
}
</
div
>
))
}
</
div
>
</
FloatingPortal
>
)
}
</>
)
}
export
default
memo
(
AddNode
)
web/app/components/workflow/nodes/_base/components/next-step.tsx
View file @
671654da
...
...
@@ -6,10 +6,8 @@ import {
}
from
'react'
import
{
getOutgoers
}
from
'reactflow'
import
BlockIcon
from
'../../../block-icon'
import
type
{
BlockEnum
,
Node
,
}
from
'../../../types'
import
type
{
Node
}
from
'../../../types'
import
{
BlockEnum
}
from
'../../../types'
import
{
useWorkflowContext
}
from
'../../../context'
import
{
useBlockSelectorContext
}
from
'../../../block-selector/context'
import
{
Plus
}
from
'@/app/components/base/icons/src/vender/line/general'
...
...
@@ -46,30 +44,6 @@ const NextStep: FC<NextStepProps> = ({
</
div
>
<
div
className=
'shrink-0 w-6'
></
div
>
<
div
className=
'grow'
>
{
!
outgoers
.
length
&&
(
<
div
onClick=
{
()
=>
{
handleToggle
({
from
:
'panel'
,
className
:
'w-[328px]'
,
callback
:
handleSelectBlock
,
})
}
}
ref=
{
from
===
'panel'
?
referenceRef
:
null
}
className=
{
`
flex items-center px-2 w-[328px] h-9 rounded-lg border border-dashed border-gray-200 bg-gray-50
hover:bg-gray-100 text-xs text-gray-500 cursor-pointer
${open && from === 'panel' && '!bg-gray-100'}
`
}
>
<
div
className=
'flex items-center justify-center mr-1.5 w-5 h-5 rounded-[5px] bg-gray-200'
>
<
Plus
className=
'w-3 h-3'
/>
</
div
>
SELECT NEXT BLOCK
</
div
>
)
}
{
!!
outgoers
.
length
&&
outgoers
.
map
(
outgoer
=>
(
<
div
...
...
@@ -88,7 +62,10 @@ const NextStep: FC<NextStepProps> = ({
from
:
'panel'
,
className
:
'w-[328px]'
,
placement
:
'top-end'
,
offset
:
6
,
offset
:
{
mainAxis
:
6
,
crossAxis
:
8
,
},
})
}
}
>
...
...
@@ -104,6 +81,30 @@ const NextStep: FC<NextStepProps> = ({
</
div
>
))
}
{
(
!
outgoers
.
length
||
selectedNode
.
data
.
type
===
BlockEnum
.
IfElse
)
&&
(
<
div
onClick=
{
()
=>
{
handleToggle
({
from
:
'panel'
,
className
:
'w-[328px]'
,
callback
:
handleSelectBlock
,
})
}
}
ref=
{
from
===
'panel'
?
referenceRef
:
null
}
className=
{
`
flex items-center px-2 w-[328px] h-9 rounded-lg border border-dashed border-gray-200 bg-gray-50
hover:bg-gray-100 text-xs text-gray-500 cursor-pointer
${open && from === 'panel' && '!bg-gray-100'}
`
}
>
<
div
className=
'flex items-center justify-center mr-1.5 w-5 h-5 rounded-[5px] bg-gray-200'
>
<
Plus
className=
'w-3 h-3'
/>
</
div
>
SELECT NEXT BLOCK
</
div
>
)
}
</
div
>
</
div
>
)
...
...
web/app/components/workflow/nodes/_base/node.tsx
View file @
671654da
...
...
@@ -11,11 +11,10 @@ import {
import
type
{
NodeProps
}
from
'reactflow'
import
{
getOutgoers
}
from
'reactflow'
import
{
useWorkflowContext
}
from
'../../context'
import
type
{
BlockEnum
}
from
'../../types'
import
{
useBlockSelectorContext
}
from
'../../block-selector/context'
import
{
BlockEnum
}
from
'../../types'
import
NodeControl
from
'../../node-control'
import
BlockIcon
from
'../../block-icon'
import
{
Plus02
}
from
'@/app/components/base/icons/src/vender/line/general
'
import
AddNode
from
'./components/add-node/index
'
type
BaseNodeProps
=
{
children
:
ReactElement
...
...
@@ -33,12 +32,6 @@ const BaseNode: FC<BaseNodeProps> = ({
handleSelectedNodeIdChange
,
handleAddNextNode
,
}
=
useWorkflowContext
()
const
{
from
,
open
,
referenceRef
,
handleToggle
,
}
=
useBlockSelectorContext
()
const
currentNode
=
useMemo
(()
=>
{
return
nodes
.
find
(
node
=>
node
.
id
===
nodeId
)
},
[
nodeId
,
nodes
])
...
...
@@ -48,6 +41,20 @@ const BaseNode: FC<BaseNodeProps> = ({
const
handleSelectBlock
=
useCallback
((
type
:
BlockEnum
)
=>
{
handleAddNextNode
(
currentNode
!
,
type
)
},
[
currentNode
,
handleAddNextNode
])
const
branches
=
useMemo
(()
=>
{
if
(
data
.
type
===
BlockEnum
.
IfElse
)
{
return
[
{
id
:
'1'
,
name
:
'Is True'
,
},
{
id
:
'2'
,
name
:
'Is False'
,
},
]
}
},
[
data
])
return
(
<
div
...
...
@@ -73,28 +80,11 @@ const BaseNode: FC<BaseNodeProps> = ({
<
div
className=
'px-3 pt-1 pb-1 text-xs text-gray-500'
>
Define the initial parameters for launching a workflow
</
div
>
{
!
outgoers
.
length
&&
(
<
div
ref=
{
from
===
'node'
?
referenceRef
:
null
}
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
()
handleToggle
({
placement
:
'right'
,
offset
:
6
,
callback
:
handleSelectBlock
,
})
}
}
className=
{
`
hidden absolute -bottom-2 left-1/2 -translate-x-1/2 items-center justify-center
w-4 h-4 rounded-full bg-primary-600 cursor-pointer z-10 group-hover:flex
${open && from === 'node' && '!flex'}
`
}
>
<
Plus02
className=
'w-2.5 h-2.5 text-white'
/>
</
div
>
)
}
<
AddNode
outgoers=
{
outgoers
}
branches=
{
branches
}
onAddNextNode=
{
handleSelectBlock
}
/>
</
div
>
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment