diff --git a/web/app/components/base/icons/assets/vender/line/general/Workflow.zip b/web/app/components/base/icons/assets/vender/line/general/Workflow.zip
new file mode 100644
index 0000000000..05631f93b0
Binary files /dev/null and b/web/app/components/base/icons/assets/vender/line/general/Workflow.zip differ
diff --git a/web/app/components/base/icons/assets/vender/line/general/check-circle.svg b/web/app/components/base/icons/assets/vender/line/general/check-circle.svg
new file mode 100644
index 0000000000..1c40b62342
--- /dev/null
+++ b/web/app/components/base/icons/assets/vender/line/general/check-circle.svg
@@ -0,0 +1,10 @@
+
diff --git a/web/app/components/base/icons/src/vender/line/general/CheckCircle.json b/web/app/components/base/icons/src/vender/line/general/CheckCircle.json
new file mode 100644
index 0000000000..60314a9690
--- /dev/null
+++ b/web/app/components/base/icons/src/vender/line/general/CheckCircle.json
@@ -0,0 +1,66 @@
+{
+ "icon": {
+ "type": "element",
+ "isRootNode": true,
+ "name": "svg",
+ "attributes": {
+ "width": "14",
+ "height": "14",
+ "viewBox": "0 0 14 14",
+ "fill": "none",
+ "xmlns": "http://www.w3.org/2000/svg"
+ },
+ "children": [
+ {
+ "type": "element",
+ "name": "g",
+ "attributes": {
+ "id": "check-circle",
+ "clip-path": "url(#clip0_465_21765)"
+ },
+ "children": [
+ {
+ "type": "element",
+ "name": "path",
+ "attributes": {
+ "id": "Icon",
+ "d": "M4.37533 6.99984L6.12533 8.74984L9.62533 5.24984M12.8337 6.99984C12.8337 10.2215 10.222 12.8332 7.00033 12.8332C3.77866 12.8332 1.16699 10.2215 1.16699 6.99984C1.16699 3.77818 3.77866 1.1665 7.00033 1.1665C10.222 1.1665 12.8337 3.77818 12.8337 6.99984Z",
+ "stroke": "currentColor",
+ "stroke-width": "1.5",
+ "stroke-linecap": "round",
+ "stroke-linejoin": "round"
+ },
+ "children": []
+ }
+ ]
+ },
+ {
+ "type": "element",
+ "name": "defs",
+ "attributes": {},
+ "children": [
+ {
+ "type": "element",
+ "name": "clipPath",
+ "attributes": {
+ "id": "clip0_465_21765"
+ },
+ "children": [
+ {
+ "type": "element",
+ "name": "rect",
+ "attributes": {
+ "width": "14",
+ "height": "14",
+ "fill": "white"
+ },
+ "children": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "name": "CheckCircle"
+}
\ No newline at end of file
diff --git a/web/app/components/base/icons/src/vender/line/general/CheckCircle.tsx b/web/app/components/base/icons/src/vender/line/general/CheckCircle.tsx
new file mode 100644
index 0000000000..fe2cbfcb54
--- /dev/null
+++ b/web/app/components/base/icons/src/vender/line/general/CheckCircle.tsx
@@ -0,0 +1,16 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './CheckCircle.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef, Omit>((
+ props,
+ ref,
+) => )
+
+Icon.displayName = 'CheckCircle'
+
+export default Icon
diff --git a/web/app/components/base/icons/src/vender/line/general/index.ts b/web/app/components/base/icons/src/vender/line/general/index.ts
index f809461b6e..545979d848 100644
--- a/web/app/components/base/icons/src/vender/line/general/index.ts
+++ b/web/app/components/base/icons/src/vender/line/general/index.ts
@@ -1,5 +1,6 @@
export { default as AtSign } from './AtSign'
export { default as Bookmark } from './Bookmark'
+export { default as CheckCircle } from './CheckCircle'
export { default as CheckDone01 } from './CheckDone01'
export { default as Check } from './Check'
export { default as DotsHorizontal } from './DotsHorizontal'
diff --git a/web/app/components/workflow/hooks.ts b/web/app/components/workflow/hooks.ts
index 4408ac42f8..b3c8da9afa 100644
--- a/web/app/components/workflow/hooks.ts
+++ b/web/app/components/workflow/hooks.ts
@@ -9,8 +9,10 @@ import {
useStoreApi,
} from 'reactflow'
import type {
+ BlockEnum,
SelectedNode,
} from './types'
+import { NodeInitialData } from './constants'
import { useStore } from './store'
export const useWorkflow = () => {
@@ -128,6 +130,36 @@ export const useWorkflow = () => {
setNodes(newNodes)
setSelectedNode({ id, data })
}, [store, setSelectedNode])
+ const handleAddNextNode = useCallback((currentNodeId: string, nodeType: BlockEnum) => {
+ const {
+ getNodes,
+ setNodes,
+ edges,
+ setEdges,
+ } = store.getState()
+ const nodes = getNodes()
+ const currentNode = nodes.find(node => node.id === currentNodeId)!
+ const nextNode = {
+ id: `${Date.now()}`,
+ data: NodeInitialData[nodeType],
+ position: {
+ x: currentNode.position.x + 304,
+ y: currentNode.position.y,
+ },
+ }
+ const newNodes = produce(nodes, (draft) => {
+ draft.push(nextNode)
+ })
+ setNodes(newNodes)
+ const newEdges = produce(edges, (draft) => {
+ draft.push({
+ id: `${currentNode.id}-${nextNode.id}`,
+ source: currentNode.id,
+ target: nextNode.id,
+ })
+ })
+ setEdges(newEdges)
+ }, [store])
return {
handleEnterNode,
@@ -136,5 +168,6 @@ export const useWorkflow = () => {
handleLeaveEdge,
handleSelectNode,
handleUpdateNodeData,
+ handleAddNextNode,
}
}
diff --git a/web/app/components/workflow/panel/run-history.tsx b/web/app/components/workflow/panel/run-history.tsx
index dbfe89793f..ade18d1a80 100644
--- a/web/app/components/workflow/panel/run-history.tsx
+++ b/web/app/components/workflow/panel/run-history.tsx
@@ -1,6 +1,8 @@
import { useStore } from '../store'
-import { XClose } from '@/app/components/base/icons/src/vender/line/general'
-import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general'
+import {
+ CheckCircle,
+ XClose,
+} from '@/app/components/base/icons/src/vender/line/general'
import { AlertCircle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
const RunHistory = () => {
diff --git a/web/app/components/workflow/utils.ts b/web/app/components/workflow/utils.ts
new file mode 100644
index 0000000000..e69de29bb2