refactor: sub-graph panel use shared Panel component

This commit is contained in:
zhsama 2026-01-15 16:12:39 +08:00
parent 8ee643e88d
commit 5525f63032
3 changed files with 32 additions and 69 deletions

View File

@ -1,11 +1,11 @@
import type { FC } from 'react'
import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types'
import type { NodeOutPutVar } from '@/app/components/workflow/types'
import { memo, useEffect, useMemo, useRef } from 'react'
import { memo, useMemo } from 'react'
import { useStore as useReactFlowStore } from 'reactflow'
import { useShallow } from 'zustand/react/shallow'
import { useIsChatMode, useWorkflowVariables } from '@/app/components/workflow/hooks'
import { Panel as NodePanel } from '@/app/components/workflow/nodes'
import Panel from '@/app/components/workflow/panel'
import { useStore } from '@/app/components/workflow/store'
import { BlockEnum } from '@/app/components/workflow/types'
import ConfigPanel from './config-panel'
@ -26,37 +26,6 @@ const SubGraphChildren: FC<SubGraphChildrenProps> = ({
const { getNodeAvailableVars } = useWorkflowVariables()
const isChatMode = useIsChatMode()
const nodePanelWidth = useStore(s => s.nodePanelWidth)
const setRightPanelWidth = useStore(s => s.setRightPanelWidth)
const panelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const element = panelRef.current
if (!element)
return
const updateWidth = (width: number) => {
if (width > 0)
setRightPanelWidth(width)
}
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.borderBoxSize?.length)
updateWidth(entry.borderBoxSize[0].inlineSize)
else if (entry.contentRect.width > 0)
updateWidth(entry.contentRect.width)
else
updateWidth(element.getBoundingClientRect().width)
}
})
resizeObserver.observe(element)
updateWidth(element.getBoundingClientRect().width)
return () => {
resizeObserver.disconnect()
}
}, [setRightPanelWidth])
const selectedNode = useReactFlowStore(useShallow((s) => {
return s.getNodes().find(node => node.data.selected)
@ -82,41 +51,36 @@ const SubGraphChildren: FC<SubGraphChildrenProps> = ({
return vars.filter(item => item.nodeId === extractorNode.id)
}, [extractorNode, getNodeAvailableVars, isChatMode])
const nodePanel = useMemo(() => {
if (!selectedNode)
const panelRight = useMemo(() => {
if (selectedNode)
return null
return (
<NodePanel
id={selectedNode.id}
type={selectedNode.type}
data={selectedNode.data}
/>
<div className="relative mr-1 h-full">
<div
className="flex h-full flex-col rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg"
style={{ width: `${nodePanelWidth}px` }}
>
<ConfigPanel
agentName={agentName}
extractorNodeId={extractorNodeId}
mentionConfig={mentionConfig}
availableNodes={availableNodes}
availableVars={availableVars}
onMentionConfigChange={onMentionConfigChange}
/>
</div>
</div>
)
}, [selectedNode])
}, [agentName, availableNodes, availableVars, extractorNodeId, mentionConfig, nodePanelWidth, onMentionConfigChange, selectedNode])
return (
<div className="pointer-events-none absolute inset-y-0 right-0 z-10 flex">
<div className="pointer-events-auto" ref={panelRef}>
{nodePanel || (
<div className="relative mr-1 h-full">
<div
className="flex h-full flex-col rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg"
style={{ width: `${nodePanelWidth}px` }}
>
<ConfigPanel
agentName={agentName}
extractorNodeId={extractorNodeId}
mentionConfig={mentionConfig}
availableNodes={availableNodes}
availableVars={availableVars}
onMentionConfigChange={onMentionConfigChange}
/>
</div>
</div>
)}
</div>
</div>
<Panel
topOffset={0}
components={{
right: panelRight,
}}
/>
)
}

View File

@ -2,7 +2,6 @@ import type { Node } from 'reactflow'
import { memo, useCallback, useEffect, useMemo, useRef } from 'react'
import { MiniMap } from 'reactflow'
import UndoRedo from '../header/undo-redo'
import { useHooksStore } from '../hooks-store'
import { useStore } from '../store'
import VariableInspectPanel from '../variable-inspect'
import VariableTrigger from '../variable-inspect/trigger'
@ -15,19 +14,16 @@ export type OperatorProps = {
const Operator = ({ handleUndo, handleRedo }: OperatorProps) => {
const bottomPanelRef = useRef<HTMLDivElement>(null)
const interactionMode = useHooksStore(s => s.interactionMode)
const workflowCanvasWidth = useStore(s => s.workflowCanvasWidth)
const rightPanelWidth = useStore(s => s.rightPanelWidth)
const nodePanelWidth = useStore(s => s.nodePanelWidth)
const setBottomPanelWidth = useStore(s => s.setBottomPanelWidth)
const setBottomPanelHeight = useStore(s => s.setBottomPanelHeight)
const bottomPanelWidth = useMemo(() => {
const panelWidth = rightPanelWidth || nodePanelWidth
if (!workflowCanvasWidth || !panelWidth)
if (!workflowCanvasWidth || !rightPanelWidth)
return 'auto'
return Math.max((workflowCanvasWidth - panelWidth), 400)
}, [interactionMode, nodePanelWidth, rightPanelWidth, workflowCanvasWidth])
return Math.max((workflowCanvasWidth - rightPanelWidth), 400)
}, [workflowCanvasWidth, rightPanelWidth])
const getMiniMapNodeClassName = useCallback((node: Node) => {
return node.data?.selected

View File

@ -19,6 +19,7 @@ export type PanelProps = {
right?: React.ReactNode
}
versionHistoryPanelProps?: VersionHistoryPanelProps
topOffset?: number
}
/**
@ -69,6 +70,7 @@ const useResizeObserver = (
const Panel: FC<PanelProps> = ({
components,
versionHistoryPanelProps,
topOffset,
}) => {
const selectedNode = useReactflow(useShallow((s) => {
const nodes = s.getNodes()
@ -128,6 +130,7 @@ const Panel: FC<PanelProps> = ({
ref={rightPanelRef}
tabIndex={-1}
className={cn('absolute bottom-1 right-0 top-14 z-10 flex outline-none')}
style={topOffset === undefined ? undefined : { top: `${topOffset}px` }}
key={`${isRestoring}`}
>
{components?.left}