Skip to content

Commit

Permalink
Merge branch 'feat/workflow' into deploy/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
zxhlyh committed Mar 16, 2024
2 parents 41ca463 + 05f97f6 commit e1e2676
Show file tree
Hide file tree
Showing 20 changed files with 78 additions and 43 deletions.
4 changes: 2 additions & 2 deletions web/app/components/workflow/custom-connection-line.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import { memo } from 'react'
import type { ConnectionLineComponentProps } from 'reactflow'
import {
Position,
Expand Down Expand Up @@ -36,4 +36,4 @@ const CustomConnectionLine = ({ fromX, fromY, toX, toY }: ConnectionLineComponen
)
}

export default CustomConnectionLine
export default memo(CustomConnectionLine)
18 changes: 14 additions & 4 deletions web/app/components/workflow/header/publish.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { useState } from 'react'
import {
memo,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { useStore } from '../store'
import {
useStore,
useWorkflowStore,
} from '../store'
import Button from '@/app/components/base/button'
import {
PortalToFollowElem,
Expand All @@ -12,13 +18,17 @@ import { useStore as useAppStore } from '@/app/components/app/store'

const Publish = () => {
const { t } = useTranslation()
const workflowStore = useWorkflowStore()
const runningStatus = useStore(s => s.runningStatus)
const [open, setOpen] = useState(false)

const handlePublish = async () => {
const appId = useAppStore.getState().appDetail?.id
try {
await publishWorkflow(`/apps/${appId}/workflows/publish`)
const res = await publishWorkflow(`/apps/${appId}/workflows/publish`)

if (res)
workflowStore.setState({ publishedAt: res.created_at })
}
catch (e) {
}
Expand Down Expand Up @@ -86,4 +96,4 @@ const Publish = () => {
)
}

export default Publish
export default memo(Publish)
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const useNodesInteractions = () => {
const connectingNodeRef = useRef<{ nodeId: string; handleType: HandleType } | null>(null)

const handleNodeDragStart = useCallback<NodeDragHandler>((_, node) => {
workflowStore.setState({ nodeAnimation: false })
const {
runningStatus,
} = workflowStore.getState()
Expand Down
11 changes: 4 additions & 7 deletions web/app/components/workflow/hooks/use-workflow-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
NodeRunningStatus,
WorkflowRunningStatus,
} from '../types'
import { NODE_WIDTH } from '../constants'
import { useStore as useAppStore } from '@/app/components/app/store'
import type { IOtherOptions } from '@/service/base'
import { ssePost } from '@/service/base'
Expand Down Expand Up @@ -135,19 +134,17 @@ export const useWorkflowRun = () => {
onNodeStarted: ({ data }) => {
const nodes = getNodes()
const {
getViewport,
setViewport,
} = reactflow

const viewport = getViewport()
const currentNodeIndex = nodes.findIndex(node => node.id === data.node_id)
const currentNode = nodes[currentNodeIndex]
const position = currentNode.position
const zoom = 0.5
const zoom = 1

setViewport({
x: (clientWidth - 400 - currentNode.width!) / 2 - position.x,
y: (clientHeight - currentNode.height!) / 2 - position.y,
zoom,
x: (((clientWidth - 400) / 2 - NODE_WIDTH / 2) / viewport.zoom - position.x) * zoom,
y: ((clientHeight / 2 - currentNode.height! / 2) / viewport.zoom - position.y) * zoom,
})
const newNodes = produce(nodes, (draft) => {
draft[currentNodeIndex].data._runningStatus = NodeRunningStatus.Running
Expand Down
11 changes: 8 additions & 3 deletions web/app/components/workflow/hooks/use-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ export const useIsChatMode = () => {
export const useWorkflow = () => {
const store = useStoreApi()
const reactflow = useReactFlow()
const workflowStore = useWorkflowStore()
const nodesExtraData = useNodesExtraData()
const { handleSyncWorkflowDraft } = useNodesSyncDraft()

const handleLayout = useCallback(async () => {
workflowStore.setState({ nodeAnimation: true })
const {
getNodes,
edges,
Expand All @@ -70,13 +72,16 @@ export const useWorkflow = () => {
})
})
setNodes(newNodes)
const zoom = 0.7
setViewport({
x: 0,
y: 0,
zoom: 0.8,
zoom,
})
setTimeout(() => {
handleSyncWorkflowDraft()
})
setTimeout(() => handleSyncWorkflowDraft())
}, [store, reactflow, handleSyncWorkflowDraft])
}, [store, reactflow, handleSyncWorkflowDraft, workflowStore])

const getTreeLeafNodes = useCallback((nodeId: string) => {
const {
Expand Down
9 changes: 7 additions & 2 deletions web/app/components/workflow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ReactFlow, {
} from 'reactflow'
import type { Viewport } from 'reactflow'
import 'reactflow/dist/style.css'
import './style.css'
import type {
Edge,
Node,
Expand Down Expand Up @@ -61,6 +62,7 @@ const Workflow: FC<WorkflowProps> = memo(({
}) => {
const showFeaturesPanel = useStore(state => state.showFeaturesPanel)
const runningStatus = useStore(s => s.runningStatus)
const nodeAnimation = useStore(s => s.nodeAnimation)
const { handleSyncWorkflowDraft } = useNodesSyncDraft()

useEffect(() => {
Expand Down Expand Up @@ -99,7 +101,11 @@ const Workflow: FC<WorkflowProps> = memo(({
return (
<div
id='workflow-container'
className='relative w-full min-w-[960px] h-full bg-[#F0F2F7]'
className={`
relative w-full min-w-[960px] h-full bg-[#F0F2F7]
${runningStatus && 'workflow-panel-animation'}
${nodeAnimation && 'workflow-node-animation'}
`}
>
<Header />
<Panel />
Expand All @@ -109,7 +115,6 @@ const Workflow: FC<WorkflowProps> = memo(({
}
<HelpLine />
<ReactFlow
className='workflow-inner'
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
nodes={nodes}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ const Add = ({
>
{
branchName && (
<div className='absolute left-1 -top-[7.5px] flex items-center px-0.5 h-3 bg-white text-[10px] text-gray-500 font-semibold rounded-[5px]'>
<div
className='absolute left-1 right-1 -top-[7.5px] flex items-center px-0.5 h-3 bg-white text-[10px] text-gray-500 font-semibold rounded-[5px] truncate'
title={branchName.toLocaleUpperCase()}
>
{branchName.toLocaleUpperCase()}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const NextStep = ({
selectedNode,
}: NextStepProps) => {
const store = useStoreApi()
const branches = selectedNode.data._targetBranches
const branches = selectedNode.data._targetBranches || []
const nodeWithBranches = selectedNode.data.type === BlockEnum.IfElse || selectedNode.data.type === BlockEnum.QuestionClassifier
const edges = useEdges()
const outgoers = getOutgoers(selectedNode as Node, store.getState().getNodes(), edges)
Expand All @@ -36,7 +36,7 @@ const NextStep = ({
toolProviderId={selectedNode!.data.provider_id}
/>
</div>
<Line linesNumber={branches ? branches.length : 1} />
<Line linesNumber={nodeWithBranches ? branches.length : 1} />
<div className='grow'>
{
!nodeWithBranches && !!outgoers.length && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ const Item = ({
>
{
branchName && (
<div className='absolute left-1 -top-[7.5px] flex items-center px-0.5 h-3 bg-white text-[10px] text-gray-500 font-semibold rounded-[5px]'>
<div
className='absolute left-1 right-1 -top-[7.5px] flex items-center px-0.5 h-3 bg-white text-[10px] text-gray-500 font-semibold rounded-[5px] truncate'
title={branchName.toLocaleUpperCase()}
>
{branchName.toLocaleUpperCase()}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import {
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { useNodeDataUpdate } from '../../../hooks'
import {
useNodeDataUpdate,
useNodesInteractions,
} from '../../../hooks'
import type { Node } from '../../../types'
import { canRunBySingle } from '../../../utils'
import PanelOperator from './panel-operator'
Expand All @@ -23,6 +26,7 @@ const NodeControl: FC<NodeControlProps> = ({
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const { handleNodeDataUpdate } = useNodeDataUpdate()
const { handleNodeSelect } = useNodesInteractions()

const handleOpenChange = useCallback((newOpen: boolean) => {
setOpen(newOpen)
Expand Down Expand Up @@ -51,6 +55,7 @@ const NodeControl: FC<NodeControlProps> = ({
_isSingleRun: !data._isSingleRun,
},
})
handleNodeSelect(id)
}}
>
{
Expand Down
2 changes: 1 addition & 1 deletion web/app/components/workflow/nodes/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const NodeComponentMap: Record<string, ComponentType<any>> = {
[BlockEnum.VariableAssigner]: VariableAssignerNode,
}

export const PanelComponentMap: Record<string, ComponentType> = {
export const PanelComponentMap: Record<string, ComponentType<any>> = {
[BlockEnum.Start]: StartPanel,
[BlockEnum.End]: EndPanel,
[BlockEnum.Answer]: AnswerPanel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useChat } from './hooks'
import Chat from '@/app/components/base/chat/chat'
import type { OnSend } from '@/app/components/base/chat/types'
import { useFeaturesStore } from '@/app/components/base/features/hooks'
import { fetchConvesationMessages } from '@/service/debug'
import { fetchSuggestedQuestions } from '@/service/debug'
import { useStore as useAppStore } from '@/app/components/app/store'

const ChatWrapper = () => {
Expand Down Expand Up @@ -49,10 +49,10 @@ const ChatWrapper = () => {
query,
files,
inputs: workflowStore.getState().inputs,
conversationId,
conversation_id: conversationId,
},
{
onGetSuggestedQuestions: (conversationId, getAbortController) => fetchConvesationMessages(appId, conversationId, getAbortController),
onGetSuggestedQuestions: (messageId, getAbortController) => fetchSuggestedQuestions(appId, messageId, getAbortController),
},
)
}
Expand Down
6 changes: 3 additions & 3 deletions web/app/components/workflow/panel/debug-and-preview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { FC } from 'react'
import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import { useStore } from '../../store'
import ChatWrapper from './chat-wrapper'

const DebugAndPreview: FC = () => {
const DebugAndPreview = () => {
const { t } = useTranslation()
const showRunHistory = useStore(s => s.showRunHistory)

Expand All @@ -28,4 +28,4 @@ const DebugAndPreview: FC = () => {
)
}

export default DebugAndPreview
export default memo(DebugAndPreview)
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const UserInput = () => {
})
}

if (!variables.length)
return null

return (
<div
className={`
Expand Down
4 changes: 3 additions & 1 deletion web/app/components/workflow/panel/record.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import Run from '../run'
import { useStore } from '../store'

const Record = () => {
const { currentSequenceNumber, workflowRunId } = useStore()
const currentSequenceNumber = useStore(s => s.currentSequenceNumber)
const workflowRunId = useStore(s => s.workflowRunId)

return (
<div className='flex flex-col w-[400px] h-full rounded-2xl border-[0.5px] border-gray-200 shadow-xl bg-white'>
<div className='flex items-center justify-between p-4 pb-1 text-base font-semibold text-gray-900'>
Expand Down
9 changes: 4 additions & 5 deletions web/app/components/workflow/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import type {
ToolInWorkflow,
ToolsMap,
} from './block-selector/types'
import { Mode } from './types'
import type {
Edge,
Node,
Expand All @@ -22,7 +21,6 @@ import type {
import { WorkflowContext } from './context'

type State = {
mode: Mode
taskId: string
currentSequenceNumber: number
workflowRunId: string
Expand All @@ -44,10 +42,10 @@ type State = {
}
notInitialWorkflow: boolean
nodesDefaultConfigs: Record<string, any>
nodeAnimation: boolean
}

type Action = {
setMode: (mode: Mode) => void
setTaskId: (taskId: string) => void
setCurrentSequenceNumber: (currentSequenceNumber: number) => void
setWorkflowRunId: (workflowRunId: string) => void
Expand All @@ -65,18 +63,17 @@ type Action = {
setBackupDraft: (backupDraft?: State['backupDraft']) => void
setNotInitialWorkflow: (notInitialWorkflow: boolean) => void
setNodesDefaultConfigs: (nodesDefaultConfigs: Record<string, any>) => void
setNodeAnimation: (nodeAnimation: boolean) => void
}

export const createWorkflowStore = () => {
return create<State & Action>(set => ({
mode: Mode.Editing,
taskId: '',
setTaskId: taskId => set(() => ({ taskId })),
currentSequenceNumber: 0,
setCurrentSequenceNumber: currentSequenceNumber => set(() => ({ currentSequenceNumber })),
workflowRunId: '',
setWorkflowRunId: workflowRunId => set(() => ({ workflowRunId })),
setMode: mode => set(() => ({ mode })),
showRunHistory: false,
setShowRunHistory: showRunHistory => set(() => ({ showRunHistory })),
showFeaturesPanel: false,
Expand Down Expand Up @@ -105,6 +102,8 @@ export const createWorkflowStore = () => {
setNotInitialWorkflow: notInitialWorkflow => set(() => ({ notInitialWorkflow })),
nodesDefaultConfigs: {},
setNodesDefaultConfigs: nodesDefaultConfigs => set(() => ({ nodesDefaultConfigs })),
nodeAnimation: false,
setNodeAnimation: nodeAnimation => set(() => ({ nodeAnimation })),
}))
}

Expand Down
7 changes: 7 additions & 0 deletions web/app/components/workflow/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.workflow-panel-animation .react-flow__viewport {
transition: transform 0.3s ease-in-out;
}

.workflow-node-animation .react-flow__node {
transition: transform 0.2s ease-in-out;
}
5 changes: 0 additions & 5 deletions web/app/components/workflow/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,6 @@ export type NodeDefault<T> = {

export type OnSelectBlock = (type: BlockEnum, toolDefaultValue?: ToolDefaultValue) => void

export enum Mode {
Editing = 'editing',
Running = 'running',
}

export enum WorkflowRunningStatus {
Waiting = 'waiting',
Running = 'running',
Expand Down
2 changes: 1 addition & 1 deletion web/app/components/workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const getLayoutByDagre = (originNodes: Node[], originEdges: Edge[]) => {
rankdir: 'LR',
align: 'UL',
nodesep: 64,
ranksep: 64,
ranksep: 40,
})
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: node.width, height: node.height })
Expand Down
2 changes: 1 addition & 1 deletion web/service/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const singleNodeRun = (appId: string, nodeId: string, params: object) =>
}

export const publishWorkflow = (url: string) => {
return post<CommonResponse>(url)
return post<CommonResponse & { created_at: number }>(url)
}

export const stopWorkflowRun = (url: string) => {
Expand Down

0 comments on commit e1e2676

Please sign in to comment.