file-list-in-log.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import React, { useMemo, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { RiArrowRightSLine } from '@remixicon/react'
  4. import FileImageRender from './file-image-render'
  5. import FileTypeIcon from './file-type-icon'
  6. import FileItem from './file-uploader-in-attachment/file-item'
  7. import type { FileEntity } from './types'
  8. import {
  9. getFileAppearanceType,
  10. } from './utils'
  11. import Tooltip from '@/app/components/base/tooltip'
  12. import { SupportUploadFileTypes } from '@/app/components/workflow/types'
  13. import cn from '@/utils/classnames'
  14. type Props = {
  15. fileList: {
  16. varName: string
  17. list: FileEntity[]
  18. }[]
  19. isExpanded?: boolean
  20. noBorder?: boolean
  21. noPadding?: boolean
  22. }
  23. const FileListInLog = ({ fileList, isExpanded = false, noBorder = false, noPadding = false }: Props) => {
  24. const { t } = useTranslation()
  25. const [expanded, setExpanded] = useState(isExpanded)
  26. const fullList = useMemo(() => {
  27. return fileList.reduce((acc: FileEntity[], { list }) => {
  28. return [...acc, ...list]
  29. }, [])
  30. }, [fileList])
  31. if (!fileList.length)
  32. return null
  33. return (
  34. <div className={cn('px-3 py-2', expanded && 'py-3', !noBorder && 'border-t border-divider-subtle', noPadding && '!p-0')}>
  35. <div className='flex justify-between gap-1'>
  36. {expanded && (
  37. <div className='grow py-1 text-text-secondary system-xs-semibold-uppercase cursor-pointer' onClick={() => setExpanded(!expanded)}>{t('appLog.runDetail.fileListLabel')}</div>
  38. )}
  39. {!expanded && (
  40. <div className='flex gap-1'>
  41. {fullList.map((file) => {
  42. const { id, name, type, supportFileType, base64Url, url } = file
  43. const isImageFile = supportFileType === SupportUploadFileTypes.image
  44. return (
  45. <>
  46. {isImageFile && (
  47. <Tooltip
  48. popupContent={name}
  49. >
  50. <div key={id}>
  51. <FileImageRender
  52. className='w-8 h-8'
  53. imageUrl={base64Url || url || ''}
  54. />
  55. </div>
  56. </Tooltip>
  57. )}
  58. {!isImageFile && (
  59. <Tooltip
  60. popupContent={name}
  61. >
  62. <div key={id} className='p-1.5 rounded-md bg-components-panel-on-panel-item-bg border-[0.5px] border-components-panel-border shadow-xs'>
  63. <FileTypeIcon
  64. type={getFileAppearanceType(name, type)}
  65. size='md'
  66. />
  67. </div>
  68. </Tooltip>
  69. )}
  70. </>
  71. )
  72. })}
  73. </div>
  74. )}
  75. <div className='flex items-center gap-1 cursor-pointer' onClick={() => setExpanded(!expanded)}>
  76. {!expanded && <div className='text-text-tertiary system-xs-medium-uppercase'>{t('appLog.runDetail.fileListDetail')}</div>}
  77. <RiArrowRightSLine className={cn('w-4 h-4 text-text-tertiary', expanded && 'rotate-90')} />
  78. </div>
  79. </div>
  80. {expanded && (
  81. <div className='flex flex-col gap-3'>
  82. {fileList.map(item => (
  83. <div key={item.varName} className='flex flex-col gap-1 system-xs-regular'>
  84. <div className='py-1 text-text-tertiary '>{item.varName}</div>
  85. {item.list.map(file => (
  86. <FileItem
  87. key={file.id}
  88. file={file}
  89. showDeleteAction={false}
  90. showDownloadAction
  91. canPreview
  92. />
  93. ))}
  94. </div>
  95. ))}
  96. </div>
  97. )}
  98. </div>
  99. )
  100. }
  101. export default FileListInLog