mirror of
https://github.com/langgenius/dify.git
synced 2026-04-13 22:57:26 +08:00
panel-operator
This commit is contained in:
parent
510f0593e9
commit
d2d6904c9b
@ -57,6 +57,7 @@ const initialEdges = [
|
||||
sourceHandle: 'source',
|
||||
target: '2',
|
||||
targetHandle: 'target',
|
||||
deletable: false,
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
|
||||
@ -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 handleSelectNode = useCallback((selectNode: SelectedNode, cancelSelection?: boolean) => {
|
||||
const handleDeleteEdge = useCallback(() => {
|
||||
const {
|
||||
getNodes,
|
||||
setNodes,
|
||||
edges,
|
||||
setEdges,
|
||||
} = 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,
|
||||
handleSelectNode,
|
||||
handleDeleteEdge,
|
||||
handleUpdateNodeData,
|
||||
handleAddNextNode,
|
||||
handleChangeCurrentNode,
|
||||
handleDeleteNode,
|
||||
handleInitialLayoutNodes,
|
||||
handleUpdateNodesPosition,
|
||||
}
|
||||
|
||||
@ -1,19 +1,17 @@
|
||||
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}
|
||||
/>
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
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)
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@ -7,23 +7,23 @@ import {
|
||||
memo,
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import type { SelectedNode } 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
|
||||
} & SelectedNode
|
||||
} & 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>
|
||||
)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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: SelectedNode) => {
|
||||
export const Panel = memo((props: Node) => {
|
||||
const nodeData = props.data
|
||||
const PanelComponent = PanelComponentMap[nodeData.type]
|
||||
|
||||
|
||||
@ -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'>
|
||||
|
||||
@ -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!} />
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -1,21 +1,16 @@
|
||||
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 })),
|
||||
}))
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user