feat: Move to node in workflow panel and fix help link hover style (#19998)

This commit is contained in:
wellCh4n 2025-05-21 11:29:24 +08:00 committed by GitHub
parent 2266f7cb6a
commit 627911d4ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 80 additions and 1 deletions

View File

@ -24,7 +24,7 @@ const HelpLink = ({
<a <a
href={link} href={link}
target='_blank' target='_blank'
className='mr-1 flex h-6 w-6 items-center justify-center' className='mr-1 flex h-6 w-6 items-center justify-center rounded-md hover:bg-state-base-hover'
> >
<RiBookOpenLine className='h-4 w-4 text-gray-500' /> <RiBookOpenLine className='h-4 w-4 text-gray-500' />
</a> </a>

View File

@ -0,0 +1,54 @@
import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import { RiCrosshairLine } from '@remixicon/react'
import type { XYPosition } from 'reactflow'
import { useReactFlow, useStoreApi } from 'reactflow'
import TooltipPlus from '@/app/components/base/tooltip'
import { useNodesSyncDraft } from '@/app/components/workflow-app/hooks'
type NodePositionProps = {
nodePosition: XYPosition,
nodeWidth?: number | null,
nodeHeight?: number | null,
}
const NodePosition = ({
nodePosition,
nodeWidth,
nodeHeight,
}: NodePositionProps) => {
const { t } = useTranslation()
const reactflow = useReactFlow()
const store = useStoreApi()
const { doSyncWorkflowDraft } = useNodesSyncDraft()
if (!nodePosition || !nodeWidth || !nodeHeight) return null
const workflowContainer = document.getElementById('workflow-container')
const { transform } = store.getState()
const zoom = transform[2]
const { clientWidth, clientHeight } = workflowContainer!
const { setViewport } = reactflow
return (
<TooltipPlus
popupContent={t('workflow.panel.moveToThisNode')}
>
<div
className='mr-1 flex h-6 w-6 cursor-pointer items-center justify-center rounded-md hover:bg-state-base-hover'
onClick={() => {
setViewport({
x: (clientWidth - 400 - nodeWidth * zoom) / 2 - nodePosition.x * zoom,
y: (clientHeight - nodeHeight * zoom) / 2 - nodePosition.y * zoom,
zoom: transform[2],
})
doSyncWorkflowDraft()
}}
>
<RiCrosshairLine className='h-4 w-4 text-text-tertiary' />
</div>
</TooltipPlus>
)
}
export default memo(NodePosition)

View File

@ -16,6 +16,7 @@ import { useTranslation } from 'react-i18next'
import NextStep from './components/next-step' import NextStep from './components/next-step'
import PanelOperator from './components/panel-operator' import PanelOperator from './components/panel-operator'
import HelpLink from './components/help-link' import HelpLink from './components/help-link'
import NodePosition from './components/node-position'
import { import {
DescriptionInput, DescriptionInput,
TitleInput, TitleInput,
@ -55,6 +56,9 @@ const BasePanel: FC<BasePanelProps> = ({
id, id,
data, data,
children, children,
position,
width,
height,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { showMessageLogModal } = useAppStore(useShallow(state => ({ const { showMessageLogModal } = useAppStore(useShallow(state => ({
@ -150,6 +154,7 @@ const BasePanel: FC<BasePanelProps> = ({
</Tooltip> </Tooltip>
) )
} }
<NodePosition nodePosition={position} nodeWidth={width} nodeHeight={height}></NodePosition>
<HelpLink nodeType={data.type} /> <HelpLink nodeType={data.type} />
<PanelOperator id={id} data={data} showHelpLink={false} /> <PanelOperator id={id} data={data} showHelpLink={false} />
<div className='mx-3 h-3.5 w-[1px] bg-divider-regular' /> <div className='mx-3 h-3.5 w-[1px] bg-divider-regular' />

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Blöcke organisieren', organizeBlocks: 'Blöcke organisieren',
change: 'Ändern', change: 'Ändern',
optional: '(optional)', optional: '(optional)',
moveToThisNode: 'Bewege zu diesem Knoten',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -300,6 +300,7 @@ const translation = {
addNextStep: 'Add the next block in this workflow', addNextStep: 'Add the next block in this workflow',
selectNextStep: 'Select Next Block', selectNextStep: 'Select Next Block',
runThisStep: 'Run this step', runThisStep: 'Run this step',
moveToThisNode: 'Move to this node',
checklist: 'Checklist', checklist: 'Checklist',
checklistTip: 'Make sure all issues are resolved before publishing', checklistTip: 'Make sure all issues are resolved before publishing',
checklistResolved: 'All issues are resolved', checklistResolved: 'All issues are resolved',

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Organizar bloques', organizeBlocks: 'Organizar bloques',
change: 'Cambiar', change: 'Cambiar',
optional: '(opcional)', optional: '(opcional)',
moveToThisNode: 'Mueve a este nodo',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'سازماندهی بلوک‌ها', organizeBlocks: 'سازماندهی بلوک‌ها',
change: 'تغییر', change: 'تغییر',
optional: '(اختیاری)', optional: '(اختیاری)',
moveToThisNode: 'به این گره بروید',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Organiser les blocs', organizeBlocks: 'Organiser les blocs',
change: 'Modifier', change: 'Modifier',
optional: '(facultatif)', optional: '(facultatif)',
moveToThisNode: 'Déplacer vers ce nœud',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -314,6 +314,7 @@ const translation = {
organizeBlocks: 'ब्लॉक्स को व्यवस्थित करें', organizeBlocks: 'ब्लॉक्स को व्यवस्थित करें',
change: 'बदलें', change: 'बदलें',
optional: '(वैकल्पिक)', optional: '(वैकल्पिक)',
moveToThisNode: 'इस नोड पर जाएं',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -317,6 +317,7 @@ const translation = {
organizeBlocks: 'Organizza blocchi', organizeBlocks: 'Organizza blocchi',
change: 'Cambia', change: 'Cambia',
optional: '(opzionale)', optional: '(opzionale)',
moveToThisNode: 'Sposta a questo nodo',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -307,6 +307,7 @@ const translation = {
organizeBlocks: 'ノード整理', organizeBlocks: 'ノード整理',
change: '変更', change: '変更',
optional: '(任意)', optional: '(任意)',
moveToThisNode: 'このノードに移動する',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: '블록 정리', organizeBlocks: '블록 정리',
change: '변경', change: '변경',
optional: '(선택사항)', optional: '(선택사항)',
moveToThisNode: '이 노드로 이동',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Organizuj bloki', organizeBlocks: 'Organizuj bloki',
change: 'Zmień', change: 'Zmień',
optional: '(opcjonalne)', optional: '(opcjonalne)',
moveToThisNode: 'Przenieś do tego węzła',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Organizar blocos', organizeBlocks: 'Organizar blocos',
change: 'Mudar', change: 'Mudar',
optional: '(opcional)', optional: '(opcional)',
moveToThisNode: 'Mova-se para este nó',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Organizează blocurile', organizeBlocks: 'Organizează blocurile',
change: 'Schimbă', change: 'Schimbă',
optional: '(opțional)', optional: '(opțional)',
moveToThisNode: 'Mutați la acest nod',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Организовать блоки', organizeBlocks: 'Организовать блоки',
change: 'Изменить', change: 'Изменить',
optional: '(необязательно)', optional: '(необязательно)',
moveToThisNode: 'Перейдите к этому узлу',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -739,6 +739,7 @@ const translation = {
checklistResolved: 'Vse težave so odpravljene', checklistResolved: 'Vse težave so odpravljene',
addNextStep: 'Dodajanje naslednjega bloka v ta potek dela', addNextStep: 'Dodajanje naslednjega bloka v ta potek dela',
change: 'Spremeniti', change: 'Spremeniti',
moveToThisNode: 'Premakni se na to vozlišče',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'จัดระเบียบบล็อก', organizeBlocks: 'จัดระเบียบบล็อก',
change: 'เปลี่ยน', change: 'เปลี่ยน',
optional: '(ไม่บังคับ)', optional: '(ไม่บังคับ)',
moveToThisNode: 'ย้ายไปที่โหนดนี้',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Blokları Düzenle', organizeBlocks: 'Blokları Düzenle',
change: 'Değiştir', change: 'Değiştir',
optional: '(isteğe bağlı)', optional: '(isteğe bağlı)',
moveToThisNode: 'Bu düğüme geç',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Організувати блоки', organizeBlocks: 'Організувати блоки',
change: 'Змінити', change: 'Змінити',
optional: '(необов\'язково)', optional: '(необов\'язково)',
moveToThisNode: 'Перемістіть до цього вузла',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: 'Tổ chức các khối', organizeBlocks: 'Tổ chức các khối',
change: 'Thay đổi', change: 'Thay đổi',
optional: '(tùy chọn)', optional: '(tùy chọn)',
moveToThisNode: 'Di chuyển đến nút này',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -307,6 +307,7 @@ const translation = {
organizeBlocks: '整理节点', organizeBlocks: '整理节点',
change: '更改', change: '更改',
optional: '(选填)', optional: '(选填)',
moveToThisNode: '定位至此节点',
}, },
nodes: { nodes: {
common: { common: {

View File

@ -302,6 +302,7 @@ const translation = {
organizeBlocks: '整理節點', organizeBlocks: '整理節點',
change: '更改', change: '更改',
optional: '(選擇性)', optional: '(選擇性)',
moveToThisNode: '定位至此節點',
}, },
nodes: { nodes: {
common: { common: {