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
d2d6904c
Commit
d2d6904c
authored
Feb 28, 2024
by
StyleZhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
panel-operator
parent
510f0593
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
178 additions
and
138 deletions
+178
-138
page.tsx
web/app/(commonLayout)/workflow/page.tsx
+1
-0
hooks.ts
web/app/components/workflow/hooks.ts
+59
-40
index.tsx
web/app/components/workflow/index.tsx
+12
-65
index.tsx
...nents/workflow/nodes/_base/components/next-step/index.tsx
+6
-3
panel-operator.tsx
...onents/workflow/nodes/_base/components/panel-operator.tsx
+77
-0
node.tsx
web/app/components/workflow/nodes/_base/node.tsx
+5
-5
panel.tsx
web/app/components/workflow/nodes/_base/panel.tsx
+7
-9
index.tsx
web/app/components/workflow/nodes/index.tsx
+3
-2
index.tsx
...app/components/workflow/panel/debug-and-preview/index.tsx
+1
-1
index.tsx
web/app/components/workflow/panel/index.tsx
+5
-2
run-history.tsx
web/app/components/workflow/panel/run-history.tsx
+1
-1
workflow-info.tsx
web/app/components/workflow/panel/workflow-info.tsx
+1
-1
store.ts
web/app/components/workflow/store.ts
+0
-5
types.ts
web/app/components/workflow/types.ts
+0
-2
utils.ts
web/app/components/workflow/utils.ts
+0
-2
No files found.
web/app/(commonLayout)/workflow/page.tsx
View file @
d2d6904c
...
...
@@ -57,6 +57,7 @@ const initialEdges = [
sourceHandle
:
'source'
,
target
:
'2'
,
targetHandle
:
'target'
,
deletable
:
false
,
},
{
id
:
'1'
,
...
...
web/app/components/workflow/hooks.ts
View file @
d2d6904c
...
...
@@ -14,12 +14,10 @@ import type {
SelectedNode
,
}
from
'./types'
import
{
NodeInitialData
}
from
'./constants'
import
{
useStore
}
from
'./store'
import
{
initialNodesPosition
}
from
'./utils'
export
const
useWorkflow
=
()
=>
{
const
store
=
useStoreApi
()
const
setSelectedNode
=
useStore
(
state
=>
state
.
setSelectedNode
)
const
handleEnterNode
=
useCallback
<
NodeMouseHandler
>
((
_
,
node
)
=>
{
const
{
...
...
@@ -71,6 +69,25 @@ export const useWorkflow = () => {
setEdges
(
newEdges
)
},
[
store
])
const
handleSelectNode
=
useCallback
((
nodeId
:
string
,
cancelSelection
?:
boolean
)
=>
{
const
{
getNodes
,
setNodes
,
}
=
store
.
getState
()
const
newNodes
=
produce
(
getNodes
(),
(
draft
)
=>
{
const
selectedNode
=
draft
.
find
(
node
=>
node
.
id
===
nodeId
)
if
(
selectedNode
)
{
if
(
cancelSelection
)
selectedNode
.
selected
=
false
else
selectedNode
.
selected
=
true
}
})
setNodes
(
newNodes
)
},
[
store
])
const
handleEnterEdge
=
useCallback
<
EdgeMouseHandler
>
((
_
,
edge
)
=>
{
const
{
edges
,
...
...
@@ -97,33 +114,19 @@ export const useWorkflow = () => {
setEdges
(
newEdges
)
},
[
store
])
const
handle
SelectNode
=
useCallback
((
selectNode
:
SelectedNode
,
cancelSelection
?:
boolean
)
=>
{
const
handle
DeleteEdge
=
useCallback
((
)
=>
{
const
{
getNod
es
,
set
Nod
es
,
edg
es
,
set
Edg
es
,
}
=
store
.
getState
()
if
(
cancelSelection
)
{
setSelectedNode
(
null
)
const
newNodes
=
produce
(
getNodes
(),
(
draft
)
=>
{
draft
.
forEach
((
item
)
=>
{
item
.
data
.
selected
=
false
})
})
setNodes
(
newNodes
)
}
else
{
setSelectedNode
(
selectNode
)
const
newNodes
=
produce
(
getNodes
(),
(
draft
)
=>
{
draft
.
forEach
((
item
)
=>
{
if
(
item
.
id
===
selectNode
.
id
)
item
.
data
.
selected
=
true
else
item
.
data
.
selected
=
false
})
})
setNodes
(
newNodes
)
}
},
[
setSelectedNode
,
store
])
const
newEdges
=
produce
(
edges
,
(
draft
)
=>
{
const
index
=
draft
.
findIndex
(
edge
=>
edge
.
selected
)
if
(
index
>
-
1
)
draft
.
splice
(
index
,
1
)
})
setEdges
(
newEdges
)
},
[
store
])
const
handleUpdateNodeData
=
useCallback
(({
id
,
data
}:
SelectedNode
)
=>
{
const
{
...
...
@@ -136,8 +139,7 @@ export const useWorkflow = () => {
currentNode
.
data
=
{
...
currentNode
.
data
,
...
data
}
})
setNodes
(
newNodes
)
setSelectedNode
({
id
,
data
})
},
[
store
,
setSelectedNode
])
},
[
store
])
const
handleAddNextNode
=
useCallback
((
currentNodeId
:
string
,
nodeType
:
BlockEnum
,
sourceHandle
:
string
)
=>
{
const
{
...
...
@@ -151,10 +153,7 @@ export const useWorkflow = () => {
const
nextNode
:
Node
=
{
id
:
`
${
Date
.
now
()}
`
,
type
:
'custom'
,
data
:
{
...
NodeInitialData
[
nodeType
],
selected
:
true
,
},
data
:
NodeInitialData
[
nodeType
],
position
:
{
x
:
currentNode
.
position
.
x
+
304
,
y
:
currentNode
.
position
.
y
,
...
...
@@ -179,8 +178,7 @@ export const useWorkflow = () => {
draft
.
push
(
newEdge
)
})
setEdges
(
newEdges
)
setSelectedNode
(
nextNode
)
},
[
store
,
setSelectedNode
])
},
[
store
])
const
handleChangeCurrentNode
=
useCallback
((
parentNodeId
:
string
,
currentNodeId
:
string
,
nodeType
:
BlockEnum
,
sourceHandle
:
string
)
=>
{
const
{
...
...
@@ -195,10 +193,7 @@ export const useWorkflow = () => {
const
newCurrentNode
:
Node
=
{
id
:
`
${
Date
.
now
()}
`
,
type
:
'custom'
,
data
:
{
...
NodeInitialData
[
nodeType
],
selected
:
true
,
},
data
:
NodeInitialData
[
nodeType
],
position
:
{
x
:
currentNode
.
position
.
x
,
y
:
currentNode
.
position
.
y
,
...
...
@@ -227,6 +222,28 @@ export const useWorkflow = () => {
setEdges
(
newEdges
)
},
[
store
])
const
handleDeleteNode
=
useCallback
((
nodeId
:
string
)
=>
{
const
{
getNodes
,
setNodes
,
edges
,
setEdges
,
}
=
store
.
getState
()
const
newNodes
=
produce
(
getNodes
(),
(
draft
)
=>
{
const
index
=
draft
.
findIndex
(
node
=>
node
.
id
===
nodeId
)
if
(
index
>
-
1
)
draft
.
splice
(
index
,
1
)
})
setNodes
(
newNodes
)
const
connectedEdges
=
getConnectedEdges
([{
id
:
nodeId
}
as
Node
],
edges
)
const
newEdges
=
produce
(
edges
,
(
draft
)
=>
{
return
draft
.
filter
(
edge
=>
!
connectedEdges
.
find
(
connectedEdge
=>
connectedEdge
.
id
===
edge
.
id
))
})
setEdges
(
newEdges
)
},
[
store
])
const
handleInitialLayoutNodes
=
useCallback
(()
=>
{
const
{
getNodes
,
...
...
@@ -283,12 +300,14 @@ export const useWorkflow = () => {
return
{
handleEnterNode
,
handleLeaveNode
,
handleSelectNode
,
handleEnterEdge
,
handleLeaveEdge
,
handle
SelectNod
e
,
handle
DeleteEdg
e
,
handleUpdateNodeData
,
handleAddNextNode
,
handleChangeCurrentNode
,
handleDeleteNode
,
handleInitialLayoutNodes
,
handleUpdateNodesPosition
,
}
...
...
web/app/components/workflow/index.tsx
View file @
d2d6904c
import
type
{
FC
}
from
'react'
import
{
memo
,
useEffect
,
useMemo
,
}
from
'react'
import
produce
from
'immer'
import
type
{
Edge
}
from
'reactflow'
import
{
memo
}
from
'react'
import
{
useKeyPress
}
from
'ahooks'
import
ReactFlow
,
{
Background
,
ReactFlowProvider
,
useEdgesState
,
// useNodesInitialized,
useNodesState
,
}
from
'reactflow'
import
'reactflow/dist/style.css'
import
type
{
Edge
,
Node
,
}
from
'./types'
import
{
useWorkflow
}
from
'./hooks'
import
Header
from
'./header'
import
CustomNode
from
'./nodes'
...
...
@@ -21,7 +19,6 @@ import ZoomInOut from './zoom-in-out'
import
CustomEdge
from
'./custom-edge'
import
CustomConnectionLine
from
'./custom-connection-line'
import
Panel
from
'./panel'
import
{
BlockEnum
,
type
Node
}
from
'./types'
const
nodeTypes
=
{
custom
:
CustomNode
,
...
...
@@ -31,73 +28,25 @@ const edgeTypes = {
}
type
WorkflowProps
=
{
selectedNodeId
?:
string
nodes
:
Node
[]
edges
:
Edge
[]
}
const
Workflow
:
FC
<
WorkflowProps
>
=
memo
(({
nodes
:
initialNodes
,
edges
:
initialEdges
,
selectedNodeId
:
initialSelectedNodeId
,
})
=>
{
const
initialData
:
{
nodes
:
Node
[]
edges
:
Edge
[]
needUpdatePosition
:
boolean
}
=
useMemo
(()
=>
{
const
start
=
initialNodes
.
find
(
node
=>
node
.
data
.
type
===
BlockEnum
.
Start
)
if
(
start
?.
position
)
{
return
{
nodes
:
initialNodes
,
edges
:
initialEdges
,
needUpdatePosition
:
false
,
}
}
return
{
nodes
:
produce
(
initialNodes
,
(
draft
)
=>
{
draft
.
forEach
((
node
)
=>
{
node
.
position
=
{
x
:
0
,
y
:
0
}
node
.
data
=
{
...
node
.
data
,
hidden
:
true
}
})
}),
edges
:
produce
(
initialEdges
,
(
draft
)
=>
{
draft
.
forEach
((
edge
)
=>
{
edge
.
hidden
=
true
})
}),
needUpdatePosition
:
true
,
}
},
[
initialNodes
,
initialEdges
])
// const nodesInitialized = useNodesInitialized({
// includeHiddenNodes: true,
// })
const
[
nodes
,
setNodes
,
onNodesChange
]
=
useNodesState
(
initialData
.
nodes
)
const
[
edges
,
setEdges
,
onEdgesChange
]
=
useEdgesState
(
initialData
.
edges
)
const
[
nodes
]
=
useNodesState
(
initialNodes
)
const
[
edges
,
_
,
onEdgesChange
]
=
useEdgesState
(
initialEdges
)
const
{
handleEnterNode
,
handleLeaveNode
,
handleEnterEdge
,
handleLeaveEdge
,
handleSelectNode
,
handleInitialLayoutNodes
,
handleDeleteEdge
,
}
=
useWorkflow
()
// useEffect(() => {
// if (nodesInitialized)
// handleInitialLayoutNodes()
// }, [nodesInitialized])
useEffect
(()
=>
{
if
(
initialSelectedNodeId
)
{
const
initialSelectedNode
=
nodes
.
find
(
n
=>
n
.
id
===
initialSelectedNodeId
)
if
(
initialSelectedNode
)
handleSelectNode
({
id
:
initialSelectedNodeId
,
data
:
initialSelectedNode
.
data
})
}
},
[
initialSelectedNodeId
])
useKeyPress
(
'Backspace'
,
handleDeleteEdge
)
return
(
<
div
className=
'relative w-full h-full'
>
...
...
@@ -111,11 +60,12 @@ const Workflow: FC<WorkflowProps> = memo(({
edges=
{
edges
}
onNodeMouseEnter=
{
handleEnterNode
}
onNodeMouseLeave=
{
handleLeaveNode
}
onEdgesChange=
{
onEdgesChange
}
onEdgeMouseEnter=
{
handleEnterEdge
}
onEdgeMouseLeave=
{
handleLeaveEdge
}
onEdgesChange=
{
onEdgesChange
}
multiSelectionKeyCode=
{
null
}
connectionLineComponent=
{
CustomConnectionLine
}
deleteKeyCode=
{
null
}
>
<
Background
gap=
{
[
14
,
14
]
}
...
...
@@ -129,15 +79,12 @@ const Workflow: FC<WorkflowProps> = memo(({
Workflow
.
displayName
=
'Workflow'
const
WorkflowWrap
:
FC
<
WorkflowProps
>
=
({
selectedNodeId
,
nodes
,
edges
,
})
=>
{
return
(
<
ReactFlowProvider
>
{
selectedNodeId
}
<
Workflow
selectedNodeId=
{
selectedNodeId
}
nodes=
{
nodes
}
edges=
{
edges
}
/>
...
...
web/app/components/workflow/nodes/_base/components/next-step/index.tsx
View file @
d2d6904c
...
...
@@ -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
)
...
...
web/app/components/workflow/nodes/_base/components/panel-operator.tsx
0 → 100644
View file @
d2d6904c
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
)
web/app/components/workflow/nodes/_base/node.tsx
View file @
d2d6904c
...
...
@@ -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
>
)
}
...
...
web/app/components/workflow/nodes/_base/panel.tsx
View file @
d2d6904c
...
...
@@ -7,23 +7,23 @@ import {
memo
,
useCallback
,
}
from
'react'
import
type
{
Selected
Node
}
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
}
&
Selected
Node
}
&
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
>
)
...
...
web/app/components/workflow/nodes/index.tsx
View file @
d2d6904c
import
{
memo
}
from
'react'
import
type
{
NodeProps
}
from
'reactflow'
import
{
BlockEnum
,
type
SelectedNode
}
from
'../types'
import
type
{
Node
}
from
'../types'
import
{
BlockEnum
}
from
'../types'
import
{
NodeComponentMap
,
PanelComponentMap
,
...
...
@@ -44,7 +45,7 @@ const CustomNode = memo((props: NodeProps) => {
})
CustomNode
.
displayName
=
'CustomNode'
export
const
Panel
=
memo
((
props
:
Selected
Node
)
=>
{
export
const
Panel
=
memo
((
props
:
Node
)
=>
{
const
nodeData
=
props
.
data
const
PanelComponent
=
PanelComponentMap
[
nodeData
.
type
]
...
...
web/app/components/workflow/panel/debug-and-preview/index.tsx
View file @
d2d6904c
...
...
@@ -4,7 +4,7 @@ import ChatWrapper from './chat-wrapper'
const
DebugAndPreview
:
FC
=
()
=>
{
return
(
<
div
className=
'flex flex-col w-[400px] h-full rounded-l-2xl border border-black/[0.02] shadow-xl
z-10
'
className=
'flex flex-col w-[400px] h-full rounded-l-2xl border border-black/[0.02] shadow-xl'
style=
{
{
background
:
'linear-gradient(156deg, rgba(242, 244, 247, 0.80) 0%, rgba(242, 244, 247, 0.00) 99.43%), var(--white, #FFF)'
}
}
>
<
div
className=
'shrink-0 flex items-center justify-between px-4 pt-3 pb-2'
>
...
...
web/app/components/workflow/panel/index.tsx
View file @
d2d6904c
...
...
@@ -3,6 +3,8 @@ import {
memo
,
useMemo
,
}
from
'react'
import
{
useNodes
}
from
'reactflow'
import
type
{
CommonNodeType
}
from
'../types'
import
{
Panel
as
NodePanel
}
from
'../nodes'
import
{
useStore
}
from
'../store'
import
WorkflowInfo
from
'./workflow-info'
...
...
@@ -11,7 +13,8 @@ import RunHistory from './run-history'
const
Panel
:
FC
=
()
=>
{
const
mode
=
useStore
(
state
=>
state
.
mode
)
const
selectedNode
=
useStore
(
state
=>
state
.
selectedNode
)
const
nodes
=
useNodes
<
CommonNodeType
>
()
const
selectedNode
=
nodes
.
find
(
node
=>
node
.
selected
)
const
showRunHistory
=
useStore
(
state
=>
state
.
showRunHistory
)
const
{
showWorkflowInfoPanel
,
...
...
@@ -26,7 +29,7 @@ const Panel: FC = () => {
},
[
mode
,
selectedNode
])
return
(
<
div
className=
'absolute top-14 right-0 bottom-2 flex'
>
<
div
className=
'absolute top-14 right-0 bottom-2 flex
z-10
'
>
{
showNodePanel
&&
(
<
NodePanel
{
...
selectedNode
!}
/>
...
...
web/app/components/workflow/panel/run-history.tsx
View file @
d2d6904c
...
...
@@ -10,7 +10,7 @@ const RunHistory = () => {
const
setShowRunHistory
=
useStore
(
state
=>
state
.
setShowRunHistory
)
return
(
<
div
className=
'w-[200px] h-full bg-white border-[0.5px] border-gray-200 shadow-xl rounded-l-2xl
z-10
'
>
<
div
className=
'w-[200px] h-full bg-white border-[0.5px] border-gray-200 shadow-xl rounded-l-2xl'
>
<
div
className=
'flex items-center justify-between px-4 pt-3 text-base font-semibold text-gray-900'
>
Run History
<
div
...
...
web/app/components/workflow/panel/workflow-info.tsx
View file @
d2d6904c
...
...
@@ -7,7 +7,7 @@ import { FileCheck02 } from '@/app/components/base/icons/src/vender/line/files'
const
WorkflowInfo
:
FC
=
()
=>
{
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 pt-4 px-4 pb-1'
>
<
div
className=
'mr-3 w-10 h-10'
></
div
>
...
...
web/app/components/workflow/store.ts
View file @
d2d6904c
import
{
create
}
from
'zustand'
import
type
{
SelectedNode
}
from
'./types'
type
State
=
{
mode
:
string
selectedNode
:
SelectedNode
|
null
showRunHistory
:
boolean
}
type
Action
=
{
setSelectedNode
:
(
node
:
SelectedNode
|
null
)
=>
void
setShowRunHistory
:
(
showRunHistory
:
boolean
)
=>
void
}
export
const
useStore
=
create
<
State
&
Action
>
(
set
=>
({
mode
:
'workflow'
,
selectedNode
:
null
,
setSelectedNode
:
node
=>
set
(()
=>
({
selectedNode
:
node
})),
showRunHistory
:
false
,
setShowRunHistory
:
showRunHistory
=>
set
(()
=>
({
showRunHistory
})),
}))
web/app/components/workflow/types.ts
View file @
d2d6904c
...
...
@@ -24,13 +24,11 @@ export type Branch = {
}
export
type
CommonNodeType
=
{
hidden
?:
boolean
position
?:
{
x
:
number
y
:
number
}
sortIndexInBranches
?:
number
selected
?:
boolean
hovering
?:
boolean
branches
?:
Branch
[]
title
:
string
...
...
web/app/components/workflow/utils.ts
View file @
d2d6904c
...
...
@@ -12,7 +12,6 @@ export const initialNodesPosition = (oldNodes: Node[], edges: Edge[]) => {
const
nodes
=
cloneDeep
(
oldNodes
)
const
start
=
nodes
.
find
(
node
=>
node
.
data
.
type
===
BlockEnum
.
Start
)
!
start
.
data
.
hidden
=
false
start
.
position
.
x
=
0
start
.
position
.
y
=
0
start
.
data
.
position
=
{
...
...
@@ -38,7 +37,6 @@ export const initialNodesPosition = (oldNodes: Node[], edges: Edge[]) => {
if
(
outgoers
.
length
)
{
queue
.
push
(...
outgoers
.
map
((
outgoer
)
=>
{
outgoer
.
data
.
hidden
=
false
outgoer
.
data
.
position
=
{
x
:
depth
+
1
,
y
:
breadth
,
...
...
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