| @@ -75,6 +75,11 @@ export const useWorkflow = () => { | |||
| const { handleSyncWorkflowDraft } = useNodesSyncDraft() | |||
| const { eventEmitter } = useEventEmitterContextContext() | |||
| const setPanelWidth = useCallback((width: number) => { | |||
| localStorage.setItem('workflow-node-panel-width', `${width}`) | |||
| workflowStore.setState({ panelWidth: width }) | |||
| }, [workflowStore]) | |||
| const handleLayout = useCallback(async () => { | |||
| workflowStore.setState({ nodeAnimation: true }) | |||
| const { | |||
| @@ -353,6 +358,7 @@ export const useWorkflow = () => { | |||
| }, [workflowStore]) | |||
| return { | |||
| setPanelWidth, | |||
| handleLayout, | |||
| getTreeLeafNodes, | |||
| getBeforeNodesInSameBranch, | |||
| @@ -13,6 +13,7 @@ export type UseResizePanelPrarams = { | |||
| minHeight?: number | |||
| maxHeight?: number | |||
| onResized?: (width: number, height: number) => void | |||
| onResize?: (width: number, height: number) => void | |||
| } | |||
| export const useResizePanel = (params?: UseResizePanelPrarams) => { | |||
| const { | |||
| @@ -23,6 +24,7 @@ export const useResizePanel = (params?: UseResizePanelPrarams) => { | |||
| minHeight = -Infinity, | |||
| maxHeight = Infinity, | |||
| onResized, | |||
| onResize, | |||
| } = params || {} | |||
| const triggerRef = useRef<HTMLDivElement>(null) | |||
| const containerRef = useRef<HTMLDivElement>(null) | |||
| @@ -63,6 +65,7 @@ export const useResizePanel = (params?: UseResizePanelPrarams) => { | |||
| if (width > maxWidth) | |||
| width = maxWidth | |||
| containerRef.current.style.width = `${width}px` | |||
| onResize?.(width, 0) | |||
| } | |||
| if (direction === 'vertical' || direction === 'both') { | |||
| @@ -79,6 +82,7 @@ export const useResizePanel = (params?: UseResizePanelPrarams) => { | |||
| height = maxHeight | |||
| containerRef.current.style.height = `${height}px` | |||
| onResize?.(0, height) | |||
| } | |||
| }, [ | |||
| direction, | |||
| @@ -87,6 +91,7 @@ export const useResizePanel = (params?: UseResizePanelPrarams) => { | |||
| maxWidth, | |||
| minHeight, | |||
| maxHeight, | |||
| onResize, | |||
| ]) | |||
| const handleStopResize = useCallback(() => { | |||
| @@ -1,4 +1,5 @@ | |||
| import { useEffect, useState } from 'react' | |||
| import { useStore } from '@/app/components/workflow/store' | |||
| type Params = { | |||
| ref: React.RefObject<HTMLDivElement> | |||
| @@ -9,6 +10,7 @@ type Params = { | |||
| const useToggleExpend = ({ ref, hasFooter = true, isInNode }: Params) => { | |||
| const [isExpand, setIsExpand] = useState(false) | |||
| const [wrapHeight, setWrapHeight] = useState(ref.current?.clientHeight) | |||
| const panelWidth = useStore(state => state.panelWidth) | |||
| const editorExpandHeight = isExpand ? wrapHeight! - (hasFooter ? 56 : 29) : 0 | |||
| useEffect(() => { | |||
| setWrapHeight(ref.current?.clientHeight) | |||
| @@ -20,11 +22,16 @@ const useToggleExpend = ({ ref, hasFooter = true, isInNode }: Params) => { | |||
| return '' | |||
| if (isInNode) | |||
| return 'fixed z-10 right-[9px] top-[166px] bottom-[8px] w-[419px] p-4 bg-white rounded-xl' | |||
| return 'fixed z-10 right-[9px] top-[166px] bottom-[8px] p-4 bg-white rounded-xl' | |||
| return 'absolute z-10 left-4 right-6 top-[52px] bottom-0 pb-4 bg-white' | |||
| })() | |||
| const wrapStyle = isExpand ? { boxShadow: '0px 0px 12px -4px rgba(16, 24, 40, 0.05), 0px -3px 6px -2px rgba(16, 24, 40, 0.03)' } : {} | |||
| const wrapStyle = isExpand | |||
| ? { | |||
| boxShadow: '0px 0px 12px -4px rgba(16, 24, 40, 0.05), 0px -3px 6px -2px rgba(16, 24, 40, 0.03)', | |||
| width: panelWidth - 1, | |||
| } | |||
| : {} | |||
| return { | |||
| wrapClassName, | |||
| wrapStyle, | |||
| @@ -26,6 +26,7 @@ import { | |||
| useNodesReadOnly, | |||
| useNodesSyncDraft, | |||
| useToolIcon, | |||
| useWorkflow, | |||
| } from '@/app/components/workflow/hooks' | |||
| import { canRunBySingle } from '@/app/components/workflow/utils' | |||
| import { Play } from '@/app/components/base/icons/src/vender/line/mediaAndDevices' | |||
| @@ -42,7 +43,10 @@ const BasePanel: FC<BasePanelProps> = ({ | |||
| children, | |||
| }) => { | |||
| const { t } = useTranslation() | |||
| const initPanelWidth = localStorage.getItem('workflow-node-panel-width') || 420 | |||
| const panelWidth = localStorage.getItem('workflow-node-panel-width') ? parseFloat(localStorage.getItem('workflow-node-panel-width')!) : 420 | |||
| const { | |||
| setPanelWidth, | |||
| } = useWorkflow() | |||
| const { handleNodeSelect } = useNodesInteractions() | |||
| const { handleSyncWorkflowDraft } = useNodesSyncDraft() | |||
| const { nodesReadOnly } = useNodesReadOnly() | |||
| @@ -50,9 +54,9 @@ const BasePanel: FC<BasePanelProps> = ({ | |||
| const availableNextNodes = nodesExtraData[data.type].availableNextNodes | |||
| const toolIcon = useToolIcon(data) | |||
| const handleResized = useCallback((width: number) => { | |||
| localStorage.setItem('workflow-node-panel-width', `${width}`) | |||
| }, []) | |||
| const handleResize = useCallback((width: number) => { | |||
| setPanelWidth(width) | |||
| }, [setPanelWidth]) | |||
| const { | |||
| triggerRef, | |||
| @@ -62,7 +66,7 @@ const BasePanel: FC<BasePanelProps> = ({ | |||
| triggerDirection: 'left', | |||
| minWidth: 420, | |||
| maxWidth: 720, | |||
| onResized: handleResized, | |||
| onResize: handleResize, | |||
| }) | |||
| const { | |||
| @@ -88,7 +92,7 @@ const BasePanel: FC<BasePanelProps> = ({ | |||
| ref={containerRef} | |||
| className='relative h-full bg-white shadow-lg border-[0.5px] border-gray-200 rounded-2xl overflow-y-auto' | |||
| style={{ | |||
| width: `${initPanelWidth}px`, | |||
| width: `${panelWidth}px`, | |||
| }} | |||
| > | |||
| <div className='sticky top-0 bg-white border-b-[0.5px] border-black/5 z-10'> | |||
| @@ -1,8 +1,6 @@ | |||
| import type { FC } from 'react' | |||
| import React, { useMemo } from 'react' | |||
| import { useStoreApi } from 'reactflow' | |||
| import React from 'react' | |||
| import { useTranslation } from 'react-i18next' | |||
| import { BlockEnum } from '../../types' | |||
| import MemoryConfig from '../_base/components/memory-config' | |||
| import VarReferencePicker from '../_base/components/variable/var-reference-picker' | |||
| import useConfig from './use-config' | |||
| @@ -29,12 +27,6 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({ | |||
| data, | |||
| }) => { | |||
| const { t } = useTranslation() | |||
| const store = useStoreApi() | |||
| const startNode = useMemo(() => { | |||
| const nodes = store.getState().getNodes() | |||
| return nodes.find(node => node.data.type === BlockEnum.Start) | |||
| }, [store]) | |||
| const { | |||
| readOnly, | |||
| @@ -21,6 +21,7 @@ import { WorkflowContext } from './context' | |||
| type Shape = { | |||
| appId: string | |||
| panelWidth: number | |||
| workflowRunningData?: WorkflowRunningData | |||
| setWorkflowRunningData: (workflowData: WorkflowRunningData) => void | |||
| historyWorkflowData?: HistoryWorkflowData | |||
| @@ -72,6 +73,7 @@ type Shape = { | |||
| export const createWorkflowStore = () => { | |||
| return createStore<Shape>(set => ({ | |||
| appId: '', | |||
| panelWidth: localStorage.getItem('workflow-node-panel-width') ? parseFloat(localStorage.getItem('workflow-node-panel-width')!) : 420, | |||
| workflowRunningData: undefined, | |||
| setWorkflowRunningData: workflowRunningData => set(() => ({ workflowRunningData })), | |||
| historyWorkflowData: undefined, | |||