mirror of
https://github.com/langgenius/dify.git
synced 2026-06-08 09:27:39 +08:00
chore: show no empty logic
This commit is contained in:
@ -59,7 +59,7 @@ vi.mock('@/hooks/use-knowledge', () => ({
|
||||
|
||||
vi.mock('@/service/knowledge/use-dataset', () => ({
|
||||
useDatasetList: vi.fn(() => ({
|
||||
data: { pages: [{ data: [] }] },
|
||||
data: { pages: [{ data: [], total: 1 }] },
|
||||
fetchNextPage: vi.fn(),
|
||||
hasNextPage: false,
|
||||
isFetching: false,
|
||||
@ -135,10 +135,18 @@ vi.mock('@/app/components/datasets/create/website/base/checkbox-with-label', ()
|
||||
}))
|
||||
|
||||
describe('List', () => {
|
||||
beforeEach(() => {
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks()
|
||||
mockBrandingEnabled = false
|
||||
mockSearchParams = new URLSearchParams()
|
||||
const { useDatasetList } = await import('@/service/knowledge/use-dataset')
|
||||
vi.mocked(useDatasetList).mockReturnValue({
|
||||
data: { pages: [{ data: [], total: 1 }] },
|
||||
fetchNextPage: vi.fn(),
|
||||
hasNextPage: false,
|
||||
isFetching: false,
|
||||
isFetchingNextPage: false,
|
||||
} as unknown as ReturnType<typeof useDatasetList>)
|
||||
})
|
||||
|
||||
describe('Rendering', () => {
|
||||
@ -190,19 +198,34 @@ describe('List', () => {
|
||||
})
|
||||
|
||||
describe('Props', () => {
|
||||
it('should pass includeAll prop to Datasets', () => {
|
||||
it('should query datasets with includeAll disabled initially', async () => {
|
||||
const { useDatasetList } = await import('@/service/knowledge/use-dataset')
|
||||
|
||||
render(<List />)
|
||||
expect(screen.getByTestId('include-all')).toHaveTextContent('false')
|
||||
|
||||
expect(useDatasetList).toHaveBeenCalledWith(expect.objectContaining({
|
||||
include_all: false,
|
||||
}))
|
||||
})
|
||||
|
||||
it('should pass empty keywords initially', () => {
|
||||
it('should query datasets with empty keywords initially', async () => {
|
||||
const { useDatasetList } = await import('@/service/knowledge/use-dataset')
|
||||
|
||||
render(<List />)
|
||||
expect(screen.getByTestId('keywords')).toHaveTextContent('')
|
||||
|
||||
expect(useDatasetList).toHaveBeenCalledWith(expect.objectContaining({
|
||||
keyword: '',
|
||||
}))
|
||||
})
|
||||
|
||||
it('should pass empty tags initially', () => {
|
||||
it('should query datasets with empty tags initially', async () => {
|
||||
const { useDatasetList } = await import('@/service/knowledge/use-dataset')
|
||||
|
||||
render(<List />)
|
||||
expect(screen.getByTestId('tags')).toHaveTextContent('')
|
||||
|
||||
expect(useDatasetList).toHaveBeenCalledWith(expect.objectContaining({
|
||||
tag_ids: [],
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
@ -256,6 +279,57 @@ describe('List', () => {
|
||||
// Should render without errors even with empty data
|
||||
expect(screen.getByTestId('datasets-component')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render first empty state when there are no datasets and no active filters', async () => {
|
||||
const { useDatasetList } = await import('@/service/knowledge/use-dataset')
|
||||
vi.mocked(useDatasetList).mockReturnValue({
|
||||
data: { pages: [{ data: [], total: 0 }] },
|
||||
fetchNextPage: vi.fn(),
|
||||
hasNextPage: false,
|
||||
isFetching: false,
|
||||
isFetchingNextPage: false,
|
||||
} as unknown as ReturnType<typeof useDatasetList>)
|
||||
|
||||
render(<List />)
|
||||
|
||||
expect(screen.getByText('dataset.firstEmpty.title')).toBeInTheDocument()
|
||||
expect(screen.queryByTestId('datasets-component')).not.toBeInTheDocument()
|
||||
expect(screen.queryByTestId('dataset-footer')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should not render first empty state before the first dataset page resolves', async () => {
|
||||
const { useDatasetList } = await import('@/service/knowledge/use-dataset')
|
||||
vi.mocked(useDatasetList).mockReturnValue({
|
||||
data: { pages: [] },
|
||||
fetchNextPage: vi.fn(),
|
||||
hasNextPage: false,
|
||||
isFetching: false,
|
||||
isFetchingNextPage: false,
|
||||
} as unknown as ReturnType<typeof useDatasetList>)
|
||||
|
||||
render(<List />)
|
||||
|
||||
expect(screen.queryByText('dataset.firstEmpty.title')).not.toBeInTheDocument()
|
||||
expect(screen.getByTestId('datasets-component')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should keep the regular list for empty filtered results', async () => {
|
||||
const { useDatasetList } = await import('@/service/knowledge/use-dataset')
|
||||
vi.mocked(useDatasetList).mockImplementation(params => ({
|
||||
data: { pages: [{ data: [], total: params.include_all ? 0 : 1 }] },
|
||||
fetchNextPage: vi.fn(),
|
||||
hasNextPage: false,
|
||||
isFetching: false,
|
||||
isFetchingNextPage: false,
|
||||
} as unknown as ReturnType<typeof useDatasetList>))
|
||||
|
||||
render(<List />)
|
||||
|
||||
fireEvent.click(screen.getByTestId('include-all-checkbox'))
|
||||
|
||||
expect(screen.getByTestId('datasets-component')).toBeInTheDocument()
|
||||
expect(screen.queryByText('dataset.firstEmpty.title')).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Branch Coverage', () => {
|
||||
|
||||
@ -5,7 +5,7 @@ import { useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { useBoolean, useDebounceFn } from 'ahooks'
|
||||
|
||||
// Libraries
|
||||
import { useState } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
|
||||
@ -15,7 +15,7 @@ import { TagFilter } from '@/features/tag-management/components/tag-filter'
|
||||
import { TagManagementModal } from '@/features/tag-management/components/tag-management-modal'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
import { useSearchParams } from '@/next/navigation'
|
||||
import { useDatasetApiBaseUrl, useInvalidDatasetList } from '@/service/knowledge/use-dataset'
|
||||
import { useDatasetApiBaseUrl, useDatasetList, useInvalidDatasetList } from '@/service/knowledge/use-dataset'
|
||||
import { systemFeaturesQueryOptions } from '@/service/system-features'
|
||||
// Components
|
||||
import ExternalAPIPanel from '../external-api/external-api-panel'
|
||||
@ -55,8 +55,21 @@ const List = () => {
|
||||
}
|
||||
|
||||
const isCurrentWorkspaceManager = useAppContextSelector(state => state.isCurrentWorkspaceManager)
|
||||
const isCurrentWorkspaceEditor = useAppContextSelector(state => state.isCurrentWorkspaceEditor)
|
||||
const { data: apiBaseInfo } = useDatasetApiBaseUrl()
|
||||
const showEmptyDataList = searchParams.get('emptyDataList') === 'true'
|
||||
const emptyDataList = searchParams.get('emptyDataList') === 'true'
|
||||
const datasetListQuery = useDatasetList({
|
||||
initialPage: 1,
|
||||
tag_ids: tagIDs,
|
||||
limit: 30,
|
||||
include_all: includeAll,
|
||||
keyword: searchKeywords,
|
||||
})
|
||||
const pages = useMemo(() => emptyDataList ? [{ data: [], total: 0 }] : datasetListQuery.data?.pages ?? [], [datasetListQuery.data?.pages, emptyDataList])
|
||||
const hasResolvedFirstPage = pages.length > 0
|
||||
const hasAnyDataset = (pages[0]?.total ?? 0) > 0
|
||||
const hasActiveFilters = tagIDs.length > 0 || keywords.trim().length > 0 || searchKeywords.trim().length > 0 || includeAll
|
||||
const showEmptyDataList = !hasAnyDataset && isCurrentWorkspaceEditor && (emptyDataList || (hasResolvedFirstPage && !hasActiveFilters))
|
||||
|
||||
return (
|
||||
<div className="relative flex grow flex-col overflow-y-auto bg-background-body">
|
||||
|
||||
Reference in New Issue
Block a user