- 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 ErrorHandleOnPanel from './components/error-handle/error-handle-on-panel'
 - import RetryOnPanel from './components/retry/retry-on-panel'
 - import { useResizePanel } from './hooks/use-resize-panel'
 - import cn from '@/utils/classnames'
 - import BlockIcon from '@/app/components/workflow/block-icon'
 - import Split from '@/app/components/workflow/nodes/_base/components/split'
 - import {
 -   WorkflowHistoryEvent,
 -   useAvailableBlocks,
 -   useNodeDataUpdate,
 -   useNodesInteractions,
 -   useNodesReadOnly,
 -   useNodesSyncDraft,
 -   useToolIcon,
 -   useWorkflow,
 -   useWorkflowHistory,
 - } from '@/app/components/workflow/hooks'
 - import {
 -   canRunBySingle,
 -   hasErrorHandleNode,
 -   hasRetryNode,
 - } 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<BasePanelProps> = ({
 -   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') ? Number.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, data.isInLoop)
 -   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 (
 -     <div className={cn(
 -       'relative mr-2 h-full',
 -       showMessageLogModal && '!absolute !mr-0 w-[384px] overflow-hidden -top-[5px] right-[416px] z-0 shadow-lg border-[0.5px] border-components-panel-border rounded-2xl transition-all',
 -     )}>
 -       <div
 -         ref={triggerRef}
 -         className='absolute top-1/2 -translate-y-1/2 -left-2 w-3 h-6 cursor-col-resize resize-x'>
 -         <div className='w-1 h-6 bg-divider-regular rounded-sm'></div>
 -       </div>
 -       <div
 -         ref={containerRef}
 -         className={cn('h-full bg-components-panel-bg shadow-lg border-[0.5px] border-components-panel-border rounded-2xl', showSingleRunPanel ? 'overflow-hidden' : 'overflow-y-auto')}
 -         style={{
 -           width: `${panelWidth}px`,
 -         }}
 -       >
 -         <div className='sticky top-0 bg-components-panel-bg border-b-[0.5px] border-black/5 z-10'>
 -           <div className='flex items-center px-4 pt-4 pb-1'>
 -             <BlockIcon
 -               className='shrink-0 mr-1'
 -               type={data.type}
 -               toolIcon={toolIcon}
 -               size='md'
 -             />
 -             <TitleInput
 -               value={data.title || ''}
 -               onBlur={handleTitleBlur}
 -             />
 -             <div className='shrink-0 flex items-center text-gray-500'>
 -               {
 -                 canRunBySingle(data.type) && !nodesReadOnly && (
 -                   <Tooltip
 -                     popupContent={t('workflow.panel.runThisStep')}
 -                     popupClassName='mr-1'
 -                   >
 -                     <div
 -                       className='flex items-center justify-center mr-1 w-6 h-6 rounded-md hover:bg-black/5 cursor-pointer'
 -                       onClick={() => {
 -                         handleNodeDataUpdate({ id, data: { _isSingleRun: true } })
 -                         handleSyncWorkflowDraft(true)
 -                       }}
 -                     >
 -                       <RiPlayLargeLine className='w-4 h-4 text-text-tertiary' />
 -                     </div>
 -                   </Tooltip>
 -                 )
 -               }
 -               <HelpLink nodeType={data.type} />
 -               <PanelOperator id={id} data={data} showHelpLink={false} />
 -               <div className='mx-3 w-[1px] h-3.5 bg-divider-regular' />
 -               <div
 -                 className='flex items-center justify-center w-6 h-6 cursor-pointer'
 -                 onClick={() => handleNodeSelect(id, true)}
 -               >
 -                 <RiCloseLine className='w-4 h-4 text-text-tertiary' />
 -               </div>
 -             </div>
 -           </div>
 -           <div className='p-2'>
 -             <DescriptionInput
 -               value={data.desc || ''}
 -               onChange={handleDescriptionChange}
 -             />
 -           </div>
 -         </div>
 -         <div>
 -           {cloneElement(children, { id, data })}
 -         </div>
 -         <Split />
 -         {
 -           hasRetryNode(data.type) && (
 -             <RetryOnPanel
 -               id={id}
 -               data={data}
 -             />
 -           )
 -         }
 -         {
 -           hasErrorHandleNode(data.type) && (
 -             <ErrorHandleOnPanel
 -               id={id}
 -               data={data}
 -             />
 -           )
 -         }
 -         {
 -           !!availableNextBlocks.length && (
 -             <div className='p-4 border-t-[0.5px] border-t-black/5'>
 -               <div className='flex items-center mb-1 system-sm-semibold-uppercase text-text-secondary'>
 -                 {t('workflow.panel.nextStep').toLocaleUpperCase()}
 -               </div>
 -               <div className='mb-2 system-xs-regular text-text-tertiary'>
 -                 {t('workflow.panel.addNextStep')}
 -               </div>
 -               <NextStep selectedNode={{ id, data } as Node} />
 -             </div>
 -           )
 -         }
 -       </div>
 -     </div>
 -   )
 - }
 - 
 - export default memo(BasePanel)
 
 
  |