| import { |
| memo, |
| useEffect, |
| useRef, |
| } from 'react' |
| import { useTranslation } from 'react-i18next' |
| import { useClickAway } from 'ahooks' |
| import ShortcutsName from './shortcuts-name' |
| import { useStore } from './store' |
| import { |
| useDSL, |
| useNodesInteractions, |
| usePanelInteractions, |
| useWorkflowStartRun, |
| } from './hooks' |
| import AddBlock from './operator/add-block' |
| import { useOperator } from './operator/hooks' |
| import cn from '@/utils/classnames' |
|
|
| const PanelContextmenu = () => { |
| const { t } = useTranslation() |
| const ref = useRef(null) |
| const panelMenu = useStore(s => s.panelMenu) |
| const clipboardElements = useStore(s => s.clipboardElements) |
| const setShowImportDSLModal = useStore(s => s.setShowImportDSLModal) |
| const { handleNodesPaste } = useNodesInteractions() |
| const { handlePaneContextmenuCancel, handleNodeContextmenuCancel } = usePanelInteractions() |
| const { handleStartWorkflowRun } = useWorkflowStartRun() |
| const { handleAddNote } = useOperator() |
| const { exportCheck } = useDSL() |
|
|
| useEffect(() => { |
| if (panelMenu) |
| handleNodeContextmenuCancel() |
| }, [panelMenu, handleNodeContextmenuCancel]) |
|
|
| useClickAway(() => { |
| handlePaneContextmenuCancel() |
| }, ref) |
|
|
| const renderTrigger = () => { |
| return ( |
| <div |
| className='flex items-center justify-between px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50' |
| > |
| {t('workflow.common.addBlock')} |
| </div> |
| ) |
| } |
|
|
| if (!panelMenu) |
| return null |
|
|
| return ( |
| <div |
| className='absolute w-[200px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-xl z-[9]' |
| style={{ |
| left: panelMenu.left, |
| top: panelMenu.top, |
| }} |
| ref={ref} |
| > |
| <div className='p-1'> |
| <AddBlock |
| renderTrigger={renderTrigger} |
| offset={{ |
| mainAxis: -36, |
| crossAxis: -4, |
| }} |
| /> |
| <div |
| className='flex items-center justify-between px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50' |
| onClick={(e) => { |
| e.stopPropagation() |
| handleAddNote() |
| handlePaneContextmenuCancel() |
| }} |
| > |
| {t('workflow.nodes.note.addNote')} |
| </div> |
| <div |
| className='flex items-center justify-between px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50' |
| onClick={() => { |
| handleStartWorkflowRun() |
| handlePaneContextmenuCancel() |
| }} |
| > |
| {t('workflow.common.run')} |
| <ShortcutsName keys={['alt', 'r']} /> |
| </div> |
| </div> |
| <div className='h-[1px] bg-gray-100'></div> |
| <div className='p-1'> |
| <div |
| className={cn( |
| 'flex items-center justify-between px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer', |
| !clipboardElements.length ? 'opacity-50 cursor-not-allowed' : 'hover:bg-gray-50', |
| )} |
| onClick={() => { |
| if (clipboardElements.length) { |
| handleNodesPaste() |
| handlePaneContextmenuCancel() |
| } |
| }} |
| > |
| {t('workflow.common.pasteHere')} |
| <ShortcutsName keys={['ctrl', 'v']} /> |
| </div> |
| </div> |
| <div className='h-[1px] bg-gray-100'></div> |
| <div className='p-1'> |
| <div |
| className='flex items-center justify-between px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50' |
| onClick={() => exportCheck()} |
| > |
| {t('app.export')} |
| </div> |
| <div |
| className='flex items-center justify-between px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50' |
| onClick={() => setShowImportDSLModal(true)} |
| > |
| {t('workflow.common.importDSL')} |
| </div> |
| </div> |
| </div> |
| ) |
| } |
|
|
| export default memo(PanelContextmenu) |
|
|