import type { FC, ReactElement, } from 'react' import { cloneElement, memo, useCallback, } from 'react' import { RiCloseLine, RiPlayLargeLine, } from '@remixicon/react' import { useShallow } from 'zustand/react/shallow' import { useTranslation } from 'react-i18next' import NextStep from './components/next-step' import PanelOperator from './components/panel-operator' import HelpLink from './components/help-link' import { DescriptionInput, TitleInput, } from './components/title-description-input' import { useResizePanel } from './hooks/use-resize-panel' import cn from '@/utils/classnames' import BlockIcon from '@/app/components/workflow/block-icon' import { WorkflowHistoryEvent, useAvailableBlocks, useNodeDataUpdate, useNodesInteractions, useNodesReadOnly, useNodesSyncDraft, useToolIcon, useWorkflow, useWorkflowHistory, } from '@/app/components/workflow/hooks' import { canRunBySingle } from '@/app/components/workflow/utils' import Tooltip from '@/app/components/base/tooltip' import type { Node } from '@/app/components/workflow/types' import { useStore as useAppStore } from '@/app/components/app/store' import { useStore } from '@/app/components/workflow/store' type BasePanelProps = { children: ReactElement } & Node const BasePanel: FC = ({ id, data, children, }) => { const { t } = useTranslation() const { showMessageLogModal } = useAppStore(useShallow(state => ({ showMessageLogModal: state.showMessageLogModal, }))) const showSingleRunPanel = useStore(s => s.showSingleRunPanel) 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() const { availableNextBlocks } = useAvailableBlocks(data.type, data.isInIteration) const toolIcon = useToolIcon(data) const handleResize = useCallback((width: number) => { setPanelWidth(width) }, [setPanelWidth]) const { triggerRef, containerRef, } = useResizePanel({ direction: 'horizontal', triggerDirection: 'left', minWidth: 420, maxWidth: 720, onResize: handleResize, }) const { saveStateToHistory } = useWorkflowHistory() const { handleNodeDataUpdate, handleNodeDataUpdateWithSyncDraft, } = useNodeDataUpdate() const handleTitleBlur = useCallback((title: string) => { handleNodeDataUpdateWithSyncDraft({ id, data: { title } }) saveStateToHistory(WorkflowHistoryEvent.NodeTitleChange) }, [handleNodeDataUpdateWithSyncDraft, id, saveStateToHistory]) const handleDescriptionChange = useCallback((desc: string) => { handleNodeDataUpdateWithSyncDraft({ id, data: { desc } }) saveStateToHistory(WorkflowHistoryEvent.NodeDescriptionChange) }, [handleNodeDataUpdateWithSyncDraft, id, saveStateToHistory]) return (
{ canRunBySingle(data.type) && !nodesReadOnly && (
{ handleNodeDataUpdate({ id, data: { _isSingleRun: true } }) handleSyncWorkflowDraft(true) }} >
) }
handleNodeSelect(id, true)} >
{cloneElement(children, { id, data })}
{ !!availableNextBlocks.length && (
{t('workflow.panel.nextStep').toLocaleUpperCase()}
{t('workflow.panel.addNextStep')}
) }
) } export default memo(BasePanel)