| <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> |
| 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) |
| 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, | ||||
| 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 => ({ | ||||
| </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' /> |
| 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: { |
| 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', |
| organizeBlocks: 'Organizar bloques', | organizeBlocks: 'Organizar bloques', | ||||
| change: 'Cambiar', | change: 'Cambiar', | ||||
| optional: '(opcional)', | optional: '(opcional)', | ||||
| moveToThisNode: 'Mueve a este nodo', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| organizeBlocks: 'سازماندهی بلوکها', | organizeBlocks: 'سازماندهی بلوکها', | ||||
| change: 'تغییر', | change: 'تغییر', | ||||
| optional: '(اختیاری)', | optional: '(اختیاری)', | ||||
| moveToThisNode: 'به این گره بروید', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| 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: { |
| organizeBlocks: 'ब्लॉक्स को व्यवस्थित करें', | organizeBlocks: 'ब्लॉक्स को व्यवस्थित करें', | ||||
| change: 'बदलें', | change: 'बदलें', | ||||
| optional: '(वैकल्पिक)', | optional: '(वैकल्पिक)', | ||||
| moveToThisNode: 'इस नोड पर जाएं', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| organizeBlocks: 'Organizza blocchi', | organizeBlocks: 'Organizza blocchi', | ||||
| change: 'Cambia', | change: 'Cambia', | ||||
| optional: '(opzionale)', | optional: '(opzionale)', | ||||
| moveToThisNode: 'Sposta a questo nodo', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| organizeBlocks: 'ノード整理', | organizeBlocks: 'ノード整理', | ||||
| change: '変更', | change: '変更', | ||||
| optional: '(任意)', | optional: '(任意)', | ||||
| moveToThisNode: 'このノードに移動する', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| organizeBlocks: '블록 정리', | organizeBlocks: '블록 정리', | ||||
| change: '변경', | change: '변경', | ||||
| optional: '(선택사항)', | optional: '(선택사항)', | ||||
| moveToThisNode: '이 노드로 이동', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| 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: { |
| organizeBlocks: 'Organizar blocos', | organizeBlocks: 'Organizar blocos', | ||||
| change: 'Mudar', | change: 'Mudar', | ||||
| optional: '(opcional)', | optional: '(opcional)', | ||||
| moveToThisNode: 'Mova-se para este nó', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| 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: { |
| organizeBlocks: 'Организовать блоки', | organizeBlocks: 'Организовать блоки', | ||||
| change: 'Изменить', | change: 'Изменить', | ||||
| optional: '(необязательно)', | optional: '(необязательно)', | ||||
| moveToThisNode: 'Перейдите к этому узлу', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| 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: { |
| organizeBlocks: 'จัดระเบียบบล็อก', | organizeBlocks: 'จัดระเบียบบล็อก', | ||||
| change: 'เปลี่ยน', | change: 'เปลี่ยน', | ||||
| optional: '(ไม่บังคับ)', | optional: '(ไม่บังคับ)', | ||||
| moveToThisNode: 'ย้ายไปที่โหนดนี้', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| 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: { |
| organizeBlocks: 'Організувати блоки', | organizeBlocks: 'Організувати блоки', | ||||
| change: 'Змінити', | change: 'Змінити', | ||||
| optional: '(необов\'язково)', | optional: '(необов\'язково)', | ||||
| moveToThisNode: 'Перемістіть до цього вузла', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| 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: { |
| organizeBlocks: '整理节点', | organizeBlocks: '整理节点', | ||||
| change: '更改', | change: '更改', | ||||
| optional: '(选填)', | optional: '(选填)', | ||||
| moveToThisNode: '定位至此节点', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |
| organizeBlocks: '整理節點', | organizeBlocks: '整理節點', | ||||
| change: '更改', | change: '更改', | ||||
| optional: '(選擇性)', | optional: '(選擇性)', | ||||
| moveToThisNode: '定位至此節點', | |||||
| }, | }, | ||||
| nodes: { | nodes: { | ||||
| common: { | common: { |