add-block.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import {
  2. memo,
  3. useCallback,
  4. } from 'react'
  5. import {
  6. RiAddLine,
  7. } from '@remixicon/react'
  8. import { useTranslation } from 'react-i18next'
  9. import {
  10. useAvailableBlocks,
  11. useNodesInteractions,
  12. useNodesReadOnly,
  13. } from '../../hooks'
  14. import type { IterationNodeType } from './types'
  15. import cn from '@/utils/classnames'
  16. import BlockSelector from '@/app/components/workflow/block-selector'
  17. import type {
  18. OnSelectBlock,
  19. } from '@/app/components/workflow/types'
  20. import {
  21. BlockEnum,
  22. } from '@/app/components/workflow/types'
  23. type AddBlockProps = {
  24. iterationNodeId: string
  25. iterationNodeData: IterationNodeType
  26. }
  27. const AddBlock = ({
  28. iterationNodeData,
  29. }: AddBlockProps) => {
  30. const { t } = useTranslation()
  31. const { nodesReadOnly } = useNodesReadOnly()
  32. const { handleNodeAdd } = useNodesInteractions()
  33. const { availableNextBlocks } = useAvailableBlocks(BlockEnum.Start, true)
  34. const handleSelect = useCallback<OnSelectBlock>((type, toolDefaultValue) => {
  35. handleNodeAdd(
  36. {
  37. nodeType: type,
  38. toolDefaultValue,
  39. },
  40. {
  41. prevNodeId: iterationNodeData.start_node_id,
  42. prevNodeSourceHandle: 'source',
  43. },
  44. )
  45. }, [handleNodeAdd, iterationNodeData.start_node_id])
  46. const renderTriggerElement = useCallback((open: boolean) => {
  47. return (
  48. <div className={cn(
  49. 'relative inline-flex items-center px-3 h-8 rounded-lg border-[0.5px] border-gray-50 bg-white shadow-xs cursor-pointer hover:bg-gray-200 text-[13px] font-medium text-gray-700',
  50. `${nodesReadOnly && '!cursor-not-allowed opacity-50'}`,
  51. open && '!bg-gray-50',
  52. )}>
  53. <RiAddLine className='mr-1 w-4 h-4' />
  54. {t('workflow.common.addBlock')}
  55. </div>
  56. )
  57. }, [nodesReadOnly, t])
  58. return (
  59. <div className='absolute top-7 left-14 flex items-center h-8 z-10'>
  60. <div className='group/insert relative w-16 h-0.5 bg-gray-300'>
  61. <div className='absolute right-0 top-1/2 -translate-y-1/2 w-0.5 h-2 bg-primary-500'></div>
  62. </div>
  63. <BlockSelector
  64. disabled={nodesReadOnly}
  65. onSelect={handleSelect}
  66. trigger={renderTriggerElement}
  67. triggerInnerClassName='inline-flex'
  68. popupClassName='!min-w-[256px]'
  69. availableBlocksTypes={availableNextBlocks}
  70. />
  71. </div>
  72. )
  73. }
  74. export default memo(AddBlock)