mirror of
https://github.com/langgenius/dify.git
synced 2026-04-27 11:06:46 +08:00
panel
This commit is contained in:
parent
5817a035f9
commit
701e441349
@ -11,6 +11,7 @@ import type {
|
|||||||
} from './types'
|
} from './types'
|
||||||
|
|
||||||
export type WorkflowContextValue = {
|
export type WorkflowContextValue = {
|
||||||
|
mode: string
|
||||||
reactFlow: ReactFlowInstance
|
reactFlow: ReactFlowInstance
|
||||||
nodes: Node[]
|
nodes: Node[]
|
||||||
edges: Edge[]
|
edges: Edge[]
|
||||||
@ -22,6 +23,7 @@ export type WorkflowContextValue = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const WorkflowContext = createContext<WorkflowContextValue>({
|
export const WorkflowContext = createContext<WorkflowContextValue>({
|
||||||
|
mode: 'workflow',
|
||||||
reactFlow: null as any,
|
reactFlow: null as any,
|
||||||
nodes: [],
|
nodes: [],
|
||||||
edges: [],
|
edges: [],
|
||||||
|
|||||||
@ -15,13 +15,10 @@ import {
|
|||||||
} from './context'
|
} from './context'
|
||||||
import { useWorkflow } from './hooks'
|
import { useWorkflow } from './hooks'
|
||||||
import Header from './header'
|
import Header from './header'
|
||||||
import CustomNode, {
|
import CustomNode from './nodes'
|
||||||
Panel,
|
|
||||||
} from './nodes'
|
|
||||||
// import AppInfoPanel from './app-info-panel'
|
|
||||||
import DebugAndPreview from './debug-and-preview'
|
|
||||||
import ZoomInOut from './zoom-in-out'
|
import ZoomInOut from './zoom-in-out'
|
||||||
import CustomEdge from './custom-edge'
|
import CustomEdge from './custom-edge'
|
||||||
|
import Panel from './panel'
|
||||||
import type { Node } from './types'
|
import type { Node } from './types'
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
@ -40,8 +37,6 @@ const Workflow = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='relative w-full h-full'>
|
<div className='relative w-full h-full'>
|
||||||
<Header />
|
<Header />
|
||||||
{/* <AppInfoPanel /> */}
|
|
||||||
<DebugAndPreview />
|
|
||||||
<Panel />
|
<Panel />
|
||||||
<ZoomInOut />
|
<ZoomInOut />
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
@ -87,6 +82,7 @@ const WorkflowWrap: FC<WorkflowWrapProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<WorkflowContext.Provider value={{
|
<WorkflowContext.Provider value={{
|
||||||
|
mode: 'workflow',
|
||||||
reactFlow,
|
reactFlow,
|
||||||
selectedNodeId,
|
selectedNodeId,
|
||||||
handleSelectedNodeIdChange,
|
handleSelectedNodeIdChange,
|
||||||
|
|||||||
@ -16,7 +16,7 @@ const NodeControl: FC<NodeControlProps> = ({
|
|||||||
isRunning,
|
isRunning,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
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'>
|
<div className='absolute right-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 && (
|
isRunning && (
|
||||||
<div className='flex items-center px-1 h-5 rounded-md bg-primary-50 text-xs font-medium text-primary-600'>
|
<div className='flex items-center px-1 h-5 rounded-md bg-primary-50 text-xs font-medium text-primary-600'>
|
||||||
@ -9,9 +9,9 @@ import {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
import type { NodeProps } from 'reactflow'
|
import type { NodeProps } from 'reactflow'
|
||||||
import { useWorkflowContext } from '../../context'
|
import { useWorkflowContext } from '../../context'
|
||||||
import NodeControl from '../../node-control'
|
|
||||||
import BlockIcon from '../../block-icon'
|
import BlockIcon from '../../block-icon'
|
||||||
import BlockSelector from '../../block-selector'
|
import BlockSelector from '../../block-selector'
|
||||||
|
import NodeControl from './components/node-control'
|
||||||
|
|
||||||
type BaseNodeProps = {
|
type BaseNodeProps = {
|
||||||
children: ReactElement
|
children: ReactElement
|
||||||
|
|||||||
@ -31,7 +31,7 @@ const BasePanel: FC<BasePanelProps> = ({
|
|||||||
} = useWorkflowContext()
|
} = useWorkflowContext()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='absolute top-14 right-2 bottom-2 w-[420px] 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 z-10 overflow-y-auto'>
|
||||||
<div className='sticky top-0 bg-white border-b-[0.5px] border-black/5'>
|
<div className='sticky top-0 bg-white border-b-[0.5px] border-black/5'>
|
||||||
<div className='flex items-center px-4 pt-3'>
|
<div className='flex items-center px-4 pt-3'>
|
||||||
<BlockIcon
|
<BlockIcon
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
|
import type { FC } from 'react'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import type { NodeProps } from 'reactflow'
|
import type { NodeProps } from 'reactflow'
|
||||||
import {
|
import {
|
||||||
Handle,
|
Handle,
|
||||||
Position,
|
Position,
|
||||||
} from 'reactflow'
|
} from 'reactflow'
|
||||||
import { useWorkflowContext } from '../context'
|
import type { Node } from '../types'
|
||||||
import { BlockEnum } from '../types'
|
import { BlockEnum } from '../types'
|
||||||
import {
|
import {
|
||||||
NodeComponentMap,
|
NodeComponentMap,
|
||||||
@ -49,18 +50,18 @@ const CustomNode = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Panel = memo(() => {
|
type PanelProps = {
|
||||||
const { selectedNode } = useWorkflowContext()
|
node: Node
|
||||||
|
}
|
||||||
if (!selectedNode)
|
export const Panel: FC<PanelProps> = memo(({
|
||||||
return null
|
node,
|
||||||
|
}) => {
|
||||||
const PanelComponent = PanelComponentMap[selectedNode.data.type]
|
const PanelComponent = PanelComponentMap[node.data.type]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BasePanel
|
<BasePanel
|
||||||
id={selectedNode.id}
|
id={node.id}
|
||||||
data={selectedNode.data}
|
data={node.data}
|
||||||
>
|
>
|
||||||
<PanelComponent />
|
<PanelComponent />
|
||||||
</BasePanel>
|
</BasePanel>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import ChatWrapper from './chat-wrapper'
|
|||||||
const DebugAndPreview: FC = () => {
|
const DebugAndPreview: FC = () => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='flex flex-col absolute top-14 right-0 bottom-2 w-[400px] 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 z-10'
|
||||||
style={{ background: 'linear-gradient(156deg, rgba(242, 244, 247, 0.80) 0%, rgba(242, 244, 247, 0.00) 99.43%), var(--white, #FFF)' }}
|
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'>
|
<div className='shrink-0 flex items-center justify-between px-4 pt-3 pb-2'>
|
||||||
49
web/app/components/workflow/panel/index.tsx
Normal file
49
web/app/components/workflow/panel/index.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import type { FC } from 'react'
|
||||||
|
import {
|
||||||
|
memo,
|
||||||
|
useMemo,
|
||||||
|
} from 'react'
|
||||||
|
import { useWorkflowContext } from '../context'
|
||||||
|
import { Panel as NodePanel } from '../nodes'
|
||||||
|
import WorkflowInfo from './workflow-info'
|
||||||
|
import DebugAndPreview from './debug-and-preview'
|
||||||
|
|
||||||
|
const Panel: FC = () => {
|
||||||
|
const {
|
||||||
|
mode,
|
||||||
|
selectedNode,
|
||||||
|
} = useWorkflowContext()
|
||||||
|
const {
|
||||||
|
showWorkflowInfoPanel,
|
||||||
|
showNodePanel,
|
||||||
|
showDebugAndPreviewPanel,
|
||||||
|
} = useMemo(() => {
|
||||||
|
return {
|
||||||
|
showWorkflowInfoPanel: mode === 'workflow' && !selectedNode,
|
||||||
|
showNodePanel: selectedNode,
|
||||||
|
showDebugAndPreviewPanel: mode === 'chatbot' && !selectedNode,
|
||||||
|
}
|
||||||
|
}, [mode, selectedNode])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='absolute top-14 right-0 bottom-2 flex'>
|
||||||
|
{
|
||||||
|
showNodePanel && (
|
||||||
|
<NodePanel node={selectedNode!} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
showWorkflowInfoPanel && (
|
||||||
|
<WorkflowInfo />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
showDebugAndPreviewPanel && (
|
||||||
|
<DebugAndPreview />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memo(Panel)
|
||||||
@ -1,19 +1,13 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import BlockIcon from './block-icon'
|
import BlockIcon from '../block-icon'
|
||||||
import { BlockEnum } from './types'
|
import { BlockEnum } from '../types'
|
||||||
import { useWorkflowContext } from './context'
|
|
||||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
|
||||||
import { FileCheck02 } from '@/app/components/base/icons/src/vender/line/files'
|
import { FileCheck02 } from '@/app/components/base/icons/src/vender/line/files'
|
||||||
|
|
||||||
const AppInfoPanel: FC = () => {
|
const WorkflowInfo: FC = () => {
|
||||||
const { selectedNode } = useWorkflowContext()
|
|
||||||
|
|
||||||
if (selectedNode)
|
|
||||||
return null
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='absolute top-14 right-2 bottom-2 w-[420px] 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 z-10 overflow-y-auto'>
|
||||||
<div className='sticky top-0 bg-white border-b-[0.5px] border-black/5'>
|
<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='flex pt-4 px-4 pb-1'>
|
||||||
<div className='mr-3 w-10 h-10'></div>
|
<div className='mr-3 w-10 h-10'></div>
|
||||||
@ -55,4 +49,4 @@ const AppInfoPanel: FC = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo(AppInfoPanel)
|
export default memo(WorkflowInfo)
|
||||||
Loading…
Reference in New Issue
Block a user