mirror of
https://github.com/langgenius/dify.git
synced 2026-09-05 08:48:10 +08:00
fix(web): stabilize knowledge upgrade transitions
This commit is contained in:
parent
b821021bd0
commit
4fc0d8bf2a
@ -111,7 +111,7 @@ const datasetListMock = vi.hoisted(() => ({
|
||||
old_dataset_id: string
|
||||
snapshot_at: string
|
||||
stage: 'completed' | 'submitting_documents'
|
||||
status: 'failed' | 'succeeded'
|
||||
status: 'failed' | 'queued' | 'running' | 'succeeded'
|
||||
total_documents: number
|
||||
total_sources: number
|
||||
} | null
|
||||
@ -412,6 +412,51 @@ describe('NewKnowledgeList', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps an active upgrade card when its control space appears before migration completes', () => {
|
||||
setResolvedPage([
|
||||
{
|
||||
createdAt: '2026-08-18T00:00:00Z',
|
||||
id: 'space-1',
|
||||
name: 'space-1',
|
||||
revision: 1,
|
||||
slug: 'space-1',
|
||||
tenantId: 'tenant-1',
|
||||
updatedAt: '2026-08-18T00:00:00Z',
|
||||
},
|
||||
])
|
||||
datasetListMock.data = {
|
||||
data: [
|
||||
{
|
||||
description: 'Legacy knowledge',
|
||||
id: 'dataset-1',
|
||||
knowledge_fs_upgrade: {
|
||||
can_retry: false,
|
||||
can_upgrade: false,
|
||||
job: {
|
||||
completed_documents: 4,
|
||||
completed_sources: 1,
|
||||
id: 'upgrade-1',
|
||||
new_control_space_id: 'space-1',
|
||||
old_dataset_id: 'dataset-1',
|
||||
snapshot_at: '2026-08-18T00:00:00Z',
|
||||
stage: 'submitting_documents',
|
||||
status: 'running',
|
||||
total_documents: 10,
|
||||
total_sources: 1,
|
||||
},
|
||||
},
|
||||
name: 'Support knowledge',
|
||||
tags: [],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
renderWithNuqs(<NewKnowledgeList view="new" onViewChange={vi.fn()} />)
|
||||
|
||||
expect(screen.getByText('upgrade:dataset-1:running')).toBeInTheDocument()
|
||||
expect(screen.queryByRole('link', { name: 'space-1' })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('does not highlight a knowledge space for a historical successful upgrade', () => {
|
||||
setResolvedPage([
|
||||
{
|
||||
|
||||
@ -141,12 +141,21 @@ export function NewKnowledgeList({
|
||||
query: debouncedSearchValue,
|
||||
tagIds,
|
||||
}) &&
|
||||
(!upgrade.job.new_control_space_id ||
|
||||
(upgrade.job.status !== 'succeeded' ||
|
||||
!upgrade.job.new_control_space_id ||
|
||||
!knowledgeSpaces.some(
|
||||
(knowledgeSpace) => knowledgeSpace.control_space_id === upgrade.job.new_control_space_id,
|
||||
)),
|
||||
)
|
||||
const hasVisibleKnowledge = knowledgeSpaces.length > 0 || pendingUpgradeCards.length > 0
|
||||
const pendingUpgradeControlSpaceIds = new Set(
|
||||
pendingUpgradeCards.flatMap((upgrade) =>
|
||||
upgrade.job.new_control_space_id ? [upgrade.job.new_control_space_id] : [],
|
||||
),
|
||||
)
|
||||
const visibleKnowledgeSpaces = knowledgeSpaces.filter(
|
||||
(knowledgeSpace) => !pendingUpgradeControlSpaceIds.has(knowledgeSpace.control_space_id),
|
||||
)
|
||||
const hasVisibleKnowledge = visibleKnowledgeSpaces.length > 0 || pendingUpgradeCards.length > 0
|
||||
|
||||
useEffect(() => {
|
||||
if (!highlightedControlSpaceId) return
|
||||
@ -286,7 +295,7 @@ export function NewKnowledgeList({
|
||||
onSucceeded={setHighlightedControlSpaceId}
|
||||
/>
|
||||
))}
|
||||
{knowledgeSpaces.map((knowledgeSpace) => (
|
||||
{visibleKnowledgeSpaces.map((knowledgeSpace) => (
|
||||
<KnowledgeSpaceCard
|
||||
key={knowledgeSpace.control_space_id}
|
||||
knowledgeSpace={knowledgeSpace}
|
||||
|
||||
@ -376,6 +376,37 @@ describe('consoleQuery transport context', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should not report query cancellation as a transport error', async () => {
|
||||
const request = vi.fn().mockRejectedValue(new DOMException('Aborted', 'AbortError'))
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
const consoleQuery = await loadConsoleQueryWithRequest(request)
|
||||
const queryOptions = consoleQuery.datasets.get.queryOptions({
|
||||
input: { query: { limit: 30, page: 1 } },
|
||||
})
|
||||
|
||||
await Promise.resolve(
|
||||
queryOptions.queryFn({ signal: new AbortController().signal } as QueryFunctionContext),
|
||||
).catch(() => undefined)
|
||||
|
||||
expect(errorSpy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should continue reporting non-cancellation transport errors', async () => {
|
||||
const networkError = new TypeError('Network failed')
|
||||
const request = vi.fn().mockRejectedValue(networkError)
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
const consoleQuery = await loadConsoleQueryWithRequest(request)
|
||||
const queryOptions = consoleQuery.datasets.get.queryOptions({
|
||||
input: { query: { limit: 30, page: 1 } },
|
||||
})
|
||||
|
||||
await Promise.resolve(
|
||||
queryOptions.queryFn({ signal: new AbortController().signal } as QueryFunctionContext),
|
||||
).catch(() => undefined)
|
||||
|
||||
expect(errorSpy).toHaveBeenCalledWith(networkError)
|
||||
})
|
||||
|
||||
it('should serialize trial app dataset ids as repeated query params', async () => {
|
||||
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
|
||||
new Response(
|
||||
|
||||
@ -72,6 +72,16 @@ export type ConsoleClientContext = TanstackQueryOperationContext & {
|
||||
|
||||
type ConsoleClientLink = ClientLink<ConsoleClientContext>
|
||||
|
||||
function isAbortError(error: unknown): boolean {
|
||||
if (!error || typeof error !== 'object') return false
|
||||
if ('name' in error && error.name === 'AbortError') return true
|
||||
return 'cause' in error && isAbortError(error.cause)
|
||||
}
|
||||
|
||||
function reportClientError(error: unknown) {
|
||||
if (!isAbortError(error)) console.error(error)
|
||||
}
|
||||
|
||||
function createConsoleOpenAPILink(contract: AnyContractRouter): ConsoleClientLink {
|
||||
return new OpenAPILink<ConsoleClientContext>(contract, {
|
||||
url: getBaseURL(API_PREFIX),
|
||||
@ -89,7 +99,7 @@ function createConsoleOpenAPILink(contract: AnyContractRouter): ConsoleClientLin
|
||||
},
|
||||
interceptors: [
|
||||
onError((error) => {
|
||||
console.error(error)
|
||||
reportClientError(error)
|
||||
}),
|
||||
],
|
||||
})
|
||||
@ -106,7 +116,7 @@ const marketplaceLink = new OpenAPILink(marketplaceRouterContract, {
|
||||
},
|
||||
interceptors: [
|
||||
onError((error) => {
|
||||
console.error(error)
|
||||
reportClientError(error)
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user