node-control.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import type { FC } from 'react'
  2. import {
  3. memo,
  4. useCallback,
  5. useState,
  6. } from 'react'
  7. import { useTranslation } from 'react-i18next'
  8. import {
  9. useNodeDataUpdate,
  10. useNodesInteractions,
  11. useNodesSyncDraft,
  12. } from '../../../hooks'
  13. import type { Node } from '../../../types'
  14. import { canRunBySingle } from '../../../utils'
  15. import PanelOperator from './panel-operator'
  16. import {
  17. Play,
  18. Stop,
  19. } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
  20. import TooltipPlus from '@/app/components/base/tooltip-plus'
  21. type NodeControlProps = Pick<Node, 'id' | 'data'>
  22. const NodeControl: FC<NodeControlProps> = ({
  23. id,
  24. data,
  25. }) => {
  26. const { t } = useTranslation()
  27. const [open, setOpen] = useState(false)
  28. const { handleNodeDataUpdate } = useNodeDataUpdate()
  29. const { handleNodeSelect } = useNodesInteractions()
  30. const { handleSyncWorkflowDraft } = useNodesSyncDraft()
  31. const handleOpenChange = useCallback((newOpen: boolean) => {
  32. setOpen(newOpen)
  33. }, [])
  34. return (
  35. <div
  36. className={`
  37. hidden group-hover:flex pb-1 absolute right-0 -top-7 h-7
  38. ${data.selected && '!flex'}
  39. ${open && '!flex'}
  40. `}
  41. >
  42. <div
  43. className='flex items-center px-0.5 h-6 bg-white rounded-lg border-[0.5px] border-gray-100 shadow-xs text-gray-500'
  44. onClick={e => e.stopPropagation()}
  45. >
  46. {
  47. canRunBySingle(data.type) && (
  48. <div
  49. className='flex items-center justify-center w-5 h-5 rounded-md cursor-pointer hover:bg-black/5'
  50. onClick={() => {
  51. handleNodeDataUpdate({
  52. id,
  53. data: {
  54. _isSingleRun: !data._isSingleRun,
  55. },
  56. })
  57. handleNodeSelect(id)
  58. if (!data._isSingleRun)
  59. handleSyncWorkflowDraft(true)
  60. }}
  61. >
  62. {
  63. data._isSingleRun
  64. ? <Stop className='w-3 h-3' />
  65. : (
  66. <TooltipPlus
  67. popupContent={t('workflow.panel.runThisStep')}
  68. >
  69. <Play className='w-3 h-3' />
  70. </TooltipPlus>
  71. )
  72. }
  73. </div>
  74. )
  75. }
  76. <PanelOperator
  77. id={id}
  78. data={data}
  79. offset={0}
  80. onOpenChange={handleOpenChange}
  81. triggerClassName='!w-5 !h-5'
  82. />
  83. </div>
  84. </div>
  85. )
  86. }
  87. export default memo(NodeControl)