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
f14a5c73
Commit
f14a5c73
authored
Feb 20, 2024
by
StyleZhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add node-control
parent
92219b5a
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
276 additions
and
2 deletions
+276
-2
plus-02.svg
...ponents/base/icons/assets/vender/line/general/plus-02.svg
+5
-0
play.svg
...ts/base/icons/assets/vender/line/mediaAndDevices/play.svg
+5
-0
stop.svg
...ts/base/icons/assets/vender/line/mediaAndDevices/stop.svg
+10
-0
Plus02.json
...components/base/icons/src/vender/line/general/Plus02.json
+39
-0
Plus02.tsx
.../components/base/icons/src/vender/line/general/Plus02.tsx
+16
-0
index.ts
...pp/components/base/icons/src/vender/line/general/index.ts
+1
-0
Play.json
...ents/base/icons/src/vender/line/mediaAndDevices/Play.json
+39
-0
Play.tsx
...nents/base/icons/src/vender/line/mediaAndDevices/Play.tsx
+16
-0
Stop.json
...ents/base/icons/src/vender/line/mediaAndDevices/Stop.json
+66
-0
Stop.tsx
...nents/base/icons/src/vender/line/mediaAndDevices/Stop.tsx
+16
-0
index.ts
...nents/base/icons/src/vender/line/mediaAndDevices/index.ts
+2
-0
context.tsx
web/app/components/workflow/context.tsx
+2
-0
hooks.ts
web/app/components/workflow/hooks.ts
+11
-0
index.tsx
web/app/components/workflow/index.tsx
+2
-0
node-control.tsx
web/app/components/workflow/node-control.tsx
+42
-0
node.tsx
web/app/components/workflow/nodes/_base/node.tsx
+4
-2
No files found.
web/app/components/base/icons/assets/vender/line/general/plus-02.svg
0 → 100644
View file @
f14a5c73
<svg
width=
"10"
height=
"10"
viewBox=
"0 0 10 10"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<g
id=
"plus"
>
<path
id=
"Icon"
d=
"M5.00004 2.08325V7.91659M2.08337 4.99992H7.91671"
stroke=
"white"
stroke-width=
"1.5"
stroke-linecap=
"round"
stroke-linejoin=
"round"
/>
</g>
</svg>
web/app/components/base/icons/assets/vender/line/mediaAndDevices/play.svg
0 → 100644
View file @
f14a5c73
<svg
width=
"12"
height=
"12"
viewBox=
"0 0 12 12"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<g
id=
"Icon"
>
<path
id=
"Icon_2"
d=
"M2.5 2.49482C2.5 2.00924 2.5 1.76644 2.60125 1.63261C2.68945 1.51601 2.82426 1.44386 2.9702 1.43515C3.13772 1.42515 3.33973 1.55982 3.74376 1.82918L9.00154 5.33436C9.33538 5.55693 9.5023 5.66821 9.56047 5.80847C9.61133 5.9311 9.61133 6.06891 9.56047 6.19154C9.5023 6.3318 9.33538 6.44308 9.00154 6.66564L3.74376 10.1708C3.33973 10.4402 3.13772 10.5749 2.9702 10.5649C2.82426 10.5561 2.68945 10.484 2.60125 10.3674C2.5 10.2336 2.5 9.99077 2.5 9.50519V2.49482Z"
stroke=
"#667085"
stroke-width=
"1.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
/>
</g>
</svg>
web/app/components/base/icons/assets/vender/line/mediaAndDevices/stop.svg
0 → 100644
View file @
f14a5c73
<svg
width=
"12"
height=
"12"
viewBox=
"0 0 12 12"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<g
id=
"Icon"
clip-path=
"url(#clip0_467_1645)"
>
<path
id=
"Icon_2"
d=
"M1.5 3.9C1.5 3.05992 1.5 2.63988 1.66349 2.31901C1.8073 2.03677 2.03677 1.8073 2.31901 1.66349C2.63988 1.5 3.05992 1.5 3.9 1.5H8.1C8.94008 1.5 9.36012 1.5 9.68099 1.66349C9.96323 1.8073 10.1927 2.03677 10.3365 2.31901C10.5 2.63988 10.5 3.05992 10.5 3.9V8.1C10.5 8.94008 10.5 9.36012 10.3365 9.68099C10.1927 9.96323 9.96323 10.1927 9.68099 10.3365C9.36012 10.5 8.94008 10.5 8.1 10.5H3.9C3.05992 10.5 2.63988 10.5 2.31901 10.3365C2.03677 10.1927 1.8073 9.96323 1.66349 9.68099C1.5 9.36012 1.5 8.94008 1.5 8.1V3.9Z"
stroke=
"#667085"
stroke-width=
"1.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
/>
</g>
<defs>
<clipPath
id=
"clip0_467_1645"
>
<rect
width=
"12"
height=
"12"
fill=
"white"
/>
</clipPath>
</defs>
</svg>
web/app/components/base/icons/src/vender/line/general/Plus02.json
0 → 100644
View file @
f14a5c73
{
"icon"
:
{
"type"
:
"element"
,
"isRootNode"
:
true
,
"name"
:
"svg"
,
"attributes"
:
{
"width"
:
"10"
,
"height"
:
"10"
,
"viewBox"
:
"0 0 10 10"
,
"fill"
:
"none"
,
"xmlns"
:
"http://www.w3.org/2000/svg"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"g"
,
"attributes"
:
{
"id"
:
"plus"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"path"
,
"attributes"
:
{
"id"
:
"Icon"
,
"d"
:
"M5.00004 2.08325V7.91659M2.08337 4.99992H7.91671"
,
"stroke"
:
"currentColor"
,
"stroke-width"
:
"1.5"
,
"stroke-linecap"
:
"round"
,
"stroke-linejoin"
:
"round"
},
"children"
:
[]
}
]
}
]
},
"name"
:
"Plus02"
}
\ No newline at end of file
web/app/components/base/icons/src/vender/line/general/Plus02.tsx
0 → 100644
View file @
f14a5c73
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import
*
as
React
from
'react'
import
data
from
'./Plus02.json'
import
IconBase
from
'@/app/components/base/icons/IconBase'
import
type
{
IconBaseProps
,
IconData
}
from
'@/app/components/base/icons/IconBase'
const
Icon
=
React
.
forwardRef
<
React
.
MutableRefObject
<
SVGElement
>
,
Omit
<
IconBaseProps
,
'data'
>>
((
props
,
ref
,
)
=>
<
IconBase
{
...
props
}
ref=
{
ref
}
data=
{
data
as
IconData
}
/>)
Icon
.
displayName
=
'Plus02'
export
default
Icon
web/app/components/base/icons/src/vender/line/general/index.ts
View file @
f14a5c73
...
...
@@ -19,6 +19,7 @@ export { default as LogOut04 } from './LogOut04'
export
{
default
as
Menu01
}
from
'./Menu01'
export
{
default
as
Pin01
}
from
'./Pin01'
export
{
default
as
Pin02
}
from
'./Pin02'
export
{
default
as
Plus02
}
from
'./Plus02'
export
{
default
as
Plus
}
from
'./Plus'
export
{
default
as
SearchLg
}
from
'./SearchLg'
export
{
default
as
Settings01
}
from
'./Settings01'
...
...
web/app/components/base/icons/src/vender/line/mediaAndDevices/Play.json
0 → 100644
View file @
f14a5c73
{
"icon"
:
{
"type"
:
"element"
,
"isRootNode"
:
true
,
"name"
:
"svg"
,
"attributes"
:
{
"width"
:
"12"
,
"height"
:
"12"
,
"viewBox"
:
"0 0 12 12"
,
"fill"
:
"none"
,
"xmlns"
:
"http://www.w3.org/2000/svg"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"g"
,
"attributes"
:
{
"id"
:
"Icon"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"path"
,
"attributes"
:
{
"id"
:
"Icon_2"
,
"d"
:
"M2.5 2.49482C2.5 2.00924 2.5 1.76644 2.60125 1.63261C2.68945 1.51601 2.82426 1.44386 2.9702 1.43515C3.13772 1.42515 3.33973 1.55982 3.74376 1.82918L9.00154 5.33436C9.33538 5.55693 9.5023 5.66821 9.56047 5.80847C9.61133 5.9311 9.61133 6.06891 9.56047 6.19154C9.5023 6.3318 9.33538 6.44308 9.00154 6.66564L3.74376 10.1708C3.33973 10.4402 3.13772 10.5749 2.9702 10.5649C2.82426 10.5561 2.68945 10.484 2.60125 10.3674C2.5 10.2336 2.5 9.99077 2.5 9.50519V2.49482Z"
,
"stroke"
:
"currentColor"
,
"stroke-width"
:
"1.25"
,
"stroke-linecap"
:
"round"
,
"stroke-linejoin"
:
"round"
},
"children"
:
[]
}
]
}
]
},
"name"
:
"Play"
}
\ No newline at end of file
web/app/components/base/icons/src/vender/line/mediaAndDevices/Play.tsx
0 → 100644
View file @
f14a5c73
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import
*
as
React
from
'react'
import
data
from
'./Play.json'
import
IconBase
from
'@/app/components/base/icons/IconBase'
import
type
{
IconBaseProps
,
IconData
}
from
'@/app/components/base/icons/IconBase'
const
Icon
=
React
.
forwardRef
<
React
.
MutableRefObject
<
SVGElement
>
,
Omit
<
IconBaseProps
,
'data'
>>
((
props
,
ref
,
)
=>
<
IconBase
{
...
props
}
ref=
{
ref
}
data=
{
data
as
IconData
}
/>)
Icon
.
displayName
=
'Play'
export
default
Icon
web/app/components/base/icons/src/vender/line/mediaAndDevices/Stop.json
0 → 100644
View file @
f14a5c73
{
"icon"
:
{
"type"
:
"element"
,
"isRootNode"
:
true
,
"name"
:
"svg"
,
"attributes"
:
{
"width"
:
"12"
,
"height"
:
"12"
,
"viewBox"
:
"0 0 12 12"
,
"fill"
:
"none"
,
"xmlns"
:
"http://www.w3.org/2000/svg"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"g"
,
"attributes"
:
{
"id"
:
"Icon"
,
"clip-path"
:
"url(#clip0_467_1645)"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"path"
,
"attributes"
:
{
"id"
:
"Icon_2"
,
"d"
:
"M1.5 3.9C1.5 3.05992 1.5 2.63988 1.66349 2.31901C1.8073 2.03677 2.03677 1.8073 2.31901 1.66349C2.63988 1.5 3.05992 1.5 3.9 1.5H8.1C8.94008 1.5 9.36012 1.5 9.68099 1.66349C9.96323 1.8073 10.1927 2.03677 10.3365 2.31901C10.5 2.63988 10.5 3.05992 10.5 3.9V8.1C10.5 8.94008 10.5 9.36012 10.3365 9.68099C10.1927 9.96323 9.96323 10.1927 9.68099 10.3365C9.36012 10.5 8.94008 10.5 8.1 10.5H3.9C3.05992 10.5 2.63988 10.5 2.31901 10.3365C2.03677 10.1927 1.8073 9.96323 1.66349 9.68099C1.5 9.36012 1.5 8.94008 1.5 8.1V3.9Z"
,
"stroke"
:
"currentColor"
,
"stroke-width"
:
"1.25"
,
"stroke-linecap"
:
"round"
,
"stroke-linejoin"
:
"round"
},
"children"
:
[]
}
]
},
{
"type"
:
"element"
,
"name"
:
"defs"
,
"attributes"
:
{},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"clipPath"
,
"attributes"
:
{
"id"
:
"clip0_467_1645"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"rect"
,
"attributes"
:
{
"width"
:
"12"
,
"height"
:
"12"
,
"fill"
:
"white"
},
"children"
:
[]
}
]
}
]
}
]
},
"name"
:
"Stop"
}
\ No newline at end of file
web/app/components/base/icons/src/vender/line/mediaAndDevices/Stop.tsx
0 → 100644
View file @
f14a5c73
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import
*
as
React
from
'react'
import
data
from
'./Stop.json'
import
IconBase
from
'@/app/components/base/icons/IconBase'
import
type
{
IconBaseProps
,
IconData
}
from
'@/app/components/base/icons/IconBase'
const
Icon
=
React
.
forwardRef
<
React
.
MutableRefObject
<
SVGElement
>
,
Omit
<
IconBaseProps
,
'data'
>>
((
props
,
ref
,
)
=>
<
IconBase
{
...
props
}
ref=
{
ref
}
data=
{
data
as
IconData
}
/>)
Icon
.
displayName
=
'Stop'
export
default
Icon
web/app/components/base/icons/src/vender/line/mediaAndDevices/index.ts
View file @
f14a5c73
export
{
default
as
Microphone01
}
from
'./Microphone01'
export
{
default
as
Play
}
from
'./Play'
export
{
default
as
SlidersH
}
from
'./SlidersH'
export
{
default
as
Speaker
}
from
'./Speaker'
export
{
default
as
Stop
}
from
'./Stop'
web/app/components/workflow/context.tsx
View file @
f14a5c73
...
...
@@ -18,6 +18,7 @@ export type WorkflowContextValue = {
handleSelectedNodeIdChange
:
(
nodeId
:
string
)
=>
void
selectedNode
?:
Node
handleAddNextNode
:
(
prevNode
:
Node
,
nextNodeType
:
BlockEnum
)
=>
void
handleUpdateNodeData
:
(
nodeId
:
string
,
data
:
Node
[
'data'
])
=>
void
}
export
const
WorkflowContext
=
createContext
<
WorkflowContextValue
>
({
...
...
@@ -26,5 +27,6 @@ export const WorkflowContext = createContext<WorkflowContextValue>({
edges
:
[],
handleSelectedNodeIdChange
:
()
=>
{},
handleAddNextNode
:
()
=>
{},
handleUpdateNodeData
:
()
=>
{},
})
export
const
useWorkflowContext
=
()
=>
useContext
(
WorkflowContext
)
web/app/components/workflow/hooks.ts
View file @
f14a5c73
...
...
@@ -60,10 +60,21 @@ export const useWorkflow = (
})
},
[
setNodes
,
setEdges
])
const
handleUpdateNodeData
=
useCallback
((
nodeId
:
string
,
data
:
Node
[
'data'
])
=>
{
setNodes
((
oldNodes
)
=>
{
return
produce
(
oldNodes
,
(
draft
)
=>
{
const
node
=
draft
.
find
(
node
=>
node
.
id
===
nodeId
)
if
(
node
)
node
.
data
=
data
})
})
},
[
setNodes
])
return
{
selectedNodeId
,
selectedNode
,
handleSelectedNodeIdChange
,
handleAddNextNode
,
handleUpdateNodeData
,
}
}
web/app/components/workflow/index.tsx
View file @
f14a5c73
...
...
@@ -73,6 +73,7 @@ const WorkflowWrap: FC<WorkflowWrapProps> = ({
handleSelectedNodeIdChange
,
selectedNode
,
handleAddNextNode
,
handleUpdateNodeData
,
}
=
useWorkflow
(
nodes
,
edges
,
...
...
@@ -90,6 +91,7 @@ const WorkflowWrap: FC<WorkflowWrapProps> = ({
nodes
,
edges
,
handleAddNextNode
,
handleUpdateNodeData
,
}
}
>
<
Workflow
/>
</
WorkflowContext
.
Provider
>
...
...
web/app/components/workflow/node-control.tsx
0 → 100644
View file @
f14a5c73
import
type
{
FC
}
from
'react'
import
{
memo
}
from
'react'
import
{
DotsHorizontal
,
Loading02
,
}
from
'@/app/components/base/icons/src/vender/line/general'
import
{
Play
,
Stop
,
}
from
'@/app/components/base/icons/src/vender/line/mediaAndDevices'
type
NodeControlProps
=
{
isRunning
?:
boolean
}
const
NodeControl
:
FC
<
NodeControlProps
>
=
({
isRunning
,
})
=>
{
return
(
<
div
className=
'absolute left-0 -top-7 flex items-center px-0.5 h-6 bg-white rounded-lg border-[0.5px] border-gray-100 shadow-xs text-gray-500'
>
{
isRunning
&&
(
<
div
className=
'flex items-center px-1 h-5 rounded-md bg-primary-50 text-xs font-medium text-primary-600'
>
<
Loading02
className=
'mr-1 w-3 h-3 animate-spin'
/>
RUNNING
</
div
>
)
}
<
div
className=
'flex items-center justify-center w-5 h-5 cursor-pointer'
>
{
isRunning
?
<
Stop
className=
'w-3 h-3'
/>
:
<
Play
className=
'w-3 h-3'
/>
}
</
div
>
<
div
className=
'flex items-center justify-center w-5 h-5 cursor-pointer'
>
<
DotsHorizontal
className=
'w-3 h-3'
/>
</
div
>
</
div
>
)
}
export
default
memo
(
NodeControl
)
web/app/components/workflow/nodes/_base/node.tsx
View file @
f14a5c73
...
...
@@ -12,8 +12,9 @@ import type { NodeProps } from 'reactflow'
import
{
getOutgoers
}
from
'reactflow'
import
{
useWorkflowContext
}
from
'../../context'
import
BlockSelector
from
'../../block-selector'
import
NodeControl
from
'../../node-control'
import
BlockIcon
from
'../../block-icon'
import
{
Plus
}
from
'@/app/components/base/icons/src/vender/line/general'
import
{
Plus
02
}
from
'@/app/components/base/icons/src/vender/line/general'
type
BaseNodeProps
=
{
children
:
ReactElement
...
...
@@ -48,7 +49,7 @@ const BaseNode: FC<BaseNodeProps> = ({
${open && '!flex'}
`
}
>
<
Plus
className=
'w-2.5 h-2.5 text-white'
/>
<
Plus
02
className=
'w-2.5 h-2.5 text-white'
/>
</
div
>
</
div
>
)
...
...
@@ -63,6 +64,7 @@ const BaseNode: FC<BaseNodeProps> = ({
`
}
onClick=
{
()
=>
handleSelectedNodeIdChange
(
nodeId
||
''
)
}
>
<
NodeControl
/>
<
div
className=
'flex items-center px-3 pt-3 pb-2'
>
<
BlockIcon
className=
'mr-2'
...
...
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