Datasets.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. 'use client'
  2. import { useEffect, useRef } from 'react'
  3. import useSWRInfinite from 'swr/infinite'
  4. import { debounce } from 'lodash-es'
  5. import { useTranslation } from 'react-i18next'
  6. import NewDatasetCard from './NewDatasetCard'
  7. import DatasetCard from './DatasetCard'
  8. import type { DataSetListResponse } from '@/models/datasets'
  9. import { fetchDatasets } from '@/service/datasets'
  10. import { useAppContext } from '@/context/app-context'
  11. const getKey = (
  12. pageIndex: number,
  13. previousPageData: DataSetListResponse,
  14. tags: string[],
  15. keyword: string,
  16. ) => {
  17. if (!pageIndex || previousPageData.has_more) {
  18. const params: any = {
  19. url: 'datasets',
  20. params: {
  21. page: pageIndex + 1,
  22. limit: 30,
  23. },
  24. }
  25. if (tags.length)
  26. params.params.tag_ids = tags
  27. if (keyword)
  28. params.params.keyword = keyword
  29. return params
  30. }
  31. return null
  32. }
  33. type Props = {
  34. containerRef: React.RefObject<HTMLDivElement>
  35. tags: string[]
  36. keywords: string
  37. }
  38. const Datasets = ({
  39. containerRef,
  40. tags,
  41. keywords,
  42. }: Props) => {
  43. const { isCurrentWorkspaceEditor } = useAppContext()
  44. const { data, isLoading, setSize, mutate } = useSWRInfinite(
  45. (pageIndex: number, previousPageData: DataSetListResponse) => getKey(pageIndex, previousPageData, tags, keywords),
  46. fetchDatasets,
  47. { revalidateFirstPage: false, revalidateAll: true },
  48. )
  49. const loadingStateRef = useRef(false)
  50. const anchorRef = useRef<HTMLAnchorElement>(null)
  51. const { t } = useTranslation()
  52. useEffect(() => {
  53. loadingStateRef.current = isLoading
  54. document.title = `${t('dataset.datasets')} - 智脑云平台`
  55. }, [isLoading])
  56. useEffect(() => {
  57. const onScroll = debounce(() => {
  58. if (!loadingStateRef.current) {
  59. const { scrollTop, clientHeight } = containerRef.current!
  60. const anchorOffset = anchorRef.current!.offsetTop
  61. if (anchorOffset - scrollTop - clientHeight < 100)
  62. setSize(size => size + 1)
  63. }
  64. }, 50)
  65. containerRef.current?.addEventListener('scroll', onScroll)
  66. return () => containerRef.current?.removeEventListener('scroll', onScroll)
  67. }, [])
  68. return (
  69. <nav className='grid content-start grid-cols-1 gap-4 px-12 pt-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 grow shrink-0'>
  70. { isCurrentWorkspaceEditor && <NewDatasetCard ref={anchorRef} /> }
  71. {data?.map(({ data: datasets }) => datasets.map(dataset => (
  72. <DatasetCard key={dataset.id} dataset={dataset} onSuccess={mutate} />),
  73. ))}
  74. </nav>
  75. )
  76. }
  77. export default Datasets