node-control.tsx 2.5 KB

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