DatasetCard.tsx 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. 'use client'
  2. import { useContext } from 'use-context-selector'
  3. import Link from 'next/link'
  4. import type { MouseEventHandler } from 'react'
  5. import { useCallback, useState } from 'react'
  6. import { useTranslation } from 'react-i18next'
  7. import cn from 'classnames'
  8. import style from '../list.module.css'
  9. import Confirm from '@/app/components/base/confirm'
  10. import { ToastContext } from '@/app/components/base/toast'
  11. import { deleteDataset } from '@/service/datasets'
  12. import AppIcon from '@/app/components/base/app-icon'
  13. import type { DataSet } from '@/models/datasets'
  14. import Tooltip from '@/app/components/base/tooltip'
  15. export type DatasetCardProps = {
  16. dataset: DataSet
  17. onDelete?: () => void
  18. }
  19. const DatasetCard = ({
  20. dataset,
  21. onDelete,
  22. }: DatasetCardProps) => {
  23. const { t } = useTranslation()
  24. const { notify } = useContext(ToastContext)
  25. const [showConfirmDelete, setShowConfirmDelete] = useState(false)
  26. const onDeleteClick: MouseEventHandler = useCallback((e) => {
  27. e.preventDefault()
  28. setShowConfirmDelete(true)
  29. }, [])
  30. const onConfirmDelete = useCallback(async () => {
  31. try {
  32. await deleteDataset(dataset.id)
  33. notify({ type: 'success', message: t('dataset.datasetDeleted') })
  34. if (onDelete)
  35. onDelete()
  36. }
  37. catch (e: any) {
  38. notify({ type: 'error', message: `${t('dataset.datasetDeleteFailed')}${'message' in e ? `: ${e.message}` : ''}` })
  39. }
  40. setShowConfirmDelete(false)
  41. }, [dataset.id])
  42. return (
  43. <>
  44. <Link href={`/datasets/${dataset.id}/documents`} className={cn(style.listItem)}>
  45. <div className={style.listItemTitle}>
  46. <AppIcon size='small' className={cn(!dataset.embedding_available && style.unavailable)} />
  47. <div className={cn(style.listItemHeading, !dataset.embedding_available && style.unavailable)}>
  48. <div className={style.listItemHeadingContent}>
  49. {dataset.name}
  50. </div>
  51. </div>
  52. {!dataset.embedding_available && (
  53. <Tooltip
  54. selector={`dataset-tag-${dataset.id}`}
  55. htmlContent={t('dataset.unavailableTip')}
  56. >
  57. <span className='px-1 border boder-gray-200 rounded-md text-gray-500 text-xs font-normal leading-[18px]'>{t('dataset.unavailable')}</span>
  58. </Tooltip>
  59. )}
  60. <span className={style.deleteDatasetIcon} onClick={onDeleteClick} />
  61. </div>
  62. <div className={cn(style.listItemDescription, !dataset.embedding_available && style.unavailable)}>{dataset.description}</div>
  63. <div className={cn(style.listItemFooter, style.datasetCardFooter, !dataset.embedding_available && style.unavailable)}>
  64. <span className={style.listItemStats}>
  65. <span className={cn(style.listItemFooterIcon, style.docIcon)} />
  66. {dataset.document_count}{t('dataset.documentCount')}
  67. </span>
  68. <span className={style.listItemStats}>
  69. <span className={cn(style.listItemFooterIcon, style.textIcon)} />
  70. {Math.round(dataset.word_count / 1000)}{t('dataset.wordCount')}
  71. </span>
  72. <span className={style.listItemStats}>
  73. <span className={cn(style.listItemFooterIcon, style.applicationIcon)} />
  74. {dataset.app_count}{t('dataset.appCount')}
  75. </span>
  76. </div>
  77. {showConfirmDelete && (
  78. <Confirm
  79. title={t('dataset.deleteDatasetConfirmTitle')}
  80. content={t('dataset.deleteDatasetConfirmContent')}
  81. isShow={showConfirmDelete}
  82. onClose={() => setShowConfirmDelete(false)}
  83. onConfirm={onConfirmDelete}
  84. onCancel={() => setShowConfirmDelete(false)}
  85. />
  86. )}
  87. </Link>
  88. </>
  89. )
  90. }
  91. export default DatasetCard