import type { FC, ReactElement, } from 'react' import { cloneElement, memo, useCallback, } from 'react' import cn from 'classnames' import { useShallow } from 'zustand/react/shallow' import { useTranslation } from 'react-i18next' import NextStep from './components/next-step' import PanelOperator from './components/panel-operator' import { DescriptionInput, TitleInput, } from './components/title-description-input' import { useResizePanel } from './hooks/use-resize-panel' import { XClose, } from '@/app/components/base/icons/src/vender/line/general' import BlockIcon from '@/app/components/workflow/block-icon' import { useNodeDataUpdate, useNodesExtraData, useNodesInteractions, 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' import TooltipPlus from '@/app/components/base/tooltip-plus' import type { Node } from '@/app/components/workflow/types' import { useStore as useAppStore } from '@/app/components/app/store' type BasePanelProps = { children: ReactElement } & Node const BasePanel: FC = ({ id, data, children, }) => { const { t } = useTranslation() const { showMessageLogModal } = useAppStore(useShallow(state => ({ showMessageLogModal: state.showMessageLogModal, }))) 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 nodesExtraData = useNodesExtraData() const availableNextNodes = nodesExtraData[data.type].availableNextNodes 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 { handleNodeDataUpdate, handleNodeDataUpdateWithSyncDraft, } = useNodeDataUpdate() const handleTitleBlur = useCallback((title: string) => { handleNodeDataUpdateWithSyncDraft({ id, data: { title } }) }, [handleNodeDataUpdateWithSyncDraft, id]) const handleDescriptionChange = useCallback((desc: string) => { handleNodeDataUpdateWithSyncDraft({ id, data: { desc } }) }, [handleNodeDataUpdateWithSyncDraft, id]) return (
{ canRunBySingle(data.type) && !nodesReadOnly && (
{ handleNodeDataUpdate({ id, data: { _isSingleRun: true } }) handleSyncWorkflowDraft(true) }} >
) }
handleNodeSelect(id, true)} >
{cloneElement(children, { id, data })}
{ !!availableNextNodes.length && (
{t('workflow.panel.nextStep').toLocaleUpperCase()}
{t('workflow.panel.addNextStep')}
) }
) } export default memo(BasePanel)