iteration-result-panel.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useCallback } from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import { RiCloseLine } from '@remixicon/react'
  6. import { ArrowNarrowLeft } from '../../base/icons/src/vender/line/arrows'
  7. import NodePanel from './node'
  8. import cn from '@/utils/classnames'
  9. import type { NodeTracing } from '@/types/workflow'
  10. const i18nPrefix = 'workflow.singleRun'
  11. type Props = {
  12. list: NodeTracing[][]
  13. onHide: () => void
  14. onBack: () => void
  15. noWrap?: boolean
  16. }
  17. const IterationResultPanel: FC<Props> = ({
  18. list,
  19. onHide,
  20. onBack,
  21. noWrap,
  22. }) => {
  23. const { t } = useTranslation()
  24. const main = (
  25. <>
  26. <div className={cn(!noWrap && 'shrink-0 ', 'pl-4 pr-3 pt-3')}>
  27. <div className='shrink-0 flex justify-between items-center h-8'>
  28. <div className='text-base font-semibold text-gray-900 truncate'>
  29. {t(`${i18nPrefix}.testRunIteration`)}
  30. </div>
  31. <div className='ml-2 shrink-0 p-1 cursor-pointer' onClick={onHide}>
  32. <RiCloseLine className='w-4 h-4 text-gray-500 ' />
  33. </div>
  34. </div>
  35. <div className='flex items-center py-2 space-x-1 text-primary-600 cursor-pointer' onClick={onBack}>
  36. <ArrowNarrowLeft className='w-4 h-4' />
  37. <div className='leading-[18px] text-[13px] font-medium'>{t(`${i18nPrefix}.back`)}</div>
  38. </div>
  39. </div>
  40. {/* List */}
  41. <div className={cn(!noWrap ? 'h-0 grow' : 'max-h-full', 'overflow-y-auto px-4 pb-4 bg-gray-50')}>
  42. {list.map((iteration, index) => (
  43. <div key={index} className={cn('my-4', index === 0 && 'mt-2')}>
  44. <div className='flex items-center'>
  45. <div className='shrink-0 leading-[18px] text-xs font-semibold text-gray-500 uppercase'>{t(`${i18nPrefix}.iteration`)} {index + 1}</div>
  46. <div
  47. className='ml-3 grow w-0 h-px'
  48. style={{ background: 'linear-gradient(to right, #F3F4F6, rgba(243, 244, 246, 0))' }}
  49. ></div>
  50. </div>
  51. <div className='mt-0.5 space-y-1'>
  52. {iteration.map(node => (
  53. <NodePanel
  54. key={node.id}
  55. className='!px-0 !py-0'
  56. nodeInfo={node}
  57. notShowIterationNav
  58. />
  59. ))}
  60. </div>
  61. </div>
  62. ))}
  63. </div>
  64. </>
  65. )
  66. const handleNotBubble = useCallback((e: React.MouseEvent) => {
  67. // if not do this, it will trigger the message log modal disappear(useClickAway)
  68. e.stopPropagation()
  69. e.nativeEvent.stopImmediatePropagation()
  70. }, [])
  71. if (noWrap)
  72. return main
  73. return (
  74. <div
  75. className='absolute inset-0 z-10 rounded-2xl pt-10'
  76. style={{
  77. backgroundColor: 'rgba(16, 24, 40, 0.20)',
  78. }}
  79. onClick={handleNotBubble}
  80. >
  81. <div className='h-full rounded-2xl bg-white flex flex-col'>
  82. {main}
  83. </div>
  84. </div >
  85. )
  86. }
  87. export default React.memo(IterationResultPanel)