Merge branch 'dev' of https://github.com/Mai-with-u/MaiBot into dev
This commit is contained in:
@@ -154,6 +154,38 @@ function mockImportDetail(taskId: string): memoryApi.MemoryImportTaskPayload {
|
||||
}
|
||||
}
|
||||
|
||||
function mockImportCompletedWithErrorsDetail(taskId: string): memoryApi.MemoryImportTaskPayload {
|
||||
return {
|
||||
...mockImportDetail(taskId),
|
||||
status: 'completed_with_errors',
|
||||
current_step: 'completed_with_errors',
|
||||
total_chunks: 12,
|
||||
done_chunks: 9,
|
||||
failed_chunks: 3,
|
||||
cancelled_chunks: 0,
|
||||
progress: 75,
|
||||
files: [
|
||||
{
|
||||
file_id: 'file-error',
|
||||
name: 'error.txt',
|
||||
source_kind: 'paste',
|
||||
input_mode: 'text',
|
||||
status: 'failed',
|
||||
current_step: 'failed',
|
||||
detected_strategy_type: 'auto',
|
||||
total_chunks: 12,
|
||||
done_chunks: 9,
|
||||
failed_chunks: 3,
|
||||
cancelled_chunks: 0,
|
||||
progress: 75,
|
||||
error: 'mock error',
|
||||
created_at: 1_710_000_000,
|
||||
updated_at: 1_710_000_100,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
describe('KnowledgeBasePage import workflow', () => {
|
||||
beforeEach(() => {
|
||||
navigateMock.mockReset()
|
||||
@@ -606,6 +638,21 @@ describe('KnowledgeBasePage import workflow', () => {
|
||||
)
|
||||
}, 20_000)
|
||||
|
||||
it('shows import failures separately from successful chunks', async () => {
|
||||
vi.mocked(memoryApi.getMemoryImportTask).mockResolvedValue({
|
||||
success: true,
|
||||
task: mockImportCompletedWithErrorsDetail('import-run-1'),
|
||||
})
|
||||
const user = userEvent.setup()
|
||||
render(<KnowledgeBasePage />)
|
||||
|
||||
await screen.findByText('长期记忆控制台', undefined, { timeout: 10_000 })
|
||||
await user.click(screen.getByRole('tab', { name: '导入' }))
|
||||
|
||||
expect((await screen.findAllByText('完成(有错误)')).length).toBeGreaterThan(0)
|
||||
expect(await screen.findByText('成功 9 / 12 分块 · 失败 3')).toBeInTheDocument()
|
||||
}, 20_000)
|
||||
|
||||
it('supports cancel and retry actions for selected task', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(<KnowledgeBasePage />)
|
||||
|
||||
@@ -39,6 +39,21 @@ import {
|
||||
normalizeProgress,
|
||||
} from '../utils'
|
||||
|
||||
function formatChunkSummary(done: unknown, total: unknown, failed: unknown, cancelled: unknown = 0): string {
|
||||
const doneCount = Number(done ?? 0)
|
||||
const totalCount = Number(total ?? 0)
|
||||
const failedCount = Number(failed ?? 0)
|
||||
const cancelledCount = Number(cancelled ?? 0)
|
||||
const parts = [`成功 ${doneCount} / ${totalCount} 分块`]
|
||||
if (failedCount > 0) {
|
||||
parts.push(`失败 ${failedCount}`)
|
||||
}
|
||||
if (cancelledCount > 0) {
|
||||
parts.push(`取消 ${cancelledCount}`)
|
||||
}
|
||||
return parts.join(' · ')
|
||||
}
|
||||
|
||||
export interface ImportTabProps {
|
||||
importCreateMode: MemoryImportTaskKind
|
||||
setImportCreateMode: Dispatch<SetStateAction<MemoryImportTaskKind>>
|
||||
@@ -1073,12 +1088,19 @@ export function ImportTab(props: ImportTabProps) {
|
||||
? 'success'
|
||||
: String(selectedImportTaskResolved.status ?? '') === 'failed'
|
||||
? 'destructive'
|
||||
: String(selectedImportTaskResolved.status ?? '') === 'cancelled'
|
||||
: String(selectedImportTaskResolved.status ?? '') === 'completed_with_errors'
|
||||
? 'warning'
|
||||
: String(selectedImportTaskResolved.status ?? '') === 'cancelled'
|
||||
? 'muted'
|
||||
: 'default'
|
||||
}
|
||||
busy={RUNNING_IMPORT_STATUS.has(String(selectedImportTaskResolved.status ?? ''))}
|
||||
detail={`已完成 ${Number(selectedImportTaskResolved.done_chunks ?? 0)} / ${Number(selectedImportTaskResolved.total_chunks ?? 0)} 分块`}
|
||||
detail={formatChunkSummary(
|
||||
selectedImportTaskResolved.done_chunks,
|
||||
selectedImportTaskResolved.total_chunks,
|
||||
selectedImportTaskResolved.failed_chunks,
|
||||
selectedImportTaskResolved.cancelled_chunks,
|
||||
)}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -1160,7 +1182,12 @@ export function ImportTab(props: ImportTabProps) {
|
||||
</div>
|
||||
<Progress value={normalizeProgress(file.progress)} className="mt-2 h-1.5" />
|
||||
<div className="mt-2 text-xs text-muted-foreground">
|
||||
{formatProgressPercent(file.progress)} · {Number(file.done_chunks ?? 0)} / {Number(file.total_chunks ?? 0)}
|
||||
{formatProgressPercent(file.progress)} · {formatChunkSummary(
|
||||
file.done_chunks,
|
||||
file.total_chunks,
|
||||
file.failed_chunks,
|
||||
file.cancelled_chunks,
|
||||
)}
|
||||
</div>
|
||||
{file.error ? (
|
||||
<div className="mt-2 truncate text-xs text-destructive">{file.error}</div>
|
||||
|
||||
Reference in New Issue
Block a user