mirror of
http://112.124.100.131/huang.ze/ebiz-dify-ai.git
synced 2025-12-20 00:06:56 +08:00
feat: workflow interaction (#4214)
This commit is contained in:
@@ -5,6 +5,8 @@ import {
|
||||
useCallback,
|
||||
useState,
|
||||
} from 'react'
|
||||
import cn from 'classnames'
|
||||
import { useKeyPress } from 'ahooks'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
useReactFlow,
|
||||
@@ -14,13 +16,32 @@ import {
|
||||
useNodesSyncDraft,
|
||||
useWorkflowReadOnly,
|
||||
} from '../hooks'
|
||||
import {
|
||||
getKeyboardKeyCodeBySystem,
|
||||
getKeyboardKeyNameBySystem,
|
||||
} from '../utils'
|
||||
import ShortcutsName from '../shortcuts-name'
|
||||
import TipPopup from './tip-popup'
|
||||
import {
|
||||
PortalToFollowElem,
|
||||
PortalToFollowElemContent,
|
||||
PortalToFollowElemTrigger,
|
||||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
import { SearchLg } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
import {
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
} from '@/app/components/base/icons/src/vender/line/editor'
|
||||
|
||||
enum ZoomType {
|
||||
zoomIn = 'zoomIn',
|
||||
zoomOut = 'zoomOut',
|
||||
zoomToFit = 'zoomToFit',
|
||||
zoomTo25 = 'zoomTo25',
|
||||
zoomTo50 = 'zoomTo50',
|
||||
zoomTo75 = 'zoomTo75',
|
||||
zoomTo100 = 'zoomTo100',
|
||||
zoomTo200 = 'zoomTo200',
|
||||
}
|
||||
|
||||
const ZoomInOut: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
@@ -41,27 +62,29 @@ const ZoomInOut: FC = () => {
|
||||
const ZOOM_IN_OUT_OPTIONS = [
|
||||
[
|
||||
{
|
||||
key: 'in',
|
||||
text: t('workflow.operator.zoomIn'),
|
||||
key: ZoomType.zoomTo200,
|
||||
text: '200%',
|
||||
},
|
||||
{
|
||||
key: 'out',
|
||||
text: t('workflow.operator.zoomOut'),
|
||||
key: ZoomType.zoomTo100,
|
||||
text: '100%',
|
||||
},
|
||||
{
|
||||
key: ZoomType.zoomTo75,
|
||||
text: '75%',
|
||||
},
|
||||
{
|
||||
key: ZoomType.zoomTo50,
|
||||
text: '50%',
|
||||
},
|
||||
{
|
||||
key: ZoomType.zoomTo25,
|
||||
text: '25%',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
key: 'to50',
|
||||
text: t('workflow.operator.zoomTo50'),
|
||||
},
|
||||
{
|
||||
key: 'to100',
|
||||
text: t('workflow.operator.zoomTo100'),
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
key: 'fit',
|
||||
key: ZoomType.zoomToFit,
|
||||
text: t('workflow.operator.zoomToFit'),
|
||||
},
|
||||
],
|
||||
@@ -71,24 +94,99 @@ const ZoomInOut: FC = () => {
|
||||
if (workflowReadOnly)
|
||||
return
|
||||
|
||||
if (type === 'in')
|
||||
zoomIn()
|
||||
|
||||
if (type === 'out')
|
||||
zoomOut()
|
||||
|
||||
if (type === 'fit')
|
||||
if (type === ZoomType.zoomToFit)
|
||||
fitView()
|
||||
|
||||
if (type === 'to50')
|
||||
if (type === ZoomType.zoomTo25)
|
||||
zoomTo(0.25)
|
||||
|
||||
if (type === ZoomType.zoomTo50)
|
||||
zoomTo(0.5)
|
||||
|
||||
if (type === 'to100')
|
||||
if (type === ZoomType.zoomTo75)
|
||||
zoomTo(0.75)
|
||||
|
||||
if (type === ZoomType.zoomTo100)
|
||||
zoomTo(1)
|
||||
|
||||
if (type === ZoomType.zoomTo200)
|
||||
zoomTo(2)
|
||||
|
||||
handleSyncWorkflowDraft()
|
||||
}
|
||||
|
||||
useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.1`, (e) => {
|
||||
e.preventDefault()
|
||||
if (workflowReadOnly)
|
||||
return
|
||||
|
||||
fitView()
|
||||
handleSyncWorkflowDraft()
|
||||
}, {
|
||||
exactMatch: true,
|
||||
useCapture: true,
|
||||
})
|
||||
|
||||
useKeyPress('shift.1', (e) => {
|
||||
e.preventDefault()
|
||||
if (workflowReadOnly)
|
||||
return
|
||||
|
||||
zoomTo(1)
|
||||
handleSyncWorkflowDraft()
|
||||
}, {
|
||||
exactMatch: true,
|
||||
useCapture: true,
|
||||
})
|
||||
|
||||
useKeyPress('shift.2', (e) => {
|
||||
e.preventDefault()
|
||||
if (workflowReadOnly)
|
||||
return
|
||||
|
||||
zoomTo(2)
|
||||
handleSyncWorkflowDraft()
|
||||
}, {
|
||||
exactMatch: true,
|
||||
useCapture: true,
|
||||
})
|
||||
|
||||
useKeyPress('shift.5', (e) => {
|
||||
e.preventDefault()
|
||||
if (workflowReadOnly)
|
||||
return
|
||||
|
||||
zoomTo(0.5)
|
||||
handleSyncWorkflowDraft()
|
||||
}, {
|
||||
exactMatch: true,
|
||||
useCapture: true,
|
||||
})
|
||||
|
||||
useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.dash`, (e) => {
|
||||
e.preventDefault()
|
||||
if (workflowReadOnly)
|
||||
return
|
||||
|
||||
zoomOut()
|
||||
handleSyncWorkflowDraft()
|
||||
}, {
|
||||
exactMatch: true,
|
||||
useCapture: true,
|
||||
})
|
||||
|
||||
useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.equalsign`, (e) => {
|
||||
e.preventDefault()
|
||||
if (workflowReadOnly)
|
||||
return
|
||||
|
||||
zoomIn()
|
||||
handleSyncWorkflowDraft()
|
||||
}, {
|
||||
exactMatch: true,
|
||||
useCapture: true,
|
||||
})
|
||||
|
||||
const handleTrigger = useCallback(() => {
|
||||
if (getWorkflowReadOnly())
|
||||
return
|
||||
@@ -108,17 +206,47 @@ const ZoomInOut: FC = () => {
|
||||
>
|
||||
<PortalToFollowElemTrigger asChild onClick={handleTrigger}>
|
||||
<div className={`
|
||||
flex items-center px-2 h-8 cursor-pointer text-[13px] hover:bg-gray-50 rounded-lg
|
||||
${open && 'bg-gray-50'}
|
||||
p-0.5 h-9 cursor-pointer text-[13px] text-gray-500 font-medium rounded-lg bg-white shadow-lg border-[0.5px] border-gray-100
|
||||
${workflowReadOnly && '!cursor-not-allowed opacity-50'}
|
||||
`}>
|
||||
<SearchLg className='mr-1 w-4 h-4' />
|
||||
<div className='w-[34px]'>{parseFloat(`${zoom * 100}`).toFixed(0)}%</div>
|
||||
<ChevronDown className='ml-1 w-4 h-4' />
|
||||
<div className={cn(
|
||||
'flex items-center justify-between w-[98px] h-8 hover:bg-gray-50 rounded-lg',
|
||||
open && 'bg-gray-50',
|
||||
)}>
|
||||
<TipPopup
|
||||
title={t('workflow.operator.zoomOut')}
|
||||
shortcuts={['ctrl', '-']}
|
||||
>
|
||||
<div
|
||||
className='flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer hover:bg-black/5'
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
zoomOut()
|
||||
}}
|
||||
>
|
||||
<ZoomOut className='w-4 h-4' />
|
||||
</div>
|
||||
</TipPopup>
|
||||
<div className='w-[34px]'>{parseFloat(`${zoom * 100}`).toFixed(0)}%</div>
|
||||
<TipPopup
|
||||
title={t('workflow.operator.zoomIn')}
|
||||
shortcuts={['ctrl', '+']}
|
||||
>
|
||||
<div
|
||||
className='flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer hover:bg-black/5'
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
zoomIn()
|
||||
}}
|
||||
>
|
||||
<ZoomIn className='w-4 h-4' />
|
||||
</div>
|
||||
</TipPopup>
|
||||
</div>
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-10'>
|
||||
<div className='w-[168px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg'>
|
||||
<div className='w-[145px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg'>
|
||||
{
|
||||
ZOOM_IN_OUT_OPTIONS.map((options, i) => (
|
||||
<Fragment key={i}>
|
||||
@@ -132,10 +260,30 @@ const ZoomInOut: FC = () => {
|
||||
options.map(option => (
|
||||
<div
|
||||
key={option.key}
|
||||
className='flex items-center px-3 h-8 rounded-lg hover:bg-gray-50 cursor-pointer text-sm text-gray-700'
|
||||
className='flex items-center justify-between px-3 h-8 rounded-lg hover:bg-gray-50 cursor-pointer text-sm text-gray-700'
|
||||
onClick={() => handleZoom(option.key)}
|
||||
>
|
||||
{option.text}
|
||||
{
|
||||
option.key === ZoomType.zoomToFit && (
|
||||
<ShortcutsName keys={[`${getKeyboardKeyNameBySystem('ctrl')}`, '1']} />
|
||||
)
|
||||
}
|
||||
{
|
||||
option.key === ZoomType.zoomTo50 && (
|
||||
<ShortcutsName keys={['shift', '5']} />
|
||||
)
|
||||
}
|
||||
{
|
||||
option.key === ZoomType.zoomTo100 && (
|
||||
<ShortcutsName keys={['shift', '1']} />
|
||||
)
|
||||
}
|
||||
{
|
||||
option.key === ZoomType.zoomTo200 && (
|
||||
<ShortcutsName keys={['shift', '2']} />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user