fix(dataset): stabilize New RAG re-index task handling

This commit is contained in:
Stephen Zhou 2026-07-30 23:51:33 +08:00
parent 3190ea955a
commit cb02cdd545
No known key found for this signature in database
36 changed files with 993 additions and 436 deletions

View File

@ -1,4 +1,5 @@
import type {
BackgroundTask,
DocumentProcessingTask,
DocumentRevisionChunk,
LogicalDocument,
@ -27,7 +28,7 @@ type InfiniteOptions = {
getNextPageParam: (lastPage: { next_cursor?: string | null }) => string | null | undefined
input: (pageParam: string | null) => unknown
initialPageParam: string | null
queryKind: 'chunks' | 'revisions' | 'tasks'
queryKind: 'chunks' | 'documents' | 'revisions' | 'tasks'
}
function infiniteInput(options?: Pick<InfiniteOptions, 'input'>) {
@ -41,6 +42,18 @@ const documentQuery = vi.hoisted(() => ({
isPending: false,
refetch: vi.fn(),
}))
const submittedJobQuery = vi.hoisted(() => ({
data: undefined as
| {
id: string
run_state?: string | null
stage?: string | null
updated_at?: number
}
| undefined,
error: null as unknown,
isPending: false,
}))
const revisionsQuery = vi.hoisted(() => ({
data: undefined as
@ -69,9 +82,7 @@ const chunksQuery = vi.hoisted(() => ({
}))
const tasksQuery = vi.hoisted(() => ({
data: undefined as
| { pages: Array<{ items: DocumentProcessingTask[]; nextCursor?: string }> }
| undefined,
data: undefined as { pages: Array<{ items: BackgroundTask[]; nextCursor?: string }> } | undefined,
error: null as unknown,
fetchNextPage: vi.fn(),
hasNextPage: false,
@ -88,6 +99,7 @@ const permissionState = vi.hoisted(() => ({
refresh: vi.fn(),
}))
const reindexMutation = vi.hoisted(() => ({ mutateAsync: vi.fn() }))
const cancelMutation = vi.hoisted(() => ({ mutateAsync: vi.fn() }))
const routerMock = vi.hoisted(() => ({ push: vi.fn() }))
const settingsState = vi.hoisted(() => ({
configurationState: 'active' as 'active' | 'setup-required',
@ -114,6 +126,20 @@ const revisionApiResponse = vi.hoisted(
state: revision.state,
}),
)
const logicalDocumentApiResponse = vi.hoisted(() => (item: LogicalDocument) => ({
active: item.active ? revisionApiResponse(item.active) : null,
active_revision: item.activeRevision ?? null,
created_at: item.createdAt,
id: item.id,
knowledge_space_id: item.knowledgeSpaceId,
provider_item_id: item.providerItemId ?? null,
row_version: item.rowVersion,
source_id: item.sourceId ?? null,
status: item.status,
title: item.title,
updated_at: item.updatedAt,
user_metadata: item.userMetadata,
}))
const chunkApiResponse = vi.hoisted(() => (item: DocumentRevisionChunk) => ({
created_at: item.createdAt,
document_id: item.documentId,
@ -127,19 +153,20 @@ const chunkApiResponse = vi.hoisted(() => (item: DocumentRevisionChunk) => ({
token_count: item.tokenCount,
user_metadata: item.userMetadata,
}))
const taskApiResponse = vi.hoisted(() => (item: DocumentProcessingTask) => ({
const taskApiResponse = vi.hoisted(() => (item: BackgroundTask) => ({
can_cancel: item.canCancel ?? true,
can_retry: item.canRetry ?? item.state === 'failed',
completed_at: item.completedAt ?? null,
created_at: item.createdAt,
document_id: item.documentId,
document_revision: item.documentRevision,
document_id: item.documentId ?? null,
document_revision: item.documentRevision ?? null,
error_code: item.errorCode ?? null,
error_message: item.errorMessage ?? null,
id: item.id,
knowledge_space_id: item.knowledgeSpaceId,
operation: item.operation ?? 'document_processing',
progress_percent: item.progressPercent,
source_id: item.sourceId ?? null,
state:
item.state === 'succeeded'
? 'completed'
@ -158,6 +185,13 @@ const documentOptions = vi.hoisted(() =>
queryKind: 'document',
})),
)
const submittedJobOptions = vi.hoisted(() =>
vi.fn((options: object) => ({
...options,
queryKey: ['knowledge-fs', 'job'],
queryKind: 'submitted-job',
})),
)
const settingsOptions = vi.hoisted(() =>
vi.fn(({ input }: { input: unknown }) => ({
queryKey: ['knowledge-fs', 'settings', input],
@ -185,6 +219,13 @@ const documentTasksOptions = vi.hoisted(() =>
queryKind: 'tasks',
})),
)
const documentsOptions = vi.hoisted(() =>
vi.fn((options: Omit<InfiniteOptions, 'queryKind'>) => ({
...options,
queryKey: ['knowledge-fs', 'documents', 'space-1'],
queryKind: 'documents',
})),
)
vi.mock('jotai', async (importOriginal) => {
const original = await importOriginal<typeof import('jotai')>()
@ -235,6 +276,20 @@ vi.mock('@tanstack/react-query', async (importOriginal) => {
return {
...original,
useInfiniteQuery: (options: InfiniteOptions) => {
if (options.queryKind === 'documents')
return {
...tasksQuery,
data: documentQuery.data
? {
pages: [
{
data: [logicalDocumentApiResponse(documentQuery.data)],
next_cursor: null,
},
],
}
: undefined,
}
if (options.queryKind === 'revisions')
return {
...revisionsQuery,
@ -278,19 +333,22 @@ vi.mock('@tanstack/react-query', async (importOriginal) => {
: undefined,
}
},
useMutation: () => reindexMutation,
useQuery: (options: { queryKind?: string }) =>
options.queryKind === 'settings'
? {
data: {
configuration_state: settingsState.configurationState,
embedding: null,
retrieval: null,
revision: 1,
},
refetch: settingsState.refetch,
}
: documentQuery,
useMutation: (options: { mutationKind?: string }) =>
options.mutationKind === 'cancel' ? cancelMutation : reindexMutation,
useQuery: (options: { queryKind?: string }) => {
if (options.queryKind === 'settings')
return {
data: {
configuration_state: settingsState.configurationState,
embedding: null,
retrieval: null,
revision: 1,
},
refetch: settingsState.refetch,
}
if (options.queryKind === 'submitted-job') return submittedJobQuery
return documentQuery
},
useQueryClient: () => queryClient,
}
})
@ -301,6 +359,15 @@ vi.mock('@/service/client', () => ({
spaces: {
byControlSpaceId: {
backgroundTasks: {
byTaskKind: {
byTaskId: {
cancel: {
post: {
mutationOptions: () => ({ mutationKind: 'cancel' }),
},
},
},
},
get: {
infiniteOptions: documentTasksOptions,
key: () => ['knowledge-fs', 'tasks'],
@ -336,6 +403,17 @@ vi.mock('@/service/client', () => ({
key: () => ['knowledge-fs', 'document'],
},
},
get: {
infiniteOptions: documentsOptions,
key: () => ['knowledge-fs', 'documents'],
},
},
jobs: {
byJobId: {
get: {
queryOptions: submittedJobOptions,
},
},
},
settings: {
get: {
@ -397,13 +475,28 @@ const task = (overrides: Partial<DocumentProcessingTask>): DocumentProcessingTas
documentRevision: 4,
id: 'task-1',
knowledgeSpaceId: 'space-1',
operation: 'document_processing',
progressPercent: 45,
stage: 'nodes_generated',
state: 'running',
taskKind: 'document',
updatedAt: '2026-07-21T10:01:00Z',
...overrides,
})
const backgroundTask = (overrides: Partial<BackgroundTask> = {}): BackgroundTask => ({
createdAt: '2026-07-21T10:00:00Z',
id: 'background-task-1',
knowledgeSpaceId: 'space-1',
operation: 'document_reindex',
progressPercent: 100,
stage: 'published',
state: 'succeeded',
taskKind: 'document_bulk',
updatedAt: '2026-07-21T10:02:00Z',
...overrides,
})
const queuedReindexResult = (): BulkDocumentReindexResult => ({
bulkJobId: 'bulk-job-1',
items: [
@ -437,10 +530,14 @@ const missingReindexResult = (): BulkDocumentReindexResult => ({
describe('DocumentDetailPage', () => {
beforeEach(() => {
vi.clearAllMocks()
globalThis.sessionStorage.clear()
permissionState.keys = ['dataset.acl.edit']
documentQuery.data = logicalDocument()
documentQuery.error = null
documentQuery.isPending = false
submittedJobQuery.data = undefined
submittedJobQuery.error = null
submittedJobQuery.isPending = false
revisionsQuery.data = { pages: [{ items: [activeRevision()] }] }
revisionsQuery.error = null
revisionsQuery.hasNextPage = false
@ -474,10 +571,12 @@ describe('DocumentDetailPage', () => {
isError: false,
}))
reindexMutation.mutateAsync.mockResolvedValue(queuedReindexResult())
cancelMutation.mutateAsync.mockResolvedValue(taskApiResponse(task({ state: 'canceled' })))
queryClient.invalidateQueries.mockResolvedValue(undefined)
})
afterEach(() => {
globalThis.sessionStorage.clear()
vi.unstubAllGlobals()
})
@ -556,7 +655,7 @@ describe('DocumentDetailPage', () => {
expect(screen.queryByText(/\[Learn more\]\(/)).not.toBeInTheDocument()
})
it('expands the parent-child tree and shows selected chunk content and metadata', async () => {
it('expands the parent-child tree without mixing selected chunk metadata into document facts', async () => {
const user = userEvent.setup()
chunksQuery.data = {
pages: [
@ -595,13 +694,16 @@ describe('DocumentDetailPage', () => {
)
expect(copy).toHaveBeenCalledWith('Workspace contract details')
expect(toastState.success).toHaveBeenCalledWith('common.actionMsg.copySuccessfully')
const characterCount = screen.getByText('dataset.newKnowledge.characterCount').closest('div')
expect(characterCount).not.toBeNull()
expect(within(characterCount!).getByText('26')).toBeInTheDocument()
expect(screen.getByText('section')).toBeInTheDocument()
expect(screen.getByText('2.1')).toBeInTheDocument()
expect(screen.getByText('sourcePage')).toBeInTheDocument()
expect(screen.getByText('8')).toBeInTheDocument()
expect(screen.getByRole('heading', { name: 'dataset.metadata.metadata' })).toBeInTheDocument()
expect(screen.getByText('common.operation.added')).toBeInTheDocument()
expect(
screen.getByText(
'dataset.newKnowledge.parentChildChunkCount:{"childCount":"1","parentCount":"1"}',
),
).toBeInTheDocument()
expect(screen.queryByText('dataset.newKnowledge.characterCount')).not.toBeInTheDocument()
expect(screen.queryByText('section')).not.toBeInTheDocument()
expect(screen.queryByText('sourcePage')).not.toBeInTheDocument()
const startLabeling = screen.getByRole('button', {
name: 'dataset.metadata.documentMetadata.startLabeling',
})
@ -642,7 +744,7 @@ describe('DocumentDetailPage', () => {
expect(tree).toHaveFocus()
})
it('supports mouse expansion and reports active re-index progress', async () => {
it('supports mouse expansion and reports the active re-index state', async () => {
const user = userEvent.setup()
chunksQuery.data = {
pages: [
@ -654,7 +756,22 @@ describe('DocumentDetailPage', () => {
},
],
}
tasksQuery.data = { pages: [{ items: [task({ progressPercent: 45 })] }] }
tasksQuery.data = {
pages: [
{
items: [
task({ progressPercent: 45 }),
task({
documentId: 'another-document',
documentRevision: 1,
id: 'another-task',
state: 'succeeded',
}),
backgroundTask({ id: 'bulk-reindex-task' }),
],
},
],
}
render(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
@ -664,11 +781,157 @@ describe('DocumentDetailPage', () => {
expect(parent).toHaveAttribute('aria-expanded', 'false')
expect(screen.queryByRole('treeitem', { name: /Child node/ })).toBeNull()
expect(screen.getByRole('status')).toHaveTextContent(
'dataset.newKnowledge.documentReindexProgress:{"progress":"45"}',
'dataset.newKnowledge.documentReindexStatus',
)
expect(
screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }),
).toHaveAttribute('data-disabled')
screen.getByRole('button', { name: 'dataset.newKnowledge.cancelDocumentReindex' }),
).not.toHaveAttribute('data-disabled')
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.viewTask' }))
const taskDrawer = screen.getByRole('dialog', {
name: 'dataset.newKnowledge.backgroundTasks',
})
expect(within(taskDrawer).getAllByText(/dataset\.newKnowledge\.processDocument/)).toHaveLength(
2,
)
expect(
within(taskDrawer).getByText('dataset.newKnowledge.overview.operation.document_reindex'),
).toBeInTheDocument()
})
it('cancels the active re-index task from the document header', async () => {
const user = userEvent.setup()
tasksQuery.data = { pages: [{ items: [task({ state: 'running' })] }] }
render(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
await user.click(
screen.getByRole('button', { name: 'dataset.newKnowledge.cancelDocumentReindex' }),
)
expect(cancelMutation.mutateAsync).toHaveBeenCalledWith({
params: {
control_space_id: 'space-1',
task_id: 'task-1',
task_kind: 'document',
},
})
await waitFor(() => expect(queryClient.invalidateQueries).toHaveBeenCalledTimes(4))
})
it('cancels a newly accepted re-index before task discovery catches up', async () => {
const user = userEvent.setup()
render(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }))
await user.click(
await screen.findByRole('button', {
name: 'dataset.newKnowledge.cancelDocumentReindex',
}),
)
expect(cancelMutation.mutateAsync).toHaveBeenCalledWith({
params: {
control_space_id: 'space-1',
task_id: 'compilation-job-1',
task_kind: 'document',
},
})
})
it('restores an accepted re-index after the document page remounts', async () => {
const user = userEvent.setup()
const rendered = render(
<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />,
)
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }))
expect(
await screen.findByRole('button', {
name: 'dataset.newKnowledge.cancelDocumentReindex',
}),
).toBeInTheDocument()
rendered.unmount()
render(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
expect(
screen.getByRole('button', { name: 'dataset.newKnowledge.cancelDocumentReindex' }),
).toBeInTheDocument()
expect(screen.getByRole('status')).toHaveTextContent(
'dataset.newKnowledge.documentReindexStatus',
)
})
it('reconciles a restored re-index through its exact compilation job', async () => {
globalThis.sessionStorage.setItem(
'dify-new-rag-reindex:space-1:document-1',
JSON.stringify({
baselineRevision: 3,
taskId: 'compilation-job-1',
}),
)
submittedJobQuery.data = {
id: 'compilation-job-1',
run_state: 'running',
stage: 'parsed',
updated_at: 1,
}
const rendered = render(
<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />,
)
expect(submittedJobOptions).toHaveBeenLastCalledWith(
expect.objectContaining({
input: {
params: {
control_space_id: 'space-1',
job_id: 'compilation-job-1',
},
},
}),
)
expect(
screen.getByRole('button', { name: 'dataset.newKnowledge.cancelDocumentReindex' }),
).toBeInTheDocument()
submittedJobQuery.data = {
id: 'compilation-job-1',
run_state: 'succeeded',
stage: 'published',
updated_at: 2,
}
rendered.rerender(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
await waitFor(() =>
expect(
screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }),
).toBeInTheDocument(),
)
await waitFor(() => expect(queryClient.invalidateQueries).toHaveBeenCalledTimes(4))
expect(globalThis.sessionStorage.getItem('dify-new-rag-reindex:space-1:document-1')).toBeNull()
})
it('clears a restored re-index when its authoritative job endpoint returns missing', async () => {
globalThis.sessionStorage.setItem(
'dify-new-rag-reindex:space-1:document-1',
JSON.stringify({
baselineRevision: 3,
taskId: 'missing-compilation-job',
}),
)
submittedJobQuery.error = { status: 404 }
tasksQuery.data = {
pages: [{ items: [task({ id: 'completed-task', state: 'succeeded' })] }],
}
render(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
await waitFor(() =>
expect(
screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }),
).toBeInTheDocument(),
)
expect(screen.queryByText('dataset.newKnowledge.documentReindexStatus')).not.toBeInTheDocument()
expect(globalThis.sessionStorage.getItem('dify-new-rag-reindex:space-1:document-1')).toBeNull()
})
it('renders missing revision and empty chunk states without issuing a usable chunk request', () => {
@ -1030,7 +1293,7 @@ describe('DocumentDetailPage', () => {
permissionState.keys = ['dataset.acl.readonly']
rendered.rerender(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
const readonlyReindexButton = screen.getByRole('button', {
name: 'dataset.newKnowledge.reindexDocument',
name: 'dataset.newKnowledge.cancelDocumentReindex',
})
expect(readonlyReindexButton).toHaveAttribute('data-disabled')
expect(readonlyReindexButton).toHaveAccessibleDescription(
@ -1167,11 +1430,16 @@ describe('DocumentDetailPage', () => {
expect(button).toHaveAttribute('aria-busy', 'true')
expect(reindexMutation.mutateAsync).toHaveBeenCalledOnce()
expect(screen.getByRole('status')).toHaveTextContent(
'dataset.newKnowledge.documentReindexStatus',
)
finishInvalidation?.()
await waitFor(() => expect(toastState.success).toHaveBeenCalled())
expect(button).toHaveAttribute('aria-busy', 'true')
await user.click(button)
expect(button).toHaveTextContent('dataset.newKnowledge.cancelDocumentReindex')
expect(button).not.toHaveAttribute('data-disabled')
expect(reindexMutation.mutateAsync).toHaveBeenCalledOnce()
expect(cancelMutation.mutateAsync).not.toHaveBeenCalled()
})
it('does not mistake an earlier failed revision for the newly submitted re-index', async () => {
@ -1184,9 +1452,10 @@ describe('DocumentDetailPage', () => {
await user.click(button)
await waitFor(() => expect(toastState.success).toHaveBeenCalled())
expect(button).toHaveAttribute('data-disabled')
await user.click(button)
expect(button).toHaveTextContent('dataset.newKnowledge.cancelDocumentReindex')
expect(button).not.toHaveAttribute('data-disabled')
expect(reindexMutation.mutateAsync).toHaveBeenCalledOnce()
expect(cancelMutation.mutateAsync).not.toHaveBeenCalled()
const discoveryOptions = documentTasksOptions.mock.lastCall?.[0] as unknown as {
refetchInterval: (query: {
@ -1232,17 +1501,11 @@ describe('DocumentDetailPage', () => {
).toBe(5000)
})
it('keeps submission protection while a delayed status recheck is unresolved', async () => {
it('keeps the accepted re-index state while task discovery is delayed', async () => {
vi.useFakeTimers()
tasksQuery.data = {
pages: [{ items: [task({ documentRevision: 4, id: 'old-failed', state: 'failed' })] }],
}
let finishTaskRefresh: (() => void) | undefined
tasksQuery.refetch.mockReturnValueOnce(
new Promise<void>((resolve) => {
finishTaskRefresh = resolve
}),
)
try {
render(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
const reindexButton = screen.getByRole('button', {
@ -1255,121 +1518,18 @@ describe('DocumentDetailPage', () => {
})
await act(() => vi.advanceTimersByTimeAsync(30000))
const alert = screen.getByRole('alert')
expect(alert).toHaveTextContent('dataset.newKnowledge.documentReindexConfirmationDelayed')
fireEvent.click(
within(alert).getByRole('button', {
name: 'dataset.newKnowledge.checkReindexStatus',
}),
expect(screen.getByRole('status')).toHaveTextContent(
'dataset.newKnowledge.documentReindexStatus',
)
expect(reindexButton).toHaveAttribute('data-disabled')
expect(reindexButton).toHaveTextContent('dataset.newKnowledge.cancelDocumentReindex')
expect(reindexButton).not.toHaveAttribute('data-disabled')
expect(reindexMutation.mutateAsync).toHaveBeenCalledOnce()
expect(tasksQuery.refetch).toHaveBeenCalledOnce()
await act(async () => {
finishTaskRefresh?.()
await Promise.resolve()
})
expect(reindexButton).toHaveAttribute('data-disabled')
expect(screen.getByRole('heading', { level: 1 })).toHaveFocus()
await act(async () => {
fireEvent.click(
within(alert).getByRole('button', {
name: 'dataset.newKnowledge.retryReindexDocument',
}),
)
await Promise.resolve()
await Promise.resolve()
})
expect(reindexMutation.mutateAsync).toHaveBeenCalledTimes(2)
expect(screen.getByRole('heading', { level: 1 })).toHaveFocus()
const discoveryOptions = documentTasksOptions.mock.lastCall?.[0] as unknown as {
refetchInterval: (query: {
state: {
data?: {
pages: Array<{
data: Array<ReturnType<typeof taskApiResponse>>
next_cursor: string | null
}>
}
}
}) => number | false
}
expect(
discoveryOptions.refetchInterval({
state: {
data: {
pages: [
{
data: [taskApiResponse(task({ documentRevision: 4, state: 'failed' }))],
next_cursor: null,
},
],
},
},
}),
).toBe(2000)
} finally {
vi.useRealTimers()
}
})
it('uses a late first task as the baseline while an explicit resubmit is pending', async () => {
vi.useFakeTimers()
tasksQuery.data = {
pages: [{ items: [task({ documentRevision: 4, id: 'old-failed', state: 'failed' })] }],
}
let finishSecondReindex: ((value: BulkDocumentReindexResult) => void) | undefined
try {
const rendered = render(
<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />,
)
await act(async () => {
fireEvent.click(
screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }),
)
await Promise.resolve()
await Promise.resolve()
})
await act(() => vi.advanceTimersByTimeAsync(30000))
reindexMutation.mutateAsync.mockImplementationOnce(
() =>
new Promise((resolve) => {
finishSecondReindex = resolve
}),
)
fireEvent.click(
screen.getByRole('button', { name: 'dataset.newKnowledge.retryReindexDocument' }),
)
tasksQuery.data = {
pages: [{ items: [task({ documentRevision: 5, id: 'late-first', state: 'running' })] }],
}
rendered.rerender(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
await act(async () => {
finishSecondReindex?.(queuedReindexResult())
await Promise.resolve()
await Promise.resolve()
})
tasksQuery.data = {
pages: [
{
items: [
task({
documentRevision: 5,
id: 'late-first',
state: 'succeeded',
}),
],
},
],
}
rendered.rerender(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
screen.queryByText('dataset.newKnowledge.documentReindexConfirmationDelayed'),
).not.toBeInTheDocument()
expect(
screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }),
).toHaveAttribute('data-disabled')
screen.queryByRole('button', { name: 'dataset.newKnowledge.retryReindexDocument' }),
).not.toBeInTheDocument()
} finally {
vi.useRealTimers()
}
@ -1456,8 +1616,8 @@ describe('DocumentDetailPage', () => {
rendered.rerender(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
expect(
screen.getByRole('button', { name: 'dataset.newKnowledge.reindexDocument' }),
).toHaveAttribute('data-disabled')
screen.getByRole('button', { name: 'dataset.newKnowledge.cancelDocumentReindex' }),
).not.toHaveAttribute('data-disabled')
await act(() => vi.advanceTimersByTimeAsync(30000))
expect(
screen.queryByRole('button', { name: 'dataset.newKnowledge.retryReindexDocument' }),
@ -1513,7 +1673,7 @@ describe('DocumentDetailPage', () => {
tasksQuery.data = { pages: [{ items: [task({ state: 'running' })] }] }
rendered.rerender(<DocumentDetailPage documentId="document-1" knowledgeSpaceId="space-1" />)
expect(screen.getByRole('status')).toHaveTextContent(
'dataset.newKnowledge.documentReindexProgress:{"progress":"45"}',
'dataset.newKnowledge.documentReindexStatus',
)
})

View File

@ -39,9 +39,11 @@ const task = (overrides: Partial<DocumentProcessingTask> = {}): DocumentProcessi
documentRevision: 3,
id: 'task-1',
knowledgeSpaceId: 'space-1',
operation: 'document_processing',
progressPercent: 10,
stage: 'queued',
state: 'queued',
taskKind: 'document',
updatedAt: '2026-07-20T10:00:00Z',
...overrides,
})

View File

@ -1,4 +1,4 @@
import type { DocumentProcessingTask, LogicalDocument } from '../document-models'
import type { BackgroundTask, DocumentProcessingTask, LogicalDocument } from '../document-models'
import type { Source } from '../source-models'
import { hashKey } from '@tanstack/react-query'
import { act, fireEvent, screen, waitFor, within } from '@testing-library/react'
@ -33,9 +33,7 @@ const documentsQuery = vi.hoisted(() => ({
}))
const tasksQuery = vi.hoisted(() => ({
data: undefined as
| { pages: Array<{ items: DocumentProcessingTask[]; nextCursor?: string }> }
| undefined,
data: undefined as { pages: Array<{ items: BackgroundTask[]; nextCursor?: string }> } | undefined,
dataUpdatedAt: 0,
dataUpdateCount: 0,
error: null as unknown,
@ -157,19 +155,20 @@ const documentApiResponse = vi.hoisted(() => (item: LogicalDocument) => ({
updated_at: item.updatedAt,
user_metadata: item.userMetadata,
}))
const taskApiResponse = vi.hoisted(() => (item: DocumentProcessingTask) => ({
const taskApiResponse = vi.hoisted(() => (item: BackgroundTask) => ({
can_cancel: item.canCancel ?? true,
can_retry: item.canRetry ?? item.state === 'failed',
completed_at: item.completedAt ?? null,
created_at: item.createdAt,
document_id: item.documentId,
document_revision: item.documentRevision,
document_id: item.documentId ?? null,
document_revision: item.documentRevision ?? null,
error_code: item.errorCode ?? null,
error_message: item.errorMessage ?? null,
id: item.id,
knowledge_space_id: item.knowledgeSpaceId,
operation: item.operation ?? 'document_processing',
progress_percent: item.progressPercent,
source_id: item.sourceId ?? null,
state:
item.state === 'succeeded'
? 'completed'
@ -314,7 +313,7 @@ vi.mock('@tanstack/react-query', async (importOriginal) => {
}
},
useMutation: (options: {
mutationFn?: (input: DocumentProcessingTask) => Promise<DocumentProcessingTask>
mutationFn?: (input: BackgroundTask) => Promise<BackgroundTask>
mutationKind?: 'bulk-upload' | 'cancel' | 'reindex' | 'retry' | 'upload'
}) => {
if (options.mutationFn)
@ -514,9 +513,24 @@ const task = (overrides: Partial<DocumentProcessingTask> = {}): DocumentProcessi
documentRevision: 2,
id: 'task-1',
knowledgeSpaceId: 'space-1',
operation: 'document_processing',
progressPercent: 45,
stage: 'parsed',
state: 'running',
taskKind: 'document',
updatedAt: '2026-07-20T10:01:00Z',
...overrides,
})
const backgroundTask = (overrides: Partial<BackgroundTask> = {}): BackgroundTask => ({
createdAt: '2026-07-20T10:00:00Z',
id: 'background-task-1',
knowledgeSpaceId: 'space-1',
operation: 'document_reindex',
progressPercent: 100,
stage: 'published',
state: 'succeeded',
taskKind: 'document_bulk',
updatedAt: '2026-07-20T10:01:00Z',
...overrides,
})
@ -2411,6 +2425,46 @@ describe('DocumentsPage', () => {
).toBeInTheDocument()
})
it('shows document, bulk re-index, and source tasks returned by the task list', async () => {
const user = userEvent.setup()
documentsQuery.data = { pages: [{ items: [document({})] }] }
tasksQuery.data = {
pages: [
{
items: [
task({ id: 'document-task', state: 'succeeded' }),
backgroundTask({ id: 'reindex-task' }),
backgroundTask({
errorMessage: 'Source sync failed',
id: 'source-task',
operation: 'source_sync',
sourceId: 'source-1',
state: 'failed',
taskKind: 'source',
}),
],
},
],
}
render(<DocumentsPage knowledgeSpaceId="space-1" />)
await user.click(
screen.getByRole('button', {
name: 'dataset.newKnowledge.tasksWithAttention:{"count":1}',
}),
)
const panel = screen.getByRole('dialog', { name: 'dataset.newKnowledge.backgroundTasks' })
expect(within(panel).getAllByRole('listitem')).toHaveLength(3)
expect(
within(panel).getByText('dataset.newKnowledge.overview.operation.document_reindex'),
).toBeInTheDocument()
expect(
within(panel).getByText('dataset.newKnowledge.overview.operation.source_sync'),
).toBeInTheDocument()
expect(within(panel).getByText('Source sync failed')).toBeInTheDocument()
})
it('gives duplicate task actions distinct accessible names', async () => {
const user = userEvent.setup()
documentsQuery.data = {

View File

@ -9,11 +9,7 @@ import copy from 'copy-to-clipboard'
import { useEffect, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { Markdown } from '@/app/components/base/markdown'
import {
chunkCharacterCount,
chunkContentParts,
chunkMetadataEntries,
} from './document-detail-model'
import { chunkCharacterCount, chunkContentParts } from './document-detail-model'
function formatBytes(bytes: number, locale: string) {
const numberFormat = new Intl.NumberFormat(locale, { maximumFractionDigits: 1 })
@ -40,6 +36,13 @@ function formatDate(value: string | undefined, locale: string) {
}).format(date)
}
function formatDateOnly(value: string | undefined, locale: string) {
if (!value) return '—'
const date = new Date(value)
if (Number.isNaN(date.getTime())) return value
return new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(date)
}
export function DocumentChunkDetail({
document,
chunks,
@ -59,15 +62,13 @@ export function DocumentChunkDetail({
}) {
const { t } = useTranslation('dataset')
const { t: tCommon } = useTranslation('common')
const selectedChunk = useMemo(
() => chunks.find((chunk) => chunk.id === selectedChunkId) ?? chunks[0],
[chunks, selectedChunkId],
)
const characterCount = useMemo(
() => chunks.reduce((total, chunk) => total + chunkCharacterCount(chunk.text), 0),
[chunks],
)
const averageChunkLength = chunks.length ? Math.round(characterCount / chunks.length) : 0
const childChunkCount = chunks.filter((chunk) => chunk.parentChunkId).length
const parentChunkCount = chunks.length - childChunkCount
const sizeBytes = revision?.sizeBytes ?? document.active?.sizeBytes
const sourceName =
typeof document.userMetadata.sourceName === 'string'
@ -149,136 +150,112 @@ export function DocumentChunkDetail({
)}
</article>
<aside className="min-w-0 xl:pl-6">
<section className="rounded-xl bg-background-default-subtle p-4">
<aside className="min-w-0 space-y-6 xl:pt-3 xl:pl-6">
<section className="flex flex-col items-start gap-2.5 rounded-xl bg-background-default-subtle p-4">
<h2 className="system-sm-semibold text-text-primary">
{t(($) => $['newKnowledge.metadata'])}
{t(($) => $['metadata.metadata'])}
</h2>
<p className="mt-2 system-xs-regular text-text-tertiary">
<p className="system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.documentOverviewDescription'])}
</p>
<Button
className="mt-2"
onClick={() => toast.info(t(($) => $['newKnowledge.filtersUnavailable']))}
variant="primary"
>
{t(($) => $['metadata.documentMetadata.startLabeling'])}
</Button>
</section>
<section className="mt-6">
<section>
<dl className="space-y-3">
<div>
<dt className="system-2xs-medium text-text-tertiary">
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.sourceColumn'])}
</dt>
<dd className="mt-1 system-xs-regular wrap-break-word text-text-secondary">
<dd className="min-w-0 flex-1 system-xs-regular wrap-break-word text-text-primary">
{sourceName ??
(document.sourceId
? t(($) => $['newKnowledge.sourceType.connector'])
: t(($) => $['newKnowledge.manualUpload']))}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.fileSize'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
<dd className="min-w-0 flex-1 system-xs-regular text-text-primary">
{sizeBytes !== undefined ? formatBytes(sizeBytes, locale) : '—'}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
{t(($) => $['newKnowledge.createdAt'])}
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{tCommon(($) => $['operation.added'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
{formatDate(document.createdAt, locale)}
<dd className="min-w-0 flex-1 system-xs-regular text-text-primary">
{formatDateOnly(document.createdAt, locale)}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.lastIndexed'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
<dd className="min-w-0 flex-1 system-xs-regular text-text-primary">
{formatDate(revision?.activatedAt ?? revision?.createdAt, locale)}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.documentRevision'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
<dd className="min-w-0 flex-1 system-xs-regular text-text-primary">
{revision?.revision ?? document.activeRevision ?? '—'}
</dd>
</div>
</dl>
</section>
<section className="mt-7">
<h2 className="system-sm-semibold text-text-primary">
<section>
<h2 className="system-xs-medium text-text-tertiary">
{t(($) => $['newKnowledge.indexInformation'])}
</h2>
<dl className="mt-3 space-y-3">
<div>
<dt className="system-2xs-medium text-text-tertiary">
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.chunkCount'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
{chunksComplete ? new Intl.NumberFormat(locale).format(chunks.length) : '—'}
<dd className="min-w-0 flex-1 system-xs-regular text-text-primary">
{chunksComplete
? childChunkCount
? t(($) => $['newKnowledge.parentChildChunkCount'], {
childCount: new Intl.NumberFormat(locale).format(childChunkCount),
parentCount: new Intl.NumberFormat(locale).format(parentChunkCount),
})
: new Intl.NumberFormat(locale).format(chunks.length)
: '—'}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.averageChunkLength'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
{chunksComplete ? new Intl.NumberFormat(locale).format(averageChunkLength) : '—'}
<dd className="min-w-0 flex-1 system-xs-regular text-text-primary">
{chunksComplete
? t(($) => $['newKnowledge.averageChunkLengthValue'], {
value: new Intl.NumberFormat(locale).format(averageChunkLength),
})
: '—'}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
<div className="flex gap-3">
<dt className="w-30 shrink-0 system-xs-regular text-text-tertiary">
{t(($) => $['newKnowledge.retrievalCount'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
<dd className="min-w-0 flex-1 system-xs-regular text-text-primary">
{retrievalCount === undefined
? '—'
: new Intl.NumberFormat(locale).format(retrievalCount)}
: t(($) => $['newKnowledge.retrievalCountValue'], {
value: new Intl.NumberFormat(locale).format(retrievalCount),
})}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
{t(($) => $['newKnowledge.mimeType'])}
</dt>
<dd className="mt-1 system-xs-regular wrap-break-word text-text-secondary">
{revision?.mimeType ?? document.active?.mimeType ?? '—'}
</dd>
</div>
{selectedChunk && (
<>
<div>
<dt className="system-2xs-medium text-text-tertiary">
{t(($) => $['newKnowledge.tokenCount'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
{new Intl.NumberFormat(locale).format(selectedChunk.tokenCount)}
</dd>
</div>
<div>
<dt className="system-2xs-medium text-text-tertiary">
{t(($) => $['newKnowledge.characterCount'])}
</dt>
<dd className="mt-1 system-xs-regular text-text-secondary">
{new Intl.NumberFormat(locale).format(chunkCharacterCount(selectedChunk.text))}
</dd>
</div>
{chunkMetadataEntries(selectedChunk.userMetadata).map(([key, value]) => (
<div key={key}>
<dt className="system-2xs-medium wrap-break-word text-text-tertiary">{key}</dt>
<dd className="mt-1 system-xs-regular wrap-break-word text-text-secondary">
{value}
</dd>
</div>
))}
</>
)}
</dl>
</section>
</aside>

View File

@ -16,35 +16,41 @@ import Link from '@/next/link'
export function DocumentDetailHeader({
backPath,
canCancelReindex,
cancelReindexBusy,
document,
effectiveRevision,
fetchNextRevisionPage,
hasNextRevisionPage,
isFetchNextRevisionPageError,
isFetchingNextRevisionPage,
onCancelReindex,
onReindex,
onRevisionChange,
reindexDisabled,
reindexDisabledReasonId,
reindexInProgress,
reindexing,
revisions,
taskIsActive,
titleRef,
}: {
backPath: string
canCancelReindex: boolean
cancelReindexBusy: boolean
document: LogicalDocument
effectiveRevision?: number
fetchNextRevisionPage: () => void
hasNextRevisionPage: boolean
isFetchNextRevisionPageError: boolean
isFetchingNextRevisionPage: boolean
onCancelReindex: () => void
onReindex: () => void
onRevisionChange: (revision: number) => void
reindexDisabled: boolean
reindexDisabledReasonId?: string
reindexInProgress: boolean
reindexing: boolean
revisions: Array<Exclude<LogicalDocumentRevision, null>>
taskIsActive: boolean
titleRef: RefObject<HTMLHeadingElement | null>
}) {
const { t } = useTranslation('dataset')
@ -124,15 +130,19 @@ export function DocumentDetailHeader({
</Button>
)}
<Button
aria-busy={reindexing || taskIsActive}
aria-busy={reindexing || cancelReindexBusy}
aria-describedby={reindexDisabledReasonId}
className="gap-1 pl-3"
disabled={reindexDisabled}
loading={reindexing}
onClick={onReindex}
disabled={reindexInProgress ? !canCancelReindex : reindexDisabled}
loading={reindexInProgress ? cancelReindexBusy : reindexing}
onClick={reindexInProgress ? onCancelReindex : onReindex}
>
<span aria-hidden className="i-ri-refresh-line size-4" />
{t(($) => $['newKnowledge.reindexDocument'])}
{!reindexInProgress && <span aria-hidden className="i-ri-refresh-line size-4" />}
{t(($) =>
reindexInProgress
? $['newKnowledge.cancelDocumentReindex']
: $['newKnowledge.reindexDocument'],
)}
</Button>
</div>
</div>

View File

@ -4,7 +4,7 @@ import { Button } from '@langgenius/dify-ui/button'
import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
import { useAtomValue } from 'jotai'
import { createParser, useQueryState } from 'nuqs'
import { useMemo, useRef } from 'react'
import { useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Loading from '@/app/components/base/loading'
import { datasetDefaultPermissionKeysAtom } from '@/context/permission-state'
@ -14,9 +14,15 @@ import { KnowledgeModelSetupDialog } from './components/knowledge-model-setup-di
import { DocumentDetailHeader } from './document-detail-header'
import { initialDocumentRevision, responseStatus } from './document-detail-model'
import { DocumentDetailStatus } from './document-detail-status'
import { documentRevisionListFromApi, logicalDocumentFromApi } from './document-models'
import {
documentRevisionListFromApi,
logicalDocumentFromApi,
logicalDocumentListFromApi,
} from './document-models'
import { DocumentRevisionContent } from './document-revision-content'
import { ProcessingTasksDrawer } from './processing-tasks-drawer'
import { newKnowledgeDocumentsPath } from './routes'
import { createTaskProgressStore } from './task-progress-store'
import { useDocumentReindex } from './use-document-reindex'
import { useKnowledgeModelSetupGuard } from './use-knowledge-model-setup-guard'
@ -64,7 +70,11 @@ export function DocumentDetailPage({
const { t: tCommon } = useTranslation('common')
const permissionKeys = useAtomValue(datasetDefaultPermissionKeysAtom)
const [selectedRevision, setSelectedRevision] = useQueryState('revision', documentRevisionParser)
const [tasksDrawerOpen, setTasksDrawerOpen] = useState(false)
const titleRef = useRef<HTMLHeadingElement>(null)
const taskProgressStoreRef = useRef<ReturnType<typeof createTaskProgressStore> | null>(null)
if (!taskProgressStoreRef.current) taskProgressStoreRef.current = createTaskProgressStore()
const taskProgressStore = taskProgressStoreRef.current
const {
configureModelSetup,
ensureModelSetupReady,
@ -92,6 +102,19 @@ export function DocumentDetailPage({
[documentId, knowledgeSpaceId],
)
const documentQuery = useQuery(documentQueryOptions)
const taskDocumentsQuery = useInfiniteQuery(
consoleQuery.knowledgeFs.spaces.byControlSpaceId.logicalDocuments.get.infiniteOptions({
enabled: tasksDrawerOpen,
input: (pageParam) => ({
params: { control_space_id: knowledgeSpaceId },
query: {
...(typeof pageParam === 'string' ? { cursor: pageParam } : {}),
},
}),
getNextPageParam: (lastPage) => lastPage.next_cursor,
initialPageParam: null as string | null,
}),
)
const revisionsQueryOptions = useMemo(
() =>
consoleQuery.knowledgeFs.spaces.byControlSpaceId.documents.byDocumentId.revisions.get.infiniteOptions(
@ -132,8 +155,14 @@ export function DocumentDetailPage({
documentQuery.data?.activeRevision ?? documentQuery.data?.active?.revision ?? 0
const documentErrorStatus = responseStatus(documentQuery.error)
const {
cancelReindex,
cancelReindexBusy,
continueLookup,
documentMissing,
fetchNextPage: fetchNextTaskPage,
hasNextPage: hasNextTaskPage,
isFetchNextPageError: isFetchNextTaskPageError,
isFetching: tasksFetching,
isFetchingNextPage: isFetchingNextTaskPage,
isLookingUp: isLookingUpTask,
isPending: tasksPending,
@ -142,15 +171,12 @@ export function DocumentDetailPage({
permissionRecoveryBusy,
permissionRecoveryNeeded,
refetch: refetchTasks,
recheckTimedOutSubmission,
reindex,
reindexBusy,
retryTimedOutSubmission,
retryWritePermission,
submissionPending,
submissionRecoveryBusy,
submissionTimedOut,
taskIsActive,
tasks,
tasksError,
writePermissionRevoked,
} = useDocumentReindex({
@ -166,6 +192,26 @@ export function DocumentDetailPage({
})
const hasEditPermission = hasPermission(permissionKeys, DatasetACLPermission.Edit)
const canEdit = hasEditPermission && !writePermissionRevoked
const reindexInProgress = submissionPending || taskIsActive
const canCancelReindex =
canEdit &&
reindexInProgress &&
(submissionPending || latestTask?.canCancel !== false) &&
!tasksError
const taskDocuments = useMemo(() => {
const documents =
taskDocumentsQuery.data?.pages.flatMap((page) => logicalDocumentListFromApi(page).items) ?? []
if (documentQuery.data && !documents.some((document) => document.id === documentQuery.data?.id))
return [documentQuery.data, ...documents]
return documents
}, [documentQuery.data, taskDocumentsQuery.data])
const taskDocumentIds = useMemo(
() => new Set(taskDocuments.map((document) => document.id)),
[taskDocuments],
)
const hasUnresolvedTaskDocuments = tasks.some(
(task) => task.documentId && !taskDocumentIds.has(task.documentId),
)
const activeRevision = availableRevisions.find(
(revision) => revision.revision === effectiveRevision,
)
@ -203,12 +249,15 @@ export function DocumentDetailPage({
<section className="flex min-h-0 flex-1 flex-col px-6 py-5 lg:px-8">
<DocumentDetailHeader
backPath={backPath}
canCancelReindex={canCancelReindex}
cancelReindexBusy={cancelReindexBusy}
document={document}
effectiveRevision={effectiveRevision}
fetchNextRevisionPage={() => void revisionsQuery.fetchNextPage()}
hasNextRevisionPage={revisionsQuery.hasNextPage}
isFetchNextRevisionPageError={revisionsQuery.isFetchNextPageError}
isFetchingNextRevisionPage={revisionsQuery.isFetchingNextPage}
onCancelReindex={() => void cancelReindex()}
onReindex={() => void reindex()}
onRevisionChange={(revision) => void setSelectedRevision(revision)}
reindexDisabled={
@ -224,9 +273,9 @@ export function DocumentDetailPage({
Boolean(tasksError)
}
reindexDisabledReasonId={!hasEditPermission ? REINDEX_RESTRICTION_ID : undefined}
reindexInProgress={reindexInProgress}
reindexing={reindexBusy || submissionPending}
revisions={availableRevisions}
taskIsActive={taskIsActive}
titleRef={titleRef}
/>
{!hasEditPermission && (
@ -240,23 +289,63 @@ export function DocumentDetailPage({
effectiveRevision={effectiveRevision}
isLookingUpTask={isLookingUpTask}
latestTask={latestTask}
locale={locale}
lookupExhausted={lookupExhausted}
permissionRecoveryBusy={permissionRecoveryBusy}
permissionRecoveryNeeded={permissionRecoveryNeeded}
recheckTimedOutSubmission={recheckTimedOutSubmission}
refetchRevisions={() => void revisionsQuery.refetch()}
refetchTasks={() => void refetchTasks()}
retryTimedOutSubmission={retryTimedOutSubmission}
retryWritePermission={retryWritePermission}
reindexInProgress={reindexInProgress}
revisionHistoryBackgroundError={Boolean(
revisionsQuery.error && !revisionsQuery.isFetchNextPageError,
)}
submissionRecoveryBusy={submissionRecoveryBusy}
submissionTimedOut={submissionTimedOut}
taskIsActive={taskIsActive}
tasksError={Boolean(tasksError)}
titleRef={titleRef}
onViewTasks={() => setTasksDrawerOpen(true)}
/>
<ProcessingTasksDrawer
actionResultsValid={!documentMissing}
canEdit={canEdit}
documentQueryError={Boolean(taskDocumentsQuery.error)}
documentQueryFetching={taskDocumentsQuery.isFetching}
documents={taskDocuments}
documentsPending={Boolean(taskDocumentsQuery.isPending || taskDocumentsQuery.hasNextPage)}
hasNextDocumentPage={Boolean(taskDocumentsQuery.hasNextPage)}
hasNextTaskPage={Boolean(hasNextTaskPage)}
hasUnresolvedTaskDocuments={hasUnresolvedTaskDocuments}
isFetchingNextDocumentPage={taskDocumentsQuery.isFetchingNextPage}
isFetchingNextTaskPage={isFetchingNextTaskPage}
knowledgeSpaceId={knowledgeSpaceId}
onLoadMoreDocuments={() => void taskDocumentsQuery.fetchNextPage()}
onLoadMoreTasks={() => void fetchNextTaskPage()}
onOpenChange={setTasksDrawerOpen}
onRefreshDocumentsAndTasks={() => {
void Promise.all([documentQuery.refetch(), taskDocumentsQuery.refetch(), refetchTasks()])
}}
onRetryDocumentQuery={() => {
if (taskDocumentsQuery.isFetchNextPageError) void taskDocumentsQuery.fetchNextPage()
else void taskDocumentsQuery.refetch()
}}
onRetryPermissionQuery={() => void retryWritePermission()}
onRetryTaskQuery={() => {
if (isFetchNextTaskPageError) void fetchNextTaskPage()
else void refetchTasks()
}}
onTaskUpdated={() => void refetchTasks()}
onWritePermissionDenied={() => void retryWritePermission()}
open={tasksDrawerOpen}
permissionQueryError={false}
permissionQueryFetching={permissionRecoveryBusy}
permissionQueryPending={false}
readOnlyReason={
canEdit ? undefined : t(($) => $['newKnowledge.documentPermissionRestricted'])
}
taskProgressStore={taskProgressStore}
taskQueryError={Boolean(tasksError)}
taskQueryFetching={tasksFetching}
taskQueryPending={tasksPending}
tasks={tasks}
/>
<DocumentRevisionContent

View File

@ -9,41 +9,33 @@ export function DocumentDetailStatus({
effectiveRevision,
isLookingUpTask,
latestTask,
locale,
lookupExhausted,
permissionRecoveryBusy,
permissionRecoveryNeeded,
recheckTimedOutSubmission,
refetchRevisions,
refetchTasks,
retryTimedOutSubmission,
retryWritePermission,
reindexInProgress,
revisionHistoryBackgroundError,
submissionRecoveryBusy,
submissionTimedOut,
taskIsActive,
tasksError,
titleRef,
onViewTasks,
}: {
continueLookup: () => void
effectiveRevision?: number
isLookingUpTask: boolean
latestTask?: DocumentProcessingTask
locale: string
lookupExhausted: boolean
permissionRecoveryBusy: boolean
permissionRecoveryNeeded: boolean
recheckTimedOutSubmission: () => Promise<unknown>
refetchRevisions: () => void
refetchTasks: () => void
retryTimedOutSubmission: () => Promise<unknown>
retryWritePermission: () => Promise<boolean>
reindexInProgress: boolean
revisionHistoryBackgroundError: boolean
submissionRecoveryBusy: boolean
submissionTimedOut: boolean
taskIsActive: boolean
tasksError: boolean
titleRef: RefObject<HTMLHeadingElement | null>
onViewTasks: () => void
}) {
const { t } = useTranslation('dataset')
const { t: tCommon } = useTranslation('common')
@ -58,7 +50,7 @@ export function DocumentDetailStatus({
return (
<>
{taskIsActive && (
{reindexInProgress && (
<div
className="mt-4 flex items-center gap-2 rounded-lg bg-state-accent-hover px-3 py-2 system-xs-regular text-text-accent"
role="status"
@ -67,9 +59,12 @@ export function DocumentDetailStatus({
aria-hidden
className="i-ri-loader-2-line size-4 animate-spin motion-reduce:animate-none"
/>
{t(($) => $['newKnowledge.documentReindexProgress'], {
progress: new Intl.NumberFormat(locale).format(latestTask?.progressPercent ?? 0),
})}
<span className="min-w-0 flex-1">
{t(($) => $['newKnowledge.documentReindexStatus'])}
</span>
<Button size="small" variant="ghost-accent" onClick={onViewTasks}>
{t(($) => $['newKnowledge.viewTask'])}
</Button>
</div>
)}
{latestTask?.state === 'failed' && (
@ -145,34 +140,6 @@ export function DocumentDetailStatus({
</div>
)}
{submissionTimedOut && (
<div
className="mt-4 flex flex-wrap items-center justify-between gap-2 rounded-lg bg-state-warning-hover px-3 py-2 system-xs-regular text-text-warning"
role="alert"
>
<span>{t(($) => $['newKnowledge.documentReindexConfirmationDelayed'])}</span>
<div className="flex flex-wrap gap-2">
<Button
disabled={submissionRecoveryBusy}
loading={submissionRecoveryBusy}
onClick={() =>
void recheckTimedOutSubmission().finally(() => titleRef.current?.focus())
}
>
{t(($) => $['newKnowledge.checkReindexStatus'])}
</Button>
<Button
disabled={submissionRecoveryBusy}
onClick={() =>
void retryTimedOutSubmission().finally(() => titleRef.current?.focus())
}
>
{t(($) => $['newKnowledge.retryReindexDocument'])}
</Button>
</div>
</div>
)}
{revisionHistoryBackgroundError && effectiveRevision !== undefined && (
<div
className="mt-4 flex flex-wrap items-center justify-between gap-2 rounded-lg bg-state-warning-hover px-3 py-2 system-xs-regular text-text-warning"

View File

@ -1,4 +1,4 @@
import type { DocumentProcessingTask, LogicalDocument } from './document-models'
import type { BackgroundTask, DocumentProcessingTask, LogicalDocument } from './document-models'
export type DocumentDisplayStatus = 'ready' | 'queued' | 'processing' | 'failed' | 'disabled'
@ -88,14 +88,14 @@ export function documentDisplayStatus(
return 'ready'
}
export function taskNeedsAttention(task: DocumentProcessingTask) {
export function taskNeedsAttention(task: BackgroundTask) {
return ATTENTION_TASK_STATES.has(task.state)
}
export function taskIsActive(task: DocumentProcessingTask) {
export function taskIsActive(task: BackgroundTask) {
return ACTIVE_TASK_STATES.has(task.state)
}
export function taskCanRetry(task: DocumentProcessingTask) {
export function taskCanRetry(task: BackgroundTask) {
return task.state === 'failed'
}

View File

@ -67,18 +67,18 @@ type DocumentChunkList = {
nextCursor?: string
}
export type DocumentProcessingTask = {
export type BackgroundTask = {
canCancel?: boolean
canRetry?: boolean
completedAt?: string
createdAt: string
documentId: string
documentRevision: number
documentId?: string
documentRevision?: number
errorCode?: string
errorMessage?: string
id: string
knowledgeSpaceId: string
operation?: KnowledgeFsBackgroundTaskResponse['operation']
operation: KnowledgeFsBackgroundTaskResponse['operation']
progressPercent: number
retryAt?: string
stage:
@ -98,10 +98,16 @@ export type DocumentProcessingTask = {
| 'failed'
| 'canceled'
| 'superseded'
taskKind?: KnowledgeFsBackgroundTaskResponse['task_kind']
sourceId?: string
taskKind: KnowledgeFsBackgroundTaskResponse['task_kind']
updatedAt: string
}
export type DocumentProcessingTask = BackgroundTask & {
documentId: string
documentRevision: number
}
type DocumentProcessingTaskList = {
items: DocumentProcessingTask[]
nextCursor?: string
@ -207,7 +213,7 @@ export function documentChunkListFromApi(
}
}
function taskStage(task: KnowledgeFsBackgroundTaskResponse): DocumentProcessingTask['stage'] {
function taskStage(task: KnowledgeFsBackgroundTaskResponse): BackgroundTask['stage'] {
if (task.state === 'completed') return 'published'
if (task.progress_percent >= 90) return 'smoke_eval_passed'
if (task.progress_percent >= 75) return 'projection_built'
@ -216,17 +222,14 @@ function taskStage(task: KnowledgeFsBackgroundTaskResponse): DocumentProcessingT
return 'queued'
}
export function documentTaskFromApi(
task: KnowledgeFsBackgroundTaskResponse,
): DocumentProcessingTask | undefined {
if (!task.document_id) return undefined
export function backgroundTaskFromApi(task: KnowledgeFsBackgroundTaskResponse): BackgroundTask {
return {
canCancel: task.can_cancel,
canRetry: task.can_retry,
completedAt: task.completed_at ?? undefined,
createdAt: task.created_at,
documentId: task.document_id,
documentRevision: task.document_revision ?? 1,
documentId: task.document_id ?? undefined,
documentRevision: task.document_revision ?? undefined,
errorCode: task.error_code ?? undefined,
errorMessage: task.error_message ?? undefined,
id: task.id,
@ -240,11 +243,33 @@ export function documentTaskFromApi(
: task.state === 'canceled'
? 'canceled'
: task.state,
sourceId: task.source_id ?? undefined,
taskKind: task.task_kind,
updatedAt: task.updated_at,
}
}
export function documentTaskFromApi(
task: KnowledgeFsBackgroundTaskResponse,
): DocumentProcessingTask | undefined {
if (!task.document_id) return undefined
return {
...backgroundTaskFromApi(task),
documentId: task.document_id,
documentRevision: task.document_revision ?? 1,
}
}
export function backgroundTaskListFromApi(response: KnowledgeFsBackgroundTaskListResponse): {
items: BackgroundTask[]
nextCursor?: string
} {
return {
items: response.data.map(backgroundTaskFromApi),
nextCursor: response.next_cursor ?? undefined,
}
}
export function documentTaskListFromApi(
response: KnowledgeFsBackgroundTaskListResponse,
): DocumentProcessingTaskList {

View File

@ -46,6 +46,7 @@ import {
taskVersionIsAfter,
} from './document-model'
import {
backgroundTaskListFromApi,
documentTaskFromApi,
documentTaskListFromApi,
logicalDocumentListFromApi,
@ -436,6 +437,10 @@ export function DocumentsPage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
() => tasksQuery.data?.pages.flatMap((page) => documentTaskListFromApi(page).items) ?? [],
[tasksQuery.data],
)
const backgroundTasks = useMemo(
() => tasksQuery.data?.pages.flatMap((page) => backgroundTaskListFromApi(page).items) ?? [],
[tasksQuery.data],
)
const documentIds = useMemo(() => new Set(documents.map((document) => document.id)), [documents])
const unresolvedTaskDocumentIds = useMemo(
() =>
@ -534,6 +539,10 @@ export function DocumentsPage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
[baseTasks, taskOverrides, terminalTaskPins],
)
const effectiveTaskById = useMemo(() => new Map(tasks.map((task) => [task.id, task])), [tasks])
const drawerTasks = useMemo(
() => backgroundTasks.map((task) => effectiveTaskById.get(task.id) ?? task),
[backgroundTasks, effectiveTaskById],
)
useEffect(() => {
for (const task of tasks) {
if (!taskIsActive(task)) {
@ -740,7 +749,7 @@ export function DocumentsPage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
const selectableFilteredDocuments = filteredDocuments.filter(
(document) => documentStatuses.get(document.id) !== 'disabled',
)
const attentionTasks = tasks.filter(taskNeedsAttention)
const attentionTasks = drawerTasks.filter(taskNeedsAttention)
const hasTaskError = attentionTasks.some(
(task) => task.state === 'failed' || task.state === 'canceled',
)
@ -2543,7 +2552,7 @@ export function DocumentsPage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
taskQueryError={Boolean(tasksQuery.error || tasksQuery.isFetchNextPageError)}
taskQueryFetching={tasksQuery.isFetching}
taskProgressStore={taskProgressStore}
tasks={tasks}
tasks={drawerTasks}
/>
<KnowledgeModelSetupDialog
open={modelSetupDialogOpen}

View File

@ -1,6 +1,6 @@
'use client'
import type { DocumentProcessingTask, LogicalDocument } from './document-models'
import type { BackgroundTask, DocumentProcessingTask, LogicalDocument } from './document-models'
import type { TaskProgressStore } from './task-progress-store'
import { Button } from '@langgenius/dify-ui/button'
import {
@ -21,18 +21,18 @@ import Loading from '@/app/components/base/loading'
import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now'
import { consoleClient } from '@/service/client'
import { taskCanRetry, taskIsActive, taskVersionIsAfter } from './document-model'
import { documentTaskFromApi } from './document-models'
import { backgroundTaskFromApi } from './document-models'
type TaskAction = 'cancel' | 'retry'
const TASK_DRAWER_LIMIT = 100
const noopSubscribe = () => () => undefined
function taskTime(task: DocumentProcessingTask) {
function taskTime(task: BackgroundTask) {
return task.completedAt ?? task.updatedAt
}
function taskLifecycle(task: DocumentProcessingTask) {
function taskLifecycle(task: BackgroundTask) {
return `${task.updatedAt}:${task.state}`
}
@ -47,18 +47,18 @@ function responseStatus(error: unknown): number | undefined {
}
}
function compareTaskRecency(left: DocumentProcessingTask, right: DocumentProcessingTask) {
function compareTaskRecency(left: BackgroundTask, right: BackgroundTask) {
if (taskVersionIsAfter(left.updatedAt, right.updatedAt)) return -1
if (taskVersionIsAfter(right.updatedAt, left.updatedAt)) return 1
return right.id.localeCompare(left.id)
}
function newestTasks(
tasks: DocumentProcessingTask[],
tasks: BackgroundTask[],
limit: number,
predicate: (task: DocumentProcessingTask) => boolean,
predicate: (task: BackgroundTask) => boolean,
) {
const selected: DocumentProcessingTask[] = []
const selected: BackgroundTask[] = []
for (const task of tasks) {
if (!predicate(task)) continue
let low = 0
@ -134,7 +134,7 @@ export function ProcessingTasksDrawer({
taskQueryError: boolean
taskQueryFetching: boolean
taskQueryPending: boolean
tasks: DocumentProcessingTask[]
tasks: BackgroundTask[]
taskProgressStore: TaskProgressStore
onRetryDocumentQuery: () => void
onRetryTaskQuery: () => void
@ -143,38 +143,32 @@ export function ProcessingTasksDrawer({
const { t: tCommon } = useTranslation('common')
const { formatTimeFromNow } = useFormatTimeFromNow()
const cancelTask = useMutation({
mutationFn: async (task: DocumentProcessingTask) => {
const updated = documentTaskFromApi(
mutationFn: async (task: BackgroundTask) =>
backgroundTaskFromApi(
await consoleClient.knowledgeFs.spaces.byControlSpaceId.backgroundTasks.byTaskKind.byTaskId.cancel.post(
{
params: {
control_space_id: knowledgeSpaceId,
task_id: task.id,
task_kind: task.taskKind ?? 'document',
task_kind: task.taskKind,
},
},
),
)
if (!updated) throw new Error('KnowledgeFS returned a non-document task')
return updated
},
),
})
const retryTask = useMutation({
mutationFn: async (task: DocumentProcessingTask) => {
const updated = documentTaskFromApi(
mutationFn: async (task: BackgroundTask) =>
backgroundTaskFromApi(
await consoleClient.knowledgeFs.spaces.byControlSpaceId.backgroundTasks.byTaskKind.byTaskId.retry.post(
{
params: {
control_space_id: knowledgeSpaceId,
task_id: task.id,
task_kind: task.taskKind ?? 'document',
task_kind: task.taskKind,
},
},
),
)
if (!updated) throw new Error('KnowledgeFS returned a non-document task')
return updated
},
),
})
const pendingActionsRef = useRef(new Set<string>())
const drawerCloseButtonRef = useRef<HTMLButtonElement>(null)
@ -335,7 +329,7 @@ export function ProcessingTasksDrawer({
drawerCloseButtonRef.current?.focus()
}, [open, orderedTasks])
const performAction = async (task: DocumentProcessingTask, action: TaskAction) => {
const performAction = async (task: BackgroundTask, action: TaskAction) => {
if (!canEdit || pendingActionsRef.current.has(task.id)) return
pendingActionsRef.current.add(task.id)
const actionOpenCycle = openCycleRef.current
@ -355,7 +349,8 @@ export function ProcessingTasksDrawer({
taskLifecycleGenerationsRef.current.get(task.id)?.generation !== actionLifecycleGeneration
)
return
onTaskUpdated(updated)
if (updated.documentId && updated.documentRevision)
onTaskUpdated(updated as DocumentProcessingTask)
setActionErrors((current) => {
const next = { ...current }
delete next[task.id]
@ -516,16 +511,17 @@ export function ProcessingTasksDrawer({
) : orderedTasks.length ? (
<ul>
{orderedTasks.map((task) => {
const title =
documentTitles.get(task.documentId) ??
(documentsPending
? t(($) => $['newKnowledge.documentColumn'])
: task.documentId)
const title = task.documentId
? (documentTitles.get(task.documentId) ??
(documentsPending
? t(($) => $['newKnowledge.documentColumn'])
: task.documentId))
: t(($) => $[`newKnowledge.overview.operation.${task.operation}`])
const timestamp = Date.parse(
taskIsActive(task) ? task.createdAt : taskTime(task),
)
const taskError = task.errorMessage ?? task.errorCode
const actionTarget = `${documentTitles.get(task.documentId) ?? task.documentId} · ${task.id}`
const actionTarget = `${title} · ${task.id}`
return (
<li key={task.id} className="flex min-h-15.5 items-center gap-2.5 py-3.5">
<span
@ -542,7 +538,9 @@ export function ProcessingTasksDrawer({
/>
<div className="min-w-0 flex-1">
<p className="truncate system-sm-medium text-text-primary">
{t(($) => $['newKnowledge.processDocument'], { name: title })}
{task.documentId
? t(($) => $['newKnowledge.processDocument'], { name: title })
: title}
</p>
<p className="mt-0.75 truncate system-xs-regular text-text-tertiary">
{t(($) => $[`newKnowledge.processingTaskState.${task.state}`], {

View File

@ -1,7 +1,8 @@
'use client'
import { toast } from '@langgenius/dify-ui/toast'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { skipToken } from '@tanstack/query-core'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useSetAtom } from 'jotai'
import { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -9,9 +10,50 @@ import { refreshWorkspacePermissionKeysAfterMutationDenialAtom } from '@/context
import { consoleQuery } from '@/service/client'
import { DatasetACLPermission, hasPermission } from '@/utils/permission'
import { responseStatus } from './document-detail-model'
import { useDocumentTaskStatus } from './use-document-task-status'
import { documentTaskIsActive, useDocumentTaskStatus } from './use-document-task-status'
const REINDEX_CONFIRMATION_TIMEOUT = 30000
const REINDEX_STORAGE_PREFIX = 'dify-new-rag-reindex'
type SubmittedReindex = {
baselineRevision: number
taskId: string
}
function compilationJobIsTerminal(job: { run_state?: string | null; stage?: string | null }) {
return (
job.run_state === 'succeeded' ||
job.run_state === 'completed' ||
job.run_state === 'failed' ||
job.run_state === 'canceled' ||
job.run_state === 'superseded' ||
job.stage === 'published' ||
job.stage === 'failed' ||
job.stage === 'canceled'
)
}
function submittedReindexStorageKey(knowledgeSpaceId: string, documentId: string) {
return `${REINDEX_STORAGE_PREFIX}:${knowledgeSpaceId}:${documentId}`
}
function readSubmittedReindex(storageKey: string): SubmittedReindex | undefined {
try {
const value = JSON.parse(globalThis.sessionStorage.getItem(storageKey) ?? 'null')
if (
!value ||
typeof value !== 'object' ||
typeof value.baselineRevision !== 'number' ||
typeof value.taskId !== 'string'
)
return
return {
baselineRevision: value.baselineRevision,
taskId: value.taskId,
}
} catch {
// Ignore unavailable or invalid recovery data.
}
}
export function useDocumentReindex({
beforeReindex,
@ -34,20 +76,19 @@ export function useDocumentReindex({
}) {
const { t } = useTranslation('dataset')
const queryClient = useQueryClient()
const storageKey = submittedReindexStorageKey(knowledgeSpaceId, documentId)
const refreshWorkspacePermissionKeysAfterMutationDenial = useSetAtom(
refreshWorkspacePermissionKeysAfterMutationDenialAtom,
)
const [writePermissionRevoked, setWritePermissionRevoked] = useState(false)
const [documentMissing, setDocumentMissing] = useState(false)
const [cancelReindexBusy, setCancelReindexBusy] = useState(false)
const [permissionRecoveryBusy, setPermissionRecoveryBusy] = useState(false)
const [permissionRecoveryNeeded, setPermissionRecoveryNeeded] = useState(false)
const [reindexBusy, setReindexBusy] = useState(false)
const [submissionRecoveryBusy, setSubmissionRecoveryBusy] = useState(false)
const [submittedReindex, setSubmittedReindex] = useState<{
baselineRevision: number
taskId: string
timedOut: boolean
}>()
const [submittedReindex, setSubmittedReindex] = useState<SubmittedReindex | undefined>(() =>
readSubmittedReindex(storageKey),
)
const permissionRecoveryPendingRef = useRef(false)
const reindexPendingRef = useRef(false)
const previousTaskStateRef = useRef<string | undefined>(undefined)
@ -56,6 +97,24 @@ export function useDocumentReindex({
const { mutateAsync: reindexDocument } = useMutation(
consoleQuery.knowledgeFs.spaces.byControlSpaceId.documents.reindex.post.mutationOptions(),
)
const { mutateAsync: cancelTask } = useMutation(
consoleQuery.knowledgeFs.spaces.byControlSpaceId.backgroundTasks.byTaskKind.byTaskId.cancel.post.mutationOptions(),
)
const submittedJobQuery = useQuery(
consoleQuery.knowledgeFs.spaces.byControlSpaceId.jobs.byJobId.get.queryOptions({
input: submittedReindex
? {
params: {
control_space_id: knowledgeSpaceId,
job_id: submittedReindex.taskId,
},
}
: skipToken,
refetchInterval: (query) =>
query.state.data && !compilationJobIsTerminal(query.state.data) ? 2000 : false,
retry: (failureCount, error) => responseStatus(error) !== 403 && failureCount < 2,
}),
)
const taskStatus = useDocumentTaskStatus({
acceptedTaskId: submittedReindex?.taskId,
documentId,
@ -65,7 +124,7 @@ export function useDocumentReindex({
? submittedReindex.baselineRevision + 1
: documentActiveRevision,
submissionNeedsRecheck: Boolean(submittedReindex),
submissionPending: Boolean(submittedReindex && !submittedReindex.timedOut),
submissionPending: Boolean(submittedReindex),
})
const { latestTask, taskIsActive } = taskStatus
const latestTaskRef = useRef(latestTask)
@ -73,7 +132,13 @@ export function useDocumentReindex({
const submittedTaskObserved = Boolean(
latestTask && submittedReindex && latestTask.id === submittedReindex.taskId,
)
const submissionPending = Boolean(submittedReindex && !submittedTaskObserved)
const submittedJobIsTerminal = Boolean(
submittedJobQuery.data && compilationJobIsTerminal(submittedJobQuery.data),
)
const submittedJobMissing = responseStatus(submittedJobQuery.error) === 404
const submissionPending = Boolean(
submittedReindex && !submittedTaskObserved && !submittedJobIsTerminal && !submittedJobMissing,
)
const retryWritePermission = async () => {
if (permissionRecoveryPendingRef.current) return false
@ -103,19 +168,19 @@ export function useDocumentReindex({
}
useEffect(() => {
if (!submittedReindex || submittedReindex.timedOut || submittedTaskObserved) return
const timeout = window.setTimeout(
() =>
setSubmittedReindex((current) =>
current?.baselineRevision === submittedReindex.baselineRevision &&
current.taskId === submittedReindex.taskId
? { ...current, timedOut: true }
: current,
),
REINDEX_CONFIRMATION_TIMEOUT,
)
return () => window.clearTimeout(timeout)
}, [submittedReindex, submittedTaskObserved])
try {
const submittedTaskIsTerminal = Boolean(
submittedReindex &&
latestTask?.id === submittedReindex.taskId &&
!documentTaskIsActive(latestTask.state),
)
if (submittedReindex && !submittedTaskIsTerminal)
globalThis.sessionStorage.setItem(storageKey, JSON.stringify(submittedReindex))
else globalThis.sessionStorage.removeItem(storageKey)
} catch {
// Re-index recovery remains available for the current page when browser storage is unavailable.
}
}, [latestTask, storageKey, submittedReindex])
useEffect(() => {
const previousState = previousTaskStateRef.current
@ -165,6 +230,35 @@ export function useDocumentReindex({
taskStatus.queryKey,
])
useEffect(() => {
if (!submittedReindex || (!submittedJobIsTerminal && !submittedJobMissing)) return
if (submittedJobIsTerminal) {
void Promise.all([
queryClient.invalidateQueries({
queryKey: documentQueryKey,
}),
queryClient.invalidateQueries({
queryKey: revisionsQueryKey,
}),
queryClient.invalidateQueries({
queryKey: chunksQueryKey,
}),
queryClient.invalidateQueries({ queryKey: taskStatus.queryKey }),
])
}
// oxlint-disable-next-line eslint-react/set-state-in-effect -- Reconcile the persisted submission with its authoritative job endpoint.
setSubmittedReindex(undefined)
}, [
chunksQueryKey,
documentQueryKey,
queryClient,
revisionsQueryKey,
submittedJobIsTerminal,
submittedJobMissing,
submittedReindex,
taskStatus.queryKey,
])
const reindex = async (baselineRevision = documentActiveRevision) => {
if (reindexPendingRef.current) return
reindexPendingRef.current = true
@ -196,7 +290,6 @@ export function useDocumentReindex({
latestTaskRef.current?.documentRevision ?? documentActiveRevision,
),
taskId,
timedOut: false,
})
await Promise.all([
queryClient.invalidateQueries({
@ -225,30 +318,52 @@ export function useDocumentReindex({
return {
...taskStatus,
cancelReindex: async () => {
const task = latestTaskRef.current
const taskId = submittedReindex?.taskId ?? task?.id
const submittedTaskIsPending = Boolean(submittedReindex)
if (
!taskId ||
(!submittedTaskIsPending &&
(!task || !documentTaskIsActive(task.state) || task.canCancel === false))
)
return false
setCancelReindexBusy(true)
try {
await cancelTask({
params: {
control_space_id: knowledgeSpaceId,
task_id: taskId,
task_kind: task?.id === taskId ? (task.taskKind ?? 'document') : 'document',
},
})
setSubmittedReindex(undefined)
await Promise.all([
queryClient.invalidateQueries({ queryKey: documentQueryKey }),
queryClient.invalidateQueries({ queryKey: revisionsQueryKey }),
queryClient.invalidateQueries({ queryKey: chunksQueryKey }),
queryClient.invalidateQueries({ queryKey: taskStatus.queryKey }),
])
return true
} catch (error) {
if (responseStatus(error) === 403) {
setWritePermissionRevoked(true)
await retryWritePermission()
}
toast.error(t(($) => $['newKnowledge.taskActionFailed']))
return false
} finally {
setCancelReindexBusy(false)
}
},
cancelReindexBusy,
documentMissing,
permissionRecoveryBusy,
permissionRecoveryNeeded,
reindex,
reindexBusy,
recheckTimedOutSubmission: async () => {
if (submissionRecoveryBusy) return
setSubmissionRecoveryBusy(true)
try {
await taskStatus.refetch()
} finally {
setSubmissionRecoveryBusy(false)
}
},
retryTimedOutSubmission: async () => {
if (submissionRecoveryBusy) return
const baselineRevision = submittedReindex?.baselineRevision ?? documentActiveRevision
setSubmittedReindex(undefined)
await reindex(baselineRevision)
},
retryWritePermission,
submissionRecoveryBusy,
submissionPending,
submissionTimedOut: Boolean(submittedReindex?.timedOut && !submittedTaskObserved),
writePermissionRevoked,
}
}

View File

@ -4,14 +4,14 @@ import { useInfiniteQuery } from '@tanstack/react-query'
import { useEffect, useMemo, useState } from 'react'
import { consoleQuery } from '@/service/client'
import { newestTaskByDocument } from './document-model'
import { documentTaskListFromApi } from './document-models'
import { backgroundTaskListFromApi, documentTaskListFromApi } from './document-models'
const TASK_PAGE_SIZE = 100
const TASK_LOOKUP_PAGE_BATCH = 3
const ACTIVE_TASK_REFRESH_INTERVAL = 5000
const SUBMISSION_DISCOVERY_REFRESH_INTERVAL = 2000
function documentTaskIsActive(state: string | undefined) {
export function documentTaskIsActive(state: string | undefined) {
return (
state === 'dispatch_pending' ||
state === 'queued' ||
@ -71,33 +71,41 @@ export function useDocumentTaskStatus({
error: tasksError,
fetchNextPage,
hasNextPage,
isFetching,
isFetchNextPageError,
isFetchingNextPage,
isPending,
refetch,
} = tasksQuery
const tasks = useMemo(
() => tasksData?.pages.flatMap((page) => backgroundTaskListFromApi(page).items) ?? [],
[tasksData],
)
const documentTasks = useMemo(
() => tasksData?.pages.flatMap((page) => documentTaskListFromApi(page).items) ?? [],
[tasksData],
)
const acceptedTask = useMemo(
() => (acceptedTaskId ? tasks.find((candidate) => candidate.id === acceptedTaskId) : undefined),
[acceptedTaskId, tasks],
() =>
acceptedTaskId
? documentTasks.find((candidate) => candidate.id === acceptedTaskId)
: undefined,
[acceptedTaskId, documentTasks],
)
const latestTask = useMemo(() => {
if (acceptedTask) return acceptedTask
const task = newestTaskByDocument(
tasks.filter(
documentTasks.filter(
(candidate) =>
candidate.documentId === documentId && candidate.documentRevision >= minimumRevision,
),
).get(documentId)
return task && task.documentRevision >= minimumRevision ? task : undefined
}, [acceptedTask, documentId, minimumRevision, tasks])
}, [acceptedTask, documentId, documentTasks, minimumRevision])
const lookupSatisfied = acceptedTaskId ? Boolean(acceptedTask) : Boolean(latestTask)
const lookupExhausted = Boolean(
!lookupSatisfied && hasNextPage && (tasksData?.pages.length ?? 0) >= lookupPageLimit,
)
useEffect(() => {
if (
isPending ||
@ -123,6 +131,10 @@ export function useDocumentTaskStatus({
return {
continueLookup: () => setLookupPageLimit((current) => current + TASK_LOOKUP_PAGE_BATCH),
fetchNextPage,
hasNextPage,
isFetchNextPageError,
isFetching,
isFetchingNextPage,
isLookingUp: Boolean(!lookupSatisfied && hasNextPage && !lookupExhausted),
isPending,
@ -131,6 +143,7 @@ export function useDocumentTaskStatus({
queryKey: tasksQueryOptions.queryKey,
refetch,
taskIsActive: documentTaskIsActive(latestTask?.state),
tasks,
tasksError,
}
}

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "نقطة النهاية",
"newKnowledge.authenticationMethod": "طريقة المصادقة",
"newKnowledge.averageChunkLength": "متوسط طول المقطع",
"newKnowledge.averageChunkLengthValue": "{{value}} حرفًا",
"newKnowledge.backToList": "العودة إلى قواعد المعرفة",
"newKnowledge.backgroundTasks": "مهام الخلفية",
"newKnowledge.backgroundTasksDescription": "يضيف المستند، ويتزامن المصدر، ويعيد فهرسة المهام.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "نعم",
"newKnowledge.bulkDocumentActions": "إجراءات المستندات المجمعة",
"newKnowledge.cancelAddSource": "إلغاء",
"newKnowledge.cancelDocumentReindex": "إلغاء إعادة الفهرسة",
"newKnowledge.cardType": "مساحة معرفة",
"newKnowledge.characterCount": "الأحرف",
"newKnowledge.checkReindexStatus": "تحقق من حالة إعادة الفهرسة",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "تم قبول إعادة الفهرسة، لكن حالة المهمة متأخرة. تحقق منها قبل الإرسال مرة أخرى.",
"newKnowledge.documentReindexFailed": "فشلت إعادة الفهرسة. تظل آخر مراجعة جاهزة متاحة.",
"newKnowledge.documentReindexProgress": "جارٍ إعادة الفهرسة · {{progress}}٪",
"newKnowledge.documentReindexStatus": "جارٍ إعادة فهرسة هذا المستند — سيستمر الفهرس الحالي في العمل حتى يصبح الفهرس الجديد جاهزًا.",
"newKnowledge.documentRevision": "المراجعة",
"newKnowledge.documentRevisionMissingDescription": "لا توجد مراجعة جاهزة لهذا المستند بعد. تحقق مجددًا بعد اكتمال المعالجة.",
"newKnowledge.documentRevisionMissingTitle": "لا توجد مراجعة متاحة",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "تعرّف على قاعدة المعرفة الجديدة ✨",
"newKnowledge.illustrationHeadline": "اربط محتواك مرة واحدة — ليجيب كل تطبيق بأحدث معرفة.",
"newKnowledge.includeSubpages": "تضمين الصفحات الفرعية",
"newKnowledge.indexInformation": "معلومات الفهرسة",
"newKnowledge.indexInformation": "الفهرسة",
"newKnowledge.interruptTask": "إيقاف",
"newKnowledge.invalidRootUrl": "أدخل عنوان URL صالحًا يبدأ بـ http(s).",
"newKnowledge.keepEditing": "متابعة التحرير",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "تم الزحف إلى {{count}} صفحة في {{host}}",
"newKnowledge.pagesCrawled_other": "تم الزحف إلى {{count}} صفحة في {{host}}",
"newKnowledge.pagesSelected": "تم تحديد {{count}}",
"newKnowledge.parentChildChunkCount": "{{parentCount}} أصلية / {{childCount}} فرعية",
"newKnowledge.partialDocumentResults": "قد تتطابق مستندات أخرى. حمّل المزيد لمواصلة البحث.",
"newKnowledge.permission": "إذن",
"newKnowledge.permissionAllMembers": "مساحة العمل · يمكن لجميع الأعضاء العرض والتحرير",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "إعادة الفهرسة",
"newKnowledge.removeSource": "قم بإزالة المصدر",
"newKnowledge.retrievalCount": "عدد مرات الاسترجاع",
"newKnowledge.retrievalCountValue": "{{value}} خلال آخر 7 أيام",
"newKnowledge.retrievalTest.analyzing": "تحليل الأدلة",
"newKnowledge.retrievalTest.cancel": "إلغاء",
"newKnowledge.retrievalTest.canceled": "تم الإلغاء",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "جارٍ الرفع…",
"newKnowledge.usingDefaults": "استخدام الإعدادات الافتراضية",
"newKnowledge.viewLabel": "عرض المعرفة",
"newKnowledge.viewTask": "عرض المهمة",
"newKnowledge.websiteCrawl": "الزحف إلى موقع الويب",
"noExternalKnowledge": "لا توجد واجهة برمجة تطبيقات معرفة خارجية حتى الآن، انقر هنا لإنشاء",
"parentMode.fullDoc": "مستند كامل",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Endpunkt",
"newKnowledge.authenticationMethod": "Authentifizierungsmethode",
"newKnowledge.averageChunkLength": "Durchschnittliche Abschnittslänge",
"newKnowledge.averageChunkLengthValue": "{{value}} Zeichen",
"newKnowledge.backToList": "Zurück zu den Wissensdatenbanken",
"newKnowledge.backgroundTasks": "Hintergrundaufgaben",
"newKnowledge.backgroundTasksDescription": "Dokumenthinzufügungen, Quellsynchronisierungen und Neuindizierungsaufträge.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Ja",
"newKnowledge.bulkDocumentActions": "Massendokumentaktionen",
"newKnowledge.cancelAddSource": "Abbrechen",
"newKnowledge.cancelDocumentReindex": "Neuindizierung abbrechen",
"newKnowledge.cardType": "Wissensbereich",
"newKnowledge.characterCount": "Zeichen",
"newKnowledge.checkReindexStatus": "Neuindizierungsstatus prüfen",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Die Neuindizierung wurde angenommen, aber der Aufgabenstatus ist verzögert. Prüfe ihn vor einer erneuten Übermittlung.",
"newKnowledge.documentReindexFailed": "Die Neuindizierung ist fehlgeschlagen. Die letzte bereite Revision bleibt verfügbar.",
"newKnowledge.documentReindexProgress": "Neuindizierung · {{progress}} %",
"newKnowledge.documentReindexStatus": "Dieses Dokument wird neu indiziert der aktuelle Index bleibt verfügbar, bis der neue bereit ist.",
"newKnowledge.documentRevision": "Versionsstand",
"newKnowledge.documentRevisionMissingDescription": "Dieses Dokument hat noch keine bereite Revision. Prüfen Sie es nach Abschluss der Verarbeitung erneut.",
"newKnowledge.documentRevisionMissingTitle": "Keine Revision verfügbar",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Lernen Sie die neue Wissensdatenbank kennen ✨",
"newKnowledge.illustrationHeadline": "Verbinde deine Inhalte einmal und jede App antwortet mit dem neuesten Wissen.",
"newKnowledge.includeSubpages": "Unterseiten einbeziehen",
"newKnowledge.indexInformation": "Indexinformationen",
"newKnowledge.indexInformation": "Index",
"newKnowledge.interruptTask": "Unterbrechen",
"newKnowledge.invalidRootUrl": "Gib eine gültige http(s)-URL ein.",
"newKnowledge.keepEditing": "Weiter bearbeiten",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} Seiten unter {{host}} gecrawlt",
"newKnowledge.pagesCrawled_other": "{{count}} Seiten unter {{host}} gecrawlt",
"newKnowledge.pagesSelected": "{{count}} ausgewählt",
"newKnowledge.parentChildChunkCount": "{{parentCount}} übergeordnete / {{childCount}} untergeordnete",
"newKnowledge.partialDocumentResults": "Weitere Dokumente könnten passen. Lade mehr, um die Suche fortzusetzen.",
"newKnowledge.permission": "Erlaubnis",
"newKnowledge.permissionAllMembers": "Arbeitsbereich · Alle Mitglieder können ihn ansehen und bearbeiten",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Neu indizieren",
"newKnowledge.removeSource": "Quelle entfernen",
"newKnowledge.retrievalCount": "Anzahl der Abrufe",
"newKnowledge.retrievalCountValue": "{{value}} in den letzten 7 Tagen",
"newKnowledge.retrievalTest.analyzing": "Belege analysieren",
"newKnowledge.retrievalTest.cancel": "Abbrechen",
"newKnowledge.retrievalTest.canceled": "Abgebrochen",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Wird hochgeladen…",
"newKnowledge.usingDefaults": "Standardeinstellungen werden verwendet",
"newKnowledge.viewLabel": "Wissensansicht",
"newKnowledge.viewTask": "Aufgabe anzeigen",
"newKnowledge.websiteCrawl": "Website-Crawling",
"noExternalKnowledge": "Es gibt noch keine External Knowledge API, klicken Sie hier, um zu erstellen",
"parentMode.fullDoc": "Vollständiges Dokument",

View File

@ -122,7 +122,7 @@
"metadata.datasetMetadata.values": "{{num}} Values",
"metadata.documentMetadata.documentInformation": "Document Information",
"metadata.documentMetadata.metadataToolTip": "Metadata serves as a critical filter that enhances the accuracy and relevance of information retrieval. You can modify and add metadata for this document here.",
"metadata.documentMetadata.startLabeling": "Start Labeling",
"metadata.documentMetadata.startLabeling": "Start labeling",
"metadata.documentMetadata.technicalParameters": "Technical Parameters",
"metadata.metadata": "Metadata",
"metadata.selectMetadata.manageAction": "Manage",
@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Endpoint",
"newKnowledge.authenticationMethod": "Authentication method",
"newKnowledge.averageChunkLength": "Average chunk length",
"newKnowledge.averageChunkLengthValue": "{{value}} characters",
"newKnowledge.backToList": "Back to knowledge bases",
"newKnowledge.backgroundTasks": "Background tasks",
"newKnowledge.backgroundTasksDescription": "Document adds, source syncs, and re-index jobs.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Yes",
"newKnowledge.bulkDocumentActions": "Bulk document actions",
"newKnowledge.cancelAddSource": "Cancel",
"newKnowledge.cancelDocumentReindex": "Cancel re-index",
"newKnowledge.cardType": "Knowledge space",
"newKnowledge.characterCount": "Characters",
"newKnowledge.checkReindexStatus": "Check re-index status",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Re-indexing was accepted, but its task status is delayed. Check again before submitting another re-index.",
"newKnowledge.documentReindexFailed": "Re-indexing failed. The last ready revision remains available.",
"newKnowledge.documentReindexProgress": "Re-indexing · {{progress}}%",
"newKnowledge.documentReindexStatus": "Re-indexing this document — the current index keeps serving until the new one is ready.",
"newKnowledge.documentRevision": "Revision",
"newKnowledge.documentRevisionMissingDescription": "This document doesn't have a ready revision yet. Check back after processing finishes.",
"newKnowledge.documentRevisionMissingTitle": "No revision available",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Meet the new Knowledge Base ✨",
"newKnowledge.illustrationHeadline": "Connect your content once — every app answers with the freshest knowledge.",
"newKnowledge.includeSubpages": "Include sub-pages",
"newKnowledge.indexInformation": "Index information",
"newKnowledge.indexInformation": "Index",
"newKnowledge.interruptTask": "Interrupt",
"newKnowledge.invalidRootUrl": "Enter a valid http(s) URL.",
"newKnowledge.keepEditing": "Keep editing",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} page crawled at {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} pages crawled at {{host}}",
"newKnowledge.pagesSelected": "{{count}} selected",
"newKnowledge.parentChildChunkCount": "{{parentCount}} parents / {{childCount}} children",
"newKnowledge.partialDocumentResults": "More documents may match. Load more to continue searching.",
"newKnowledge.permission": "Permission",
"newKnowledge.permissionAllMembers": "Workspace · all members can view and edit",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Re-index",
"newKnowledge.removeSource": "Remove source",
"newKnowledge.retrievalCount": "Retrieval count",
"newKnowledge.retrievalCountValue": "{{value}} in last 7 days",
"newKnowledge.retrievalTest.analyzing": "Analyze evidence",
"newKnowledge.retrievalTest.cancel": "Cancel",
"newKnowledge.retrievalTest.canceled": "Canceled",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Uploading…",
"newKnowledge.usingDefaults": "Using defaults",
"newKnowledge.viewLabel": "Knowledge view",
"newKnowledge.viewTask": "View task",
"newKnowledge.websiteCrawl": "Website crawl",
"noExternalKnowledge": "There is no External Knowledge API yet, click here to create",
"parentMode.fullDoc": "Full-doc",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Punto final",
"newKnowledge.authenticationMethod": "Método de autenticación",
"newKnowledge.averageChunkLength": "Longitud media del fragmento",
"newKnowledge.averageChunkLengthValue": "{{value}} caracteres",
"newKnowledge.backToList": "Volver a las bases de conocimiento",
"newKnowledge.backgroundTasks": "Tareas en segundo plano",
"newKnowledge.backgroundTasksDescription": "Agrega documentos, sincroniza fuentes y vuelve a indexar trabajos.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Sí",
"newKnowledge.bulkDocumentActions": "Acciones de documentos masivos",
"newKnowledge.cancelAddSource": "Cancelar",
"newKnowledge.cancelDocumentReindex": "Cancelar reindexación",
"newKnowledge.cardType": "Espacio de conocimiento",
"newKnowledge.characterCount": "Caracteres",
"newKnowledge.checkReindexStatus": "Comprobar estado de reindexación",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "La reindexación fue aceptada, pero el estado de la tarea está retrasado. Compruébalo antes de volver a enviarla.",
"newKnowledge.documentReindexFailed": "La reindexación falló. La última revisión lista sigue disponible.",
"newKnowledge.documentReindexProgress": "Reindexando · {{progress}} %",
"newKnowledge.documentReindexStatus": "Se está reindexando este documento; el índice actual seguirá disponible hasta que el nuevo esté listo.",
"newKnowledge.documentRevision": "Revisión",
"newKnowledge.documentRevisionMissingDescription": "Este documento aún no tiene una revisión lista. Vuelve cuando termine el procesamiento.",
"newKnowledge.documentRevisionMissingTitle": "No hay ninguna revisión disponible",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Conoce la nueva base de conocimiento ✨",
"newKnowledge.illustrationHeadline": "Conecta tu contenido una vez: cada aplicación responderá con el conocimiento más reciente.",
"newKnowledge.includeSubpages": "Incluir subpáginas",
"newKnowledge.indexInformation": "Información del índice",
"newKnowledge.indexInformation": "Índice",
"newKnowledge.interruptTask": "Interrumpir",
"newKnowledge.invalidRootUrl": "Introduce una URL http(s) válida.",
"newKnowledge.keepEditing": "Seguir editando",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} páginas rastreadas en {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} páginas rastreadas en {{host}}",
"newKnowledge.pagesSelected": "{{count}} seleccionados",
"newKnowledge.parentChildChunkCount": "{{parentCount}} principales / {{childCount}} secundarios",
"newKnowledge.partialDocumentResults": "Puede haber más documentos coincidentes. Carga más para continuar la búsqueda.",
"newKnowledge.permission": "Permiso",
"newKnowledge.permissionAllMembers": "Espacio de trabajo · todos los miembros pueden ver y editar",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Volver a indexar",
"newKnowledge.removeSource": "Eliminar fuente",
"newKnowledge.retrievalCount": "Número de recuperaciones",
"newKnowledge.retrievalCountValue": "{{value}} en los últimos 7 días",
"newKnowledge.retrievalTest.analyzing": "Analizar evidencias",
"newKnowledge.retrievalTest.cancel": "Cancelar",
"newKnowledge.retrievalTest.canceled": "Cancelado",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Subiendo…",
"newKnowledge.usingDefaults": "Usando valores predeterminados",
"newKnowledge.viewLabel": "Vista de conocimiento",
"newKnowledge.viewTask": "Ver tarea",
"newKnowledge.websiteCrawl": "Rastreo del sitio web",
"noExternalKnowledge": "Todavía no hay una API de conocimiento externo, haga clic aquí para crear",
"parentMode.fullDoc": "Documento completo",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "نقطه پایانی",
"newKnowledge.authenticationMethod": "روش احراز هویت",
"newKnowledge.averageChunkLength": "میانگین طول قطعه",
"newKnowledge.averageChunkLengthValue": "{{value}} نویسه",
"newKnowledge.backToList": "بازگشت به پایگاه های دانش",
"newKnowledge.backgroundTasks": "وظایف پس زمینه",
"newKnowledge.backgroundTasksDescription": "افزودن اسناد، همگام سازی منبع، و فهرست مجدد مشاغل.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "بله",
"newKnowledge.bulkDocumentActions": "اقدامات سند انبوه",
"newKnowledge.cancelAddSource": "لغو",
"newKnowledge.cancelDocumentReindex": "لغو نمایه‌سازی مجدد",
"newKnowledge.cardType": "فضای دانش",
"newKnowledge.characterCount": "نویسه‌ها",
"newKnowledge.checkReindexStatus": "بررسی وضعیت بازفهرست‌سازی",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "بازفهرست‌سازی پذیرفته شد، اما وضعیت کار با تأخیر نمایش داده می‌شود. پیش از ارسال دوباره آن را بررسی کنید.",
"newKnowledge.documentReindexFailed": "نمایه‌سازی دوباره ناموفق بود. آخرین بازبینی آماده همچنان در دسترس است.",
"newKnowledge.documentReindexProgress": "در حال نمایه‌سازی دوباره · {{progress}}٪",
"newKnowledge.documentReindexStatus": "این سند در حال نمایه‌سازی مجدد است — نمایه فعلی تا آماده شدن نمایه جدید به کار خود ادامه می‌دهد.",
"newKnowledge.documentRevision": "بازبینی",
"newKnowledge.documentRevisionMissingDescription": "این سند هنوز بازبینی آماده‌ای ندارد. پس از پایان پردازش دوباره بررسی کنید.",
"newKnowledge.documentRevisionMissingTitle": "هیچ بازبینی در دسترس نیست",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "با پایگاه دانش جدید آشنا شوید ✨",
"newKnowledge.illustrationHeadline": "محتوای خود را یک‌بار متصل کنید تا هر برنامه با تازه‌ترین دانش پاسخ دهد.",
"newKnowledge.includeSubpages": "شامل صفحه‌های فرعی",
"newKnowledge.indexInformation": "اطلاعات نمایه",
"newKnowledge.indexInformation": "نمایه",
"newKnowledge.interruptTask": "توقف",
"newKnowledge.invalidRootUrl": "یک نشانی معتبر http(s) وارد کنید.",
"newKnowledge.keepEditing": "ادامه ویرایش",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} صفحه در {{host}} پیمایش شد",
"newKnowledge.pagesCrawled_other": "{{count}} صفحه در {{host}} پیمایش شد",
"newKnowledge.pagesSelected": "{{count}} مورد انتخاب شد",
"newKnowledge.parentChildChunkCount": "{{parentCount}} والد / {{childCount}} فرزند",
"newKnowledge.partialDocumentResults": "ممکن است اسناد بیشتری مطابقت داشته باشند. برای ادامه جستجو موارد بیشتری بارگیری کنید.",
"newKnowledge.permission": "اجازه",
"newKnowledge.permissionAllMembers": "فضای کاری · همه اعضا می توانند مشاهده و ویرایش کنند",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "فهرست مجدد",
"newKnowledge.removeSource": "حذف منبع",
"newKnowledge.retrievalCount": "تعداد بازیابی",
"newKnowledge.retrievalCountValue": "{{value}} در ۷ روز گذشته",
"newKnowledge.retrievalTest.analyzing": "تحلیل شواهد",
"newKnowledge.retrievalTest.cancel": "لغو",
"newKnowledge.retrievalTest.canceled": "لغو شد",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "در حال بارگذاری…",
"newKnowledge.usingDefaults": "استفاده از تنظیمات پیش‌فرض",
"newKnowledge.viewLabel": "نمای دانش",
"newKnowledge.viewTask": "مشاهده وظیفه",
"newKnowledge.websiteCrawl": "خزیدن وب سایت",
"noExternalKnowledge": "هنوز هیچ API دانش خارجی وجود ندارد، برای ایجاد اینجا را کلیک کنید",
"parentMode.fullDoc": "مستند کامل",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Point de terminaison",
"newKnowledge.authenticationMethod": "Méthode d'authentification",
"newKnowledge.averageChunkLength": "Longueur moyenne des segments",
"newKnowledge.averageChunkLengthValue": "{{value}} caractères",
"newKnowledge.backToList": "Retour aux bases de connaissances",
"newKnowledge.backgroundTasks": "Tâches en arrière-plan",
"newKnowledge.backgroundTasksDescription": "Ajouts de documents, synchronisations de sources et tâches de réindexation.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Oui",
"newKnowledge.bulkDocumentActions": "Actions de documents en masse",
"newKnowledge.cancelAddSource": "Annuler",
"newKnowledge.cancelDocumentReindex": "Annuler la réindexation",
"newKnowledge.cardType": "Espace de connaissances",
"newKnowledge.characterCount": "Caractères",
"newKnowledge.checkReindexStatus": "Vérifier létat de réindexation",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "La réindexation a été acceptée, mais létat de la tâche est retardé. Vérifiez-le avant un nouvel envoi.",
"newKnowledge.documentReindexFailed": "La réindexation a échoué. La dernière révision prête reste disponible.",
"newKnowledge.documentReindexProgress": "Réindexation · {{progress}} %",
"newKnowledge.documentReindexStatus": "Ce document est en cours de réindexation — lindex actuel reste disponible jusquà ce que le nouveau soit prêt.",
"newKnowledge.documentRevision": "Révision",
"newKnowledge.documentRevisionMissingDescription": "Ce document ne possède pas encore de révision prête. Revenez une fois le traitement terminé.",
"newKnowledge.documentRevisionMissingTitle": "Aucune révision disponible",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Découvrez la nouvelle base de connaissances ✨",
"newKnowledge.illustrationHeadline": "Connectez votre contenu une fois : chaque application répond avec les connaissances les plus récentes.",
"newKnowledge.includeSubpages": "Inclure les sous-pages",
"newKnowledge.indexInformation": "Informations dindexation",
"newKnowledge.indexInformation": "Index",
"newKnowledge.interruptTask": "Interrompre",
"newKnowledge.invalidRootUrl": "Saisissez une URL http(s) valide.",
"newKnowledge.keepEditing": "Continuer la modification",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} pages explorées sur {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} pages explorées sur {{host}}",
"newKnowledge.pagesSelected": "{{count}} sélectionné(s)",
"newKnowledge.parentChildChunkCount": "{{parentCount}} parents / {{childCount}} enfants",
"newKnowledge.partialDocumentResults": "Dautres documents peuvent correspondre. Chargez-en davantage pour poursuivre la recherche.",
"newKnowledge.permission": "Autorisation",
"newKnowledge.permissionAllMembers": "Espace de travail · tous les membres peuvent consulter et modifier",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Réindexer",
"newKnowledge.removeSource": "Supprimer la source",
"newKnowledge.retrievalCount": "Nombre de récupérations",
"newKnowledge.retrievalCountValue": "{{value}} au cours des 7 derniers jours",
"newKnowledge.retrievalTest.analyzing": "Analyser les éléments",
"newKnowledge.retrievalTest.cancel": "Annuler",
"newKnowledge.retrievalTest.canceled": "Annulé",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Téléversement…",
"newKnowledge.usingDefaults": "Valeurs par défaut utilisées",
"newKnowledge.viewLabel": "Vue des connaissances",
"newKnowledge.viewTask": "Voir la tâche",
"newKnowledge.websiteCrawl": "Exploration du site Web",
"noExternalKnowledge": "Il ny a pas encore dAPI de connaissances externes, cliquez ici pour créer",
"parentMode.fullDoc": "Doc complet",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "समापन बिंदु",
"newKnowledge.authenticationMethod": "प्रमाणीकरण विधि",
"newKnowledge.averageChunkLength": "औसत खंड लंबाई",
"newKnowledge.averageChunkLengthValue": "{{value}} वर्ण",
"newKnowledge.backToList": "ज्ञानकोष पर वापस जाएँ",
"newKnowledge.backgroundTasks": "पृष्ठभूमि कार्य",
"newKnowledge.backgroundTasksDescription": "दस्तावेज़ जोड़ता है, स्रोत सिंक करता है, और नौकरियों को पुन: अनुक्रमित करता है।",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "हाँ",
"newKnowledge.bulkDocumentActions": "थोक दस्तावेज़ क्रियाएँ",
"newKnowledge.cancelAddSource": "रद्द करें",
"newKnowledge.cancelDocumentReindex": "री-इंडेक्स रद्द करें",
"newKnowledge.cardType": "नॉलेज स्पेस",
"newKnowledge.characterCount": "अक्षर",
"newKnowledge.checkReindexStatus": "पुनः इंडेक्स स्थिति जाँचें",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "पुनः इंडेक्स अनुरोध स्वीकार हुआ, लेकिन कार्य स्थिति में देरी है। दोबारा भेजने से पहले जाँचें।",
"newKnowledge.documentReindexFailed": "पुनः इंडेक्सिंग विफल हुई। अंतिम तैयार संशोधन उपलब्ध रहेगा।",
"newKnowledge.documentReindexProgress": "पुनः इंडेक्स हो रहा है · {{progress}}%",
"newKnowledge.documentReindexStatus": "इस दस्तावेज़ को फिर से इंडेक्स किया जा रहा है — नया इंडेक्स तैयार होने तक मौजूदा इंडेक्स उपलब्ध रहेगा।",
"newKnowledge.documentRevision": "संशोधन",
"newKnowledge.documentRevisionMissingDescription": "इस दस्तावेज़ का कोई तैयार संशोधन अभी नहीं है। प्रोसेसिंग पूरी होने के बाद फिर देखें।",
"newKnowledge.documentRevisionMissingTitle": "कोई संशोधन उपलब्ध नहीं",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "नए नॉलेज बेस से मिलें ✨",
"newKnowledge.illustrationHeadline": "अपनी सामग्री एक बार कनेक्ट करें — हर ऐप नवीनतम ज्ञान के साथ जवाब देगा।",
"newKnowledge.includeSubpages": "उप-पेज शामिल करें",
"newKnowledge.indexInformation": "अनुक्रमणिका जानकारी",
"newKnowledge.indexInformation": "अनुक्रमणिका",
"newKnowledge.interruptTask": "रोकें",
"newKnowledge.invalidRootUrl": "मान्य http(s) URL दर्ज करें।",
"newKnowledge.keepEditing": "संपादन जारी रखें",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{host}} पर {{count}} पेज क्रॉल किए गए",
"newKnowledge.pagesCrawled_other": "{{host}} पर {{count}} पेज क्रॉल किए गए",
"newKnowledge.pagesSelected": "{{count}} चयनित",
"newKnowledge.parentChildChunkCount": "{{parentCount}} पैरेंट / {{childCount}} चाइल्ड",
"newKnowledge.partialDocumentResults": "और दस्तावेज़ मेल खा सकते हैं। खोज जारी रखने के लिए और लोड करें।",
"newKnowledge.permission": "अनुमति",
"newKnowledge.permissionAllMembers": "कार्यक्षेत्र · सभी सदस्य देख और संपादित कर सकते हैं",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "पुन: अनुक्रमणिका",
"newKnowledge.removeSource": "स्रोत हटाएं",
"newKnowledge.retrievalCount": "पुनर्प्राप्ति संख्या",
"newKnowledge.retrievalCountValue": "पिछले 7 दिनों में {{value}}",
"newKnowledge.retrievalTest.analyzing": "साक्ष्य का विश्लेषण करें",
"newKnowledge.retrievalTest.cancel": "रद्द करें",
"newKnowledge.retrievalTest.canceled": "रद्द किया गया",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "अपलोड हो रहा है…",
"newKnowledge.usingDefaults": "डिफ़ॉल्ट सेटिंग का उपयोग हो रहा है",
"newKnowledge.viewLabel": "नॉलेज दृश्य",
"newKnowledge.viewTask": "टास्क देखें",
"newKnowledge.websiteCrawl": "वेबसाइट क्रॉल",
"noExternalKnowledge": "अभी तक कोई बाहरी ज्ञान एपीआई नहीं है, बनाने के लिए यहां क्लिक करें",
"parentMode.fullDoc": "पूर्ण-दस्तावेज़",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Titik akhir",
"newKnowledge.authenticationMethod": "Metode otentikasi",
"newKnowledge.averageChunkLength": "Panjang potongan rata-rata",
"newKnowledge.averageChunkLengthValue": "{{value}} karakter",
"newKnowledge.backToList": "Kembali ke basis pengetahuan",
"newKnowledge.backgroundTasks": "Tugas latar belakang",
"newKnowledge.backgroundTasksDescription": "Penambahan dokumen, sinkronisasi sumber, dan mengindeks ulang pekerjaan.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Ya",
"newKnowledge.bulkDocumentActions": "Tindakan dokumen massal",
"newKnowledge.cancelAddSource": "Batal",
"newKnowledge.cancelDocumentReindex": "Batalkan pengindeksan ulang",
"newKnowledge.cardType": "Ruang pengetahuan",
"newKnowledge.characterCount": "Karakter",
"newKnowledge.checkReindexStatus": "Periksa status pengindeksan ulang",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Pengindeksan ulang diterima, tetapi status tugas tertunda. Periksa sebelum mengirim ulang.",
"newKnowledge.documentReindexFailed": "Pengindeksan ulang gagal. Revisi siap terakhir tetap tersedia.",
"newKnowledge.documentReindexProgress": "Mengindeks ulang · {{progress}}%",
"newKnowledge.documentReindexStatus": "Dokumen ini sedang diindeks ulang — indeks saat ini tetap tersedia hingga indeks baru siap.",
"newKnowledge.documentRevision": "Revisi",
"newKnowledge.documentRevisionMissingDescription": "Dokumen ini belum memiliki revisi siap. Periksa lagi setelah pemrosesan selesai.",
"newKnowledge.documentRevisionMissingTitle": "Tidak ada revisi yang tersedia",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Kenali Basis Pengetahuan baru ✨",
"newKnowledge.illustrationHeadline": "Hubungkan konten Anda sekali — setiap aplikasi menjawab dengan pengetahuan terbaru.",
"newKnowledge.includeSubpages": "Sertakan subhalaman",
"newKnowledge.indexInformation": "Informasi indeks",
"newKnowledge.indexInformation": "Indeks",
"newKnowledge.interruptTask": "Hentikan",
"newKnowledge.invalidRootUrl": "Masukkan URL http(s) yang valid.",
"newKnowledge.keepEditing": "Lanjutkan mengedit",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} halaman dirayapi di {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} halaman dirayapi di {{host}}",
"newKnowledge.pagesSelected": "{{count}} dipilih",
"newKnowledge.parentChildChunkCount": "{{parentCount}} induk / {{childCount}} anak",
"newKnowledge.partialDocumentResults": "Mungkin ada dokumen lain yang cocok. Muat lebih banyak untuk melanjutkan pencarian.",
"newKnowledge.permission": "Izin",
"newKnowledge.permissionAllMembers": "Ruang Kerja · semua anggota dapat melihat dan mengedit",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Indeks ulang",
"newKnowledge.removeSource": "Hapus sumber",
"newKnowledge.retrievalCount": "Jumlah pengambilan",
"newKnowledge.retrievalCountValue": "{{value}} dalam 7 hari terakhir",
"newKnowledge.retrievalTest.analyzing": "Analisis bukti",
"newKnowledge.retrievalTest.cancel": "Batal",
"newKnowledge.retrievalTest.canceled": "Dibatalkan",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Mengunggah…",
"newKnowledge.usingDefaults": "Menggunakan pengaturan default",
"newKnowledge.viewLabel": "Tampilan pengetahuan",
"newKnowledge.viewTask": "Lihat tugas",
"newKnowledge.websiteCrawl": "Perayapan situs web",
"noExternalKnowledge": "Belum ada API Pengetahuan Eksternal, klik di sini untuk membuat",
"parentMode.fullDoc": "Dokumen lengkap",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Punto finale",
"newKnowledge.authenticationMethod": "Metodo di autenticazione",
"newKnowledge.averageChunkLength": "Lunghezza media dei segmenti",
"newKnowledge.averageChunkLengthValue": "{{value}} caratteri",
"newKnowledge.backToList": "Torniamo alle basi di conoscenza",
"newKnowledge.backgroundTasks": "Attività in background",
"newKnowledge.backgroundTasksDescription": "Aggiunte di documenti, sincronizzazioni di origini e processi di reindicizzazione.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Sì",
"newKnowledge.bulkDocumentActions": "Azioni di documenti in blocco",
"newKnowledge.cancelAddSource": "Annulla",
"newKnowledge.cancelDocumentReindex": "Annulla reindicizzazione",
"newKnowledge.cardType": "Spazio di conoscenza",
"newKnowledge.characterCount": "Caratteri",
"newKnowledge.checkReindexStatus": "Controlla stato reindicizzazione",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "La reindicizzazione è stata accettata, ma lo stato dellattività è in ritardo. Controllalo prima di inviarne unaltra.",
"newKnowledge.documentReindexFailed": "La reindicizzazione non è riuscita. Lultima revisione pronta resta disponibile.",
"newKnowledge.documentReindexProgress": "Reindicizzazione · {{progress}}%",
"newKnowledge.documentReindexStatus": "Questo documento è in fase di reindicizzazione: lindice attuale rimane disponibile finché il nuovo non è pronto.",
"newKnowledge.documentRevision": "Revisione",
"newKnowledge.documentRevisionMissingDescription": "Questo documento non ha ancora una revisione pronta. Ricontrolla al termine dellelaborazione.",
"newKnowledge.documentRevisionMissingTitle": "Nessuna revisione disponibile",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Scopri la nuova Knowledge Base ✨",
"newKnowledge.illustrationHeadline": "Collega i tuoi contenuti una sola volta: ogni app risponderà con le conoscenze più aggiornate.",
"newKnowledge.includeSubpages": "Includi sottopagine",
"newKnowledge.indexInformation": "Informazioni sullindice",
"newKnowledge.indexInformation": "Indice",
"newKnowledge.interruptTask": "Interrompere",
"newKnowledge.invalidRootUrl": "Inserisci un URL http(s) valido.",
"newKnowledge.keepEditing": "Continua a modificare",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} pagine sottoposte a scansione su {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} pagine sottoposte a scansione su {{host}}",
"newKnowledge.pagesSelected": "{{count}} selezionati",
"newKnowledge.parentChildChunkCount": "{{parentCount}} principali / {{childCount}} secondari",
"newKnowledge.partialDocumentResults": "Potrebbero esserci altri documenti corrispondenti. Caricane altri per continuare la ricerca.",
"newKnowledge.permission": "Autorizzazione",
"newKnowledge.permissionAllMembers": "Area di lavoro · tutti i membri possono visualizzare e modificare",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Reindicizzare",
"newKnowledge.removeSource": "Rimuovi la fonte",
"newKnowledge.retrievalCount": "Numero di recuperi",
"newKnowledge.retrievalCountValue": "{{value}} negli ultimi 7 giorni",
"newKnowledge.retrievalTest.analyzing": "Analizza le evidenze",
"newKnowledge.retrievalTest.cancel": "Annulla",
"newKnowledge.retrievalTest.canceled": "Annullato",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Caricamento…",
"newKnowledge.usingDefaults": "Impostazioni predefinite in uso",
"newKnowledge.viewLabel": "Vista conoscenza",
"newKnowledge.viewTask": "Visualizza attività",
"newKnowledge.websiteCrawl": "Scansione del sito web",
"noExternalKnowledge": "Non esiste ancora un'API di conoscenza esterna, fai clic qui per creare",
"parentMode.fullDoc": "Full-doc",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "エンドポイント",
"newKnowledge.authenticationMethod": "認証方法",
"newKnowledge.averageChunkLength": "チャンクの平均長",
"newKnowledge.averageChunkLengthValue": "{{value}} 文字",
"newKnowledge.backToList": "ナレッジベースに戻る",
"newKnowledge.backgroundTasks": "バックグラウンドタスク",
"newKnowledge.backgroundTasksDescription": "ドキュメントの追加、ソースの同期、ジョブの再インデックス。",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "はい",
"newKnowledge.bulkDocumentActions": "一括ドキュメントアクション",
"newKnowledge.cancelAddSource": "キャンセル",
"newKnowledge.cancelDocumentReindex": "再インデックスをキャンセル",
"newKnowledge.cardType": "ナレッジスペース",
"newKnowledge.characterCount": "文字数",
"newKnowledge.checkReindexStatus": "再インデックス状態を確認",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "再インデックスは受理されましたが、タスク状態の反映が遅れています。再送信前に確認してください。",
"newKnowledge.documentReindexFailed": "再インデックスに失敗しました。最後に準備完了となったリビジョンは引き続き利用できます。",
"newKnowledge.documentReindexProgress": "再インデックス中 · {{progress}}%",
"newKnowledge.documentReindexStatus": "このドキュメントを再インデックスしています。新しいインデックスの準備ができるまで、現在のインデックスが引き続き使用されます。",
"newKnowledge.documentRevision": "リビジョン",
"newKnowledge.documentRevisionMissingDescription": "このドキュメントには準備完了のリビジョンがまだありません。処理完了後に再度確認してください。",
"newKnowledge.documentRevisionMissingTitle": "利用可能なリビジョンはありません",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "新しいナレッジベースへようこそ ✨",
"newKnowledge.illustrationHeadline": "コンテンツを一度接続すれば、すべてのアプリが最新のナレッジで回答します。",
"newKnowledge.includeSubpages": "サブページを含める",
"newKnowledge.indexInformation": "インデックス情報",
"newKnowledge.indexInformation": "インデックス",
"newKnowledge.interruptTask": "中断",
"newKnowledge.invalidRootUrl": "有効なhttp(s) URLを入力してください。",
"newKnowledge.keepEditing": "編集を続ける",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{host}} で{{count}}ページをクロールしました",
"newKnowledge.pagesCrawled_other": "{{host}} で{{count}}ページをクロールしました",
"newKnowledge.pagesSelected": "{{count}} 件選択済み",
"newKnowledge.parentChildChunkCount": "親 {{parentCount}} / 子 {{childCount}}",
"newKnowledge.partialDocumentResults": "一致するドキュメントがほかにもある可能性があります。検索を続けるにはさらに読み込んでください。",
"newKnowledge.permission": "許可",
"newKnowledge.permissionAllMembers": "ワークスペース · すべてのメンバーが表示および編集できます",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "インデックスを再作成する",
"newKnowledge.removeSource": "ソースを削除",
"newKnowledge.retrievalCount": "取得回数",
"newKnowledge.retrievalCountValue": "過去7日間で{{value}}回",
"newKnowledge.retrievalTest.analyzing": "根拠を分析",
"newKnowledge.retrievalTest.cancel": "キャンセル",
"newKnowledge.retrievalTest.canceled": "キャンセル済み",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "アップロード中…",
"newKnowledge.usingDefaults": "デフォルト設定を使用中",
"newKnowledge.viewLabel": "ナレッジ表示",
"newKnowledge.viewTask": "タスクを表示",
"newKnowledge.websiteCrawl": "ウェブサイトのクロール",
"noExternalKnowledge": "外部ナレッジベース連携 API がありません。ここをクリックして作成してください",
"parentMode.fullDoc": "全体",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "종점",
"newKnowledge.authenticationMethod": "인증 방법",
"newKnowledge.averageChunkLength": "평균 청크 길이",
"newKnowledge.averageChunkLengthValue": "{{value}}자",
"newKnowledge.backToList": "지식 베이스로 돌아가기",
"newKnowledge.backgroundTasks": "백그라운드 작업",
"newKnowledge.backgroundTasksDescription": "문서 추가, 소스 동기화 및 재색인 작업.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "예",
"newKnowledge.bulkDocumentActions": "대량 문서 작업",
"newKnowledge.cancelAddSource": "취소",
"newKnowledge.cancelDocumentReindex": "재인덱싱 취소",
"newKnowledge.cardType": "지식 공간",
"newKnowledge.characterCount": "문자 수",
"newKnowledge.checkReindexStatus": "재인덱싱 상태 확인",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "재인덱싱이 접수되었지만 작업 상태 반영이 지연되고 있습니다. 다시 제출하기 전에 확인하세요.",
"newKnowledge.documentReindexFailed": "재인덱싱에 실패했습니다. 마지막 준비 완료 리비전은 계속 사용할 수 있습니다.",
"newKnowledge.documentReindexProgress": "재인덱싱 중 · {{progress}}%",
"newKnowledge.documentReindexStatus": "이 문서를 재인덱싱하는 중입니다. 새 인덱스가 준비될 때까지 현재 인덱스가 계속 제공됩니다.",
"newKnowledge.documentRevision": "리비전",
"newKnowledge.documentRevisionMissingDescription": "이 문서에는 아직 준비 완료된 리비전이 없습니다. 처리가 끝난 후 다시 확인하세요.",
"newKnowledge.documentRevisionMissingTitle": "사용 가능한 리비전 없음",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "새로운 지식 베이스를 만나보세요 ✨",
"newKnowledge.illustrationHeadline": "콘텐츠를 한 번 연결하면 모든 앱이 최신 지식으로 답변합니다.",
"newKnowledge.includeSubpages": "하위 페이지 포함",
"newKnowledge.indexInformation": "인덱스 정보",
"newKnowledge.indexInformation": "인덱스",
"newKnowledge.interruptTask": "중단",
"newKnowledge.invalidRootUrl": "유효한 http(s) URL을 입력하세요.",
"newKnowledge.keepEditing": "계속 편집",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{host}}에서 {{count}}개 페이지를 크롤링했습니다",
"newKnowledge.pagesCrawled_other": "{{host}}에서 {{count}}개 페이지를 크롤링했습니다",
"newKnowledge.pagesSelected": "{{count}}개 선택됨",
"newKnowledge.parentChildChunkCount": "상위 {{parentCount}}개 / 하위 {{childCount}}개",
"newKnowledge.partialDocumentResults": "일치하는 문서가 더 있을 수 있습니다. 검색을 계속하려면 더 불러오세요.",
"newKnowledge.permission": "허가",
"newKnowledge.permissionAllMembers": "작업공간 · 모든 구성원이 보고 편집할 수 있습니다.",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "재인덱싱",
"newKnowledge.removeSource": "소스 제거",
"newKnowledge.retrievalCount": "검색 횟수",
"newKnowledge.retrievalCountValue": "최근 7일 동안 {{value}}회",
"newKnowledge.retrievalTest.analyzing": "근거 분석",
"newKnowledge.retrievalTest.cancel": "취소",
"newKnowledge.retrievalTest.canceled": "취소됨",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "업로드 중…",
"newKnowledge.usingDefaults": "기본값 사용 중",
"newKnowledge.viewLabel": "지식 보기",
"newKnowledge.viewTask": "작업 보기",
"newKnowledge.websiteCrawl": "웹사이트 크롤링",
"noExternalKnowledge": "아직 외부 지식 API 가 없으므로 여기를 클릭하여 생성하십시오.",
"parentMode.fullDoc": "전체 문서",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Eindpunt",
"newKnowledge.authenticationMethod": "Authenticatiemethode",
"newKnowledge.averageChunkLength": "Gemiddelde segmentlengte",
"newKnowledge.averageChunkLengthValue": "{{value}} tekens",
"newKnowledge.backToList": "Terug naar kennisbanken",
"newKnowledge.backgroundTasks": "Achtergrondtaken",
"newKnowledge.backgroundTasksDescription": "Documenten toevoegen, bronsynchronisaties en taken opnieuw indexeren.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Ja",
"newKnowledge.bulkDocumentActions": "Bulkdocumentacties",
"newKnowledge.cancelAddSource": "Annuleren",
"newKnowledge.cancelDocumentReindex": "Herindexering annuleren",
"newKnowledge.cardType": "Kennisruimte",
"newKnowledge.characterCount": "Tekens",
"newKnowledge.checkReindexStatus": "Status van herindexering controleren",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "De herindexering is geaccepteerd, maar de taakstatus is vertraagd. Controleer deze voordat je opnieuw indient.",
"newKnowledge.documentReindexFailed": "Opnieuw indexeren is mislukt. De laatste gereedstaande revisie blijft beschikbaar.",
"newKnowledge.documentReindexProgress": "Opnieuw indexeren · {{progress}}%",
"newKnowledge.documentReindexStatus": "Dit document wordt opnieuw geïndexeerd — de huidige index blijft beschikbaar totdat de nieuwe gereed is.",
"newKnowledge.documentRevision": "Revisie",
"newKnowledge.documentRevisionMissingDescription": "Dit document heeft nog geen gereedstaande revisie. Kijk opnieuw nadat de verwerking is voltooid.",
"newKnowledge.documentRevisionMissingTitle": "Geen revisie beschikbaar",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Maak kennis met de nieuwe Kennisbank ✨",
"newKnowledge.illustrationHeadline": "Koppel je content één keer — elke app antwoordt met de meest actuele kennis.",
"newKnowledge.includeSubpages": "Subpaginas opnemen",
"newKnowledge.indexInformation": "Indexinformatie",
"newKnowledge.indexInformation": "Index",
"newKnowledge.interruptTask": "Onderbreken",
"newKnowledge.invalidRootUrl": "Voer een geldige http(s)-URL in.",
"newKnowledge.keepEditing": "Doorgaan met bewerken",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} paginas gecrawld op {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} paginas gecrawld op {{host}}",
"newKnowledge.pagesSelected": "{{count}} geselecteerd",
"newKnowledge.parentChildChunkCount": "{{parentCount}} bovenliggend / {{childCount}} onderliggend",
"newKnowledge.partialDocumentResults": "Er kunnen meer overeenkomende documenten zijn. Laad meer om verder te zoeken.",
"newKnowledge.permission": "Toestemming",
"newKnowledge.permissionAllMembers": "Werkruimte · alle leden kunnen bekijken en bewerken",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Opnieuw indexeren",
"newKnowledge.removeSource": "Bron verwijderen",
"newKnowledge.retrievalCount": "Aantal zoekacties",
"newKnowledge.retrievalCountValue": "{{value}} in de afgelopen 7 dagen",
"newKnowledge.retrievalTest.analyzing": "Bewijs analyseren",
"newKnowledge.retrievalTest.cancel": "Annuleren",
"newKnowledge.retrievalTest.canceled": "Geannuleerd",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Uploaden…",
"newKnowledge.usingDefaults": "Standaardinstellingen gebruikt",
"newKnowledge.viewLabel": "Kennisweergave",
"newKnowledge.viewTask": "Taak bekijken",
"newKnowledge.websiteCrawl": "Websitecrawl",
"noExternalKnowledge": "There is no External Knowledge API yet, click here to create",
"parentMode.fullDoc": "Full-doc",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Punkt końcowy",
"newKnowledge.authenticationMethod": "Metoda uwierzytelniania",
"newKnowledge.averageChunkLength": "Średnia długość fragmentu",
"newKnowledge.averageChunkLengthValue": "{{value}} znaków",
"newKnowledge.backToList": "Powrót do baz wiedzy",
"newKnowledge.backgroundTasks": "Zadania w tle",
"newKnowledge.backgroundTasksDescription": "Dodawanie dokumentów, synchronizacja źródeł i ponowne indeksowanie zadań.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Tak",
"newKnowledge.bulkDocumentActions": "Zbiorcze akcje dokumentów",
"newKnowledge.cancelAddSource": "Anuluj",
"newKnowledge.cancelDocumentReindex": "Anuluj ponowne indeksowanie",
"newKnowledge.cardType": "Przestrzeń wiedzy",
"newKnowledge.characterCount": "Znaki",
"newKnowledge.checkReindexStatus": "Sprawdź stan ponownego indeksowania",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Ponowne indeksowanie zostało przyjęte, ale stan zadania jest opóźniony. Sprawdź go przed ponownym wysłaniem.",
"newKnowledge.documentReindexFailed": "Ponowne indeksowanie nie powiodło się. Ostatnia gotowa wersja pozostaje dostępna.",
"newKnowledge.documentReindexProgress": "Ponowne indeksowanie · {{progress}}%",
"newKnowledge.documentReindexStatus": "Ten dokument jest ponownie indeksowany — bieżący indeks pozostanie dostępny, dopóki nowy nie będzie gotowy.",
"newKnowledge.documentRevision": "Wersja",
"newKnowledge.documentRevisionMissingDescription": "Ten dokument nie ma jeszcze gotowej wersji. Sprawdź ponownie po zakończeniu przetwarzania.",
"newKnowledge.documentRevisionMissingTitle": "Brak dostępnej wersji",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Poznaj nową bazę wiedzy ✨",
"newKnowledge.illustrationHeadline": "Połącz treści raz — każda aplikacja odpowie, korzystając z najnowszej wiedzy.",
"newKnowledge.includeSubpages": "Uwzględnij podstrony",
"newKnowledge.indexInformation": "Informacje o indeksie",
"newKnowledge.indexInformation": "Indeks",
"newKnowledge.interruptTask": "Przerwij",
"newKnowledge.invalidRootUrl": "Wprowadź prawidłowy adres URL http(s).",
"newKnowledge.keepEditing": "Kontynuuj edycję",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "Przeskanowano {{count}} stron w {{host}}",
"newKnowledge.pagesCrawled_other": "Przeskanowano {{count}} stron w {{host}}",
"newKnowledge.pagesSelected": "Wybrano: {{count}}",
"newKnowledge.parentChildChunkCount": "{{parentCount}} nadrzędnych / {{childCount}} podrzędnych",
"newKnowledge.partialDocumentResults": "Więcej dokumentów może pasować. Wczytaj więcej, aby kontynuować wyszukiwanie.",
"newKnowledge.permission": "Pozwolenie",
"newKnowledge.permissionAllMembers": "Obszar roboczy · wszyscy członkowie mogą przeglądać i edytować",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Ponowne indeksowanie",
"newKnowledge.removeSource": "Usuń źródło",
"newKnowledge.retrievalCount": "Liczba pobrań",
"newKnowledge.retrievalCountValue": "{{value}} w ciągu ostatnich 7 dni",
"newKnowledge.retrievalTest.analyzing": "Analizuj dowody",
"newKnowledge.retrievalTest.cancel": "Anuluj",
"newKnowledge.retrievalTest.canceled": "Anulowano",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Przesyłanie…",
"newKnowledge.usingDefaults": "Używane są ustawienia domyślne",
"newKnowledge.viewLabel": "Widok wiedzy",
"newKnowledge.viewTask": "Wyświetl zadanie",
"newKnowledge.websiteCrawl": "Indeksowanie witryny",
"noExternalKnowledge": "Nie ma jeszcze interfejsu API wiedzy zewnętrznej, kliknij tutaj, aby utworzyć",
"parentMode.fullDoc": "Pełna wersja dokumentu",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Ponto final",
"newKnowledge.authenticationMethod": "Método de autenticação",
"newKnowledge.averageChunkLength": "Comprimento médio do segmento",
"newKnowledge.averageChunkLengthValue": "{{value}} caracteres",
"newKnowledge.backToList": "Voltar às bases de conhecimento",
"newKnowledge.backgroundTasks": "Tarefas em segundo plano",
"newKnowledge.backgroundTasksDescription": "Adições de documentos, sincronizações de origem e reindexação de trabalhos.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Sim",
"newKnowledge.bulkDocumentActions": "Ações de documentos em massa",
"newKnowledge.cancelAddSource": "Cancelar",
"newKnowledge.cancelDocumentReindex": "Cancelar reindexação",
"newKnowledge.cardType": "Espaço de conhecimento",
"newKnowledge.characterCount": "Caracteres",
"newKnowledge.checkReindexStatus": "Verificar status da reindexação",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "A reindexação foi aceita, mas o status da tarefa está atrasado. Verifique antes de enviar novamente.",
"newKnowledge.documentReindexFailed": "A reindexação falhou. A última revisão pronta continua disponível.",
"newKnowledge.documentReindexProgress": "Reindexando · {{progress}}%",
"newKnowledge.documentReindexStatus": "Este documento está sendo reindexado — o índice atual continuará disponível até que o novo esteja pronto.",
"newKnowledge.documentRevision": "Revisão",
"newKnowledge.documentRevisionMissingDescription": "Este documento ainda não tem uma revisão pronta. Volte após o processamento terminar.",
"newKnowledge.documentRevisionMissingTitle": "Nenhuma revisão disponível",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Conheça a nova Base de Conhecimento ✨",
"newKnowledge.illustrationHeadline": "Conecte seu conteúdo uma vez — cada aplicativo responderá com o conhecimento mais recente.",
"newKnowledge.includeSubpages": "Incluir subpáginas",
"newKnowledge.indexInformation": "Informações do índice",
"newKnowledge.indexInformation": "Índice",
"newKnowledge.interruptTask": "Interromper",
"newKnowledge.invalidRootUrl": "Insira uma URL http(s) válida.",
"newKnowledge.keepEditing": "Continuar editando",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} páginas rastreadas em {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} páginas rastreadas em {{host}}",
"newKnowledge.pagesSelected": "{{count}} selecionado(s)",
"newKnowledge.parentChildChunkCount": "{{parentCount}} principais / {{childCount}} secundários",
"newKnowledge.partialDocumentResults": "Pode haver mais documentos correspondentes. Carregue mais para continuar a pesquisa.",
"newKnowledge.permission": "Permissão",
"newKnowledge.permissionAllMembers": "Espaço de trabalho · todos os membros podem visualizar e editar",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Reindexar",
"newKnowledge.removeSource": "Remover fonte",
"newKnowledge.retrievalCount": "Quantidade de recuperações",
"newKnowledge.retrievalCountValue": "{{value}} nos últimos 7 dias",
"newKnowledge.retrievalTest.analyzing": "Analisar evidências",
"newKnowledge.retrievalTest.cancel": "Cancelar",
"newKnowledge.retrievalTest.canceled": "Cancelado",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Enviando…",
"newKnowledge.usingDefaults": "Usando valores padrão",
"newKnowledge.viewLabel": "Visualização de conhecimento",
"newKnowledge.viewTask": "Ver tarefa",
"newKnowledge.websiteCrawl": "Rastreamento de site",
"noExternalKnowledge": "Ainda não existe uma API de conhecimento externo, clique aqui para criar",
"parentMode.fullDoc": "Documento completo",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Punct final",
"newKnowledge.authenticationMethod": "Metoda de autentificare",
"newKnowledge.averageChunkLength": "Lungimea medie a segmentului",
"newKnowledge.averageChunkLengthValue": "{{value}} caractere",
"newKnowledge.backToList": "Înapoi la bazele de cunoștințe",
"newKnowledge.backgroundTasks": "Sarcini de fundal",
"newKnowledge.backgroundTasksDescription": "Adăugări de documente, sincronizare sursă și reindexare lucrări.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Da",
"newKnowledge.bulkDocumentActions": "Acțiuni în bloc pentru documente",
"newKnowledge.cancelAddSource": "Anula",
"newKnowledge.cancelDocumentReindex": "Anulează reindexarea",
"newKnowledge.cardType": "Spațiu de cunoștințe",
"newKnowledge.characterCount": "Caractere",
"newKnowledge.checkReindexStatus": "Verifică starea reindexării",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Reindexarea a fost acceptată, dar starea activității întârzie. Verific-o înainte de a retrimite.",
"newKnowledge.documentReindexFailed": "Reindexarea a eșuat. Ultima revizie pregătită rămâne disponibilă.",
"newKnowledge.documentReindexProgress": "Se reindexează · {{progress}}%",
"newKnowledge.documentReindexStatus": "Acest document este reindexat — indexul curent rămâne disponibil până când cel nou este gata.",
"newKnowledge.documentRevision": "Revizie",
"newKnowledge.documentRevisionMissingDescription": "Acest document nu are încă o revizie pregătită. Revino după finalizarea procesării.",
"newKnowledge.documentRevisionMissingTitle": "Nicio revizie disponibilă",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Descoperă noua bază de cunoștințe ✨",
"newKnowledge.illustrationHeadline": "Conectează conținutul o singură dată — fiecare aplicație răspunde cu cele mai noi informații.",
"newKnowledge.includeSubpages": "Include subpaginile",
"newKnowledge.indexInformation": "Informații despre index",
"newKnowledge.indexInformation": "Index",
"newKnowledge.interruptTask": "Întrerupe",
"newKnowledge.invalidRootUrl": "Introdu o adresă URL http(s) validă.",
"newKnowledge.keepEditing": "Continuă editarea",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{count}} pagini explorate la {{host}}",
"newKnowledge.pagesCrawled_other": "{{count}} pagini explorate la {{host}}",
"newKnowledge.pagesSelected": "{{count}} selectate",
"newKnowledge.parentChildChunkCount": "{{parentCount}} părinte / {{childCount}} copil",
"newKnowledge.partialDocumentResults": "Este posibil să existe mai multe documente potrivite. Încarcă mai multe pentru a continua căutarea.",
"newKnowledge.permission": "Permisiune",
"newKnowledge.permissionAllMembers": "Spațiu de lucru · toți membrii pot vizualiza și edita",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Reindexați",
"newKnowledge.removeSource": "Eliminați sursa",
"newKnowledge.retrievalCount": "Număr de regăsiri",
"newKnowledge.retrievalCountValue": "{{value}} în ultimele 7 zile",
"newKnowledge.retrievalTest.analyzing": "Analizează dovezile",
"newKnowledge.retrievalTest.cancel": "Anulează",
"newKnowledge.retrievalTest.canceled": "Anulat",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Se încarcă…",
"newKnowledge.usingDefaults": "Se folosesc valorile implicite",
"newKnowledge.viewLabel": "Vizualizare cunoștințe",
"newKnowledge.viewTask": "Vezi sarcina",
"newKnowledge.websiteCrawl": "Accesare cu crawlere a site-ului",
"noExternalKnowledge": "Nu există încă un API de cunoștințe externe, faceți clic aici pentru a crea",
"parentMode.fullDoc": "Documentar complet",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Конечная точка",
"newKnowledge.authenticationMethod": "Метод аутентификации",
"newKnowledge.averageChunkLength": "Средняя длина фрагмента",
"newKnowledge.averageChunkLengthValue": "{{value}} символов",
"newKnowledge.backToList": "Вернуться к базам знаний",
"newKnowledge.backgroundTasks": "Фоновые задачи",
"newKnowledge.backgroundTasksDescription": "Добавление документов, синхронизация источников и переиндексация заданий.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Да",
"newKnowledge.bulkDocumentActions": "Массовые действия с документами",
"newKnowledge.cancelAddSource": "Отмена",
"newKnowledge.cancelDocumentReindex": "Отменить переиндексацию",
"newKnowledge.cardType": "Пространство знаний",
"newKnowledge.characterCount": "Символы",
"newKnowledge.checkReindexStatus": "Проверить статус переиндексации",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Переиндексация принята, но статус задачи задерживается. Проверьте его перед повторной отправкой.",
"newKnowledge.documentReindexFailed": "Переиндексация завершилась с ошибкой. Последняя готовая редакция остаётся доступной.",
"newKnowledge.documentReindexProgress": "Переиндексация · {{progress}}%",
"newKnowledge.documentReindexStatus": "Этот документ переиндексируется — текущий индекс останется доступен, пока новый не будет готов.",
"newKnowledge.documentRevision": "Редакция",
"newKnowledge.documentRevisionMissingDescription": "У этого документа пока нет готовой редакции. Проверьте снова после завершения обработки.",
"newKnowledge.documentRevisionMissingTitle": "Нет доступной редакции",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Познакомьтесь с новой базой знаний ✨",
"newKnowledge.illustrationHeadline": "Подключите контент один раз — и каждое приложение будет отвечать на основе самых свежих знаний.",
"newKnowledge.includeSubpages": "Включать вложенные страницы",
"newKnowledge.indexInformation": "Сведения об индексе",
"newKnowledge.indexInformation": "Индекс",
"newKnowledge.interruptTask": "Прерывание",
"newKnowledge.invalidRootUrl": "Введите корректный URL с http(s).",
"newKnowledge.keepEditing": "Продолжить редактирование",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "Просканировано страниц на {{host}}: {{count}}",
"newKnowledge.pagesCrawled_other": "Просканировано страниц на {{host}}: {{count}}",
"newKnowledge.pagesSelected": "Выбрано: {{count}}",
"newKnowledge.parentChildChunkCount": "{{parentCount}} родительских / {{childCount}} дочерних",
"newKnowledge.partialDocumentResults": "Подходящих документов может быть больше. Загрузите ещё, чтобы продолжить поиск.",
"newKnowledge.permission": "Разрешение",
"newKnowledge.permissionAllMembers": "Рабочая область · все участники могут просматривать и редактировать",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Переиндексация",
"newKnowledge.removeSource": "Удалить источник",
"newKnowledge.retrievalCount": "Количество извлечений",
"newKnowledge.retrievalCountValue": "{{value}} за последние 7 дней",
"newKnowledge.retrievalTest.analyzing": "Анализ доказательств",
"newKnowledge.retrievalTest.cancel": "Отмена",
"newKnowledge.retrievalTest.canceled": "Отменено",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Загрузка…",
"newKnowledge.usingDefaults": "Используются настройки по умолчанию",
"newKnowledge.viewLabel": "Вид базы знаний",
"newKnowledge.viewTask": "Просмотреть задачу",
"newKnowledge.websiteCrawl": "Сканирование веб-сайта",
"noExternalKnowledge": "У нас еще нет External Knowledge API, нажмите здесь, чтобы создать",
"parentMode.fullDoc": "Полный документ",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Končna točka",
"newKnowledge.authenticationMethod": "Metoda avtentikacije",
"newKnowledge.averageChunkLength": "Povprečna dolžina odseka",
"newKnowledge.averageChunkLengthValue": "{{value}} znakov",
"newKnowledge.backToList": "Nazaj k bazam znanja",
"newKnowledge.backgroundTasks": "Naloge v ozadju",
"newKnowledge.backgroundTasksDescription": "Dodajanje dokumentov, sinhronizacija virov in ponovno indeksiranje opravil.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Da",
"newKnowledge.bulkDocumentActions": "Dejanja množičnih dokumentov",
"newKnowledge.cancelAddSource": "Prekliči",
"newKnowledge.cancelDocumentReindex": "Prekliči ponovno indeksiranje",
"newKnowledge.cardType": "Prostor znanja",
"newKnowledge.characterCount": "Znaki",
"newKnowledge.checkReindexStatus": "Preveri stanje ponovnega indeksiranja",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Ponovno indeksiranje je bilo sprejeto, vendar stanje opravila zamuja. Preverite ga pred ponovno oddajo.",
"newKnowledge.documentReindexFailed": "Ponovno indeksiranje ni uspelo. Zadnja pripravljena različica ostaja na voljo.",
"newKnowledge.documentReindexProgress": "Ponovno indeksiranje · {{progress}}%",
"newKnowledge.documentReindexStatus": "Ta dokument se ponovno indeksira — trenutni indeks bo na voljo, dokler novi ne bo pripravljen.",
"newKnowledge.documentRevision": "Različica",
"newKnowledge.documentRevisionMissingDescription": "Ta dokument še nima pripravljene različice. Preverite po končani obdelavi.",
"newKnowledge.documentRevisionMissingTitle": "Ni razpoložljive različice",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Spoznajte novo bazo znanja ✨",
"newKnowledge.illustrationHeadline": "Vsebino povežite enkrat — vsaka aplikacija bo odgovarjala z najnovejšim znanjem.",
"newKnowledge.includeSubpages": "Vključi podstrani",
"newKnowledge.indexInformation": "Podatki o indeksu",
"newKnowledge.indexInformation": "Indeks",
"newKnowledge.interruptTask": "Prekini",
"newKnowledge.invalidRootUrl": "Vnesite veljaven URL http(s).",
"newKnowledge.keepEditing": "Nadaljuj urejanje",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "Preiskanih strani na {{host}}: {{count}}",
"newKnowledge.pagesCrawled_other": "Preiskanih strani na {{host}}: {{count}}",
"newKnowledge.pagesSelected": "Izbrano: {{count}}",
"newKnowledge.parentChildChunkCount": "{{parentCount}} nadrejenih / {{childCount}} podrejenih",
"newKnowledge.partialDocumentResults": "Morda se ujema več dokumentov. Naložite jih več za nadaljevanje iskanja.",
"newKnowledge.permission": "Dovoljenje",
"newKnowledge.permissionAllMembers": "Delovni prostor · vsi člani si lahko ogledujejo in urejajo",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Ponovno indeksiraj",
"newKnowledge.removeSource": "Odstrani vir",
"newKnowledge.retrievalCount": "Število pridobitev",
"newKnowledge.retrievalCountValue": "{{value}} v zadnjih 7 dneh",
"newKnowledge.retrievalTest.analyzing": "Analiziraj dokaze",
"newKnowledge.retrievalTest.cancel": "Prekliči",
"newKnowledge.retrievalTest.canceled": "Preklicano",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Nalaganje…",
"newKnowledge.usingDefaults": "Uporabljene so privzete nastavitve",
"newKnowledge.viewLabel": "Prikaz znanja",
"newKnowledge.viewTask": "Prikaži opravilo",
"newKnowledge.websiteCrawl": "Iskanje po vsebini spletne strani",
"noExternalKnowledge": "Zunanjega API-ja za znanje še ni, kliknite tukaj za ustvarjanje",
"parentMode.fullDoc": "Celoten dokument",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "จุดสิ้นสุด",
"newKnowledge.authenticationMethod": "วิธีการตรวจสอบความถูกต้อง",
"newKnowledge.averageChunkLength": "ความยาวส่วนข้อมูลเฉลี่ย",
"newKnowledge.averageChunkLengthValue": "{{value}} อักขระ",
"newKnowledge.backToList": "กลับสู่ฐานความรู้",
"newKnowledge.backgroundTasks": "งานเบื้องหลัง",
"newKnowledge.backgroundTasksDescription": "การเพิ่มเอกสาร การซิงค์แหล่งที่มา และงานจัดทำดัชนีใหม่",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "ใช่",
"newKnowledge.bulkDocumentActions": "การดำเนินการกับเอกสารจำนวนมาก",
"newKnowledge.cancelAddSource": "ยกเลิก",
"newKnowledge.cancelDocumentReindex": "ยกเลิกการทำดัชนีใหม่",
"newKnowledge.cardType": "พื้นที่ความรู้",
"newKnowledge.characterCount": "อักขระ",
"newKnowledge.checkReindexStatus": "ตรวจสอบสถานะการทำดัชนีใหม่",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "ระบบรับคำขอทำดัชนีใหม่แล้ว แต่สถานะงานล่าช้า โปรดตรวจสอบก่อนส่งอีกครั้ง",
"newKnowledge.documentReindexFailed": "การจัดทำดัชนีใหม่ล้มเหลว รุ่นแก้ไขล่าสุดที่พร้อมใช้งานยังคงอยู่",
"newKnowledge.documentReindexProgress": "กำลังจัดทำดัชนีใหม่ · {{progress}}%",
"newKnowledge.documentReindexStatus": "กำลังทำดัชนีเอกสารนี้ใหม่ — ดัชนีปัจจุบันจะยังใช้งานได้จนกว่าดัชนีใหม่จะพร้อม",
"newKnowledge.documentRevision": "รุ่นแก้ไข",
"newKnowledge.documentRevisionMissingDescription": "เอกสารนี้ยังไม่มีรุ่นแก้ไขที่พร้อม โปรดตรวจสอบอีกครั้งหลังประมวลผลเสร็จ",
"newKnowledge.documentRevisionMissingTitle": "ไม่มีรุ่นแก้ไขที่พร้อมใช้งาน",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "พบกับฐานความรู้แบบใหม่ ✨",
"newKnowledge.illustrationHeadline": "เชื่อมต่อเนื้อหาครั้งเดียว ทุกแอปจะตอบด้วยความรู้ล่าสุด",
"newKnowledge.includeSubpages": "รวมหน้าย่อย",
"newKnowledge.indexInformation": "ข้อมูลดัชนี",
"newKnowledge.indexInformation": "ดัชนี",
"newKnowledge.interruptTask": "ขัดจังหวะ",
"newKnowledge.invalidRootUrl": "ป้อน URL http(s) ที่ถูกต้อง",
"newKnowledge.keepEditing": "แก้ไขต่อ",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "รวบรวมข้อมูล {{count}} หน้าที่ {{host}}",
"newKnowledge.pagesCrawled_other": "รวบรวมข้อมูล {{count}} หน้าที่ {{host}}",
"newKnowledge.pagesSelected": "เลือกแล้ว {{count}} รายการ",
"newKnowledge.parentChildChunkCount": "{{parentCount}} รายการหลัก / {{childCount}} รายการย่อย",
"newKnowledge.partialDocumentResults": "อาจมีเอกสารที่ตรงกันเพิ่มเติม โหลดเพิ่มเพื่อค้นหาต่อ",
"newKnowledge.permission": "การอนุญาต",
"newKnowledge.permissionAllMembers": "พื้นที่ทำงาน · สมาชิกทุกคนสามารถดูและแก้ไขได้",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "จัดทำดัชนีใหม่",
"newKnowledge.removeSource": "ลบแหล่งสัญญาณ",
"newKnowledge.retrievalCount": "จำนวนการเรียกค้น",
"newKnowledge.retrievalCountValue": "{{value}} ครั้งในช่วง 7 วันที่ผ่านมา",
"newKnowledge.retrievalTest.analyzing": "วิเคราะห์หลักฐาน",
"newKnowledge.retrievalTest.cancel": "ยกเลิก",
"newKnowledge.retrievalTest.canceled": "ยกเลิกแล้ว",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "กำลังอัปโหลด…",
"newKnowledge.usingDefaults": "ใช้ค่าเริ่มต้น",
"newKnowledge.viewLabel": "มุมมองความรู้",
"newKnowledge.viewTask": "ดูงาน",
"newKnowledge.websiteCrawl": "การรวบรวมข้อมูลเว็บไซต์",
"noExternalKnowledge": "ยังไม่มี External Knowledge API คลิกที่นี่เพื่อสร้าง",
"parentMode.fullDoc": "เอกสารฉบับเต็ม",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Uç nokta",
"newKnowledge.authenticationMethod": "Kimlik doğrulama yöntemi",
"newKnowledge.averageChunkLength": "Ortalama parça uzunluğu",
"newKnowledge.averageChunkLengthValue": "{{value}} karakter",
"newKnowledge.backToList": "Bilgi tabanlarına geri dön",
"newKnowledge.backgroundTasks": "Arka plan görevleri",
"newKnowledge.backgroundTasksDescription": "Belge ekleme, kaynak senkronizasyonu ve işleri yeniden indeksleme.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Evet",
"newKnowledge.bulkDocumentActions": "Toplu belge işlemleri",
"newKnowledge.cancelAddSource": "İptal et",
"newKnowledge.cancelDocumentReindex": "Yeniden indekslemeyi iptal et",
"newKnowledge.cardType": "Bilgi alanı",
"newKnowledge.characterCount": "Karakterler",
"newKnowledge.checkReindexStatus": "Yeniden indeksleme durumunu kontrol et",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Yeniden indeksleme kabul edildi ancak görev durumu gecikiyor. Tekrar göndermeden önce kontrol edin.",
"newKnowledge.documentReindexFailed": "Yeniden dizinleme başarısız oldu. Son hazır revizyon kullanılabilir durumda.",
"newKnowledge.documentReindexProgress": "Yeniden dizinleniyor · %{{progress}}",
"newKnowledge.documentReindexStatus": "Bu belge yeniden indeksleniyor — yeni indeks hazır olana kadar mevcut indeks kullanılmaya devam eder.",
"newKnowledge.documentRevision": "Revizyon",
"newKnowledge.documentRevisionMissingDescription": "Bu belgenin henüz hazır bir revizyonu yok. İşlem tamamlandıktan sonra tekrar kontrol edin.",
"newKnowledge.documentRevisionMissingTitle": "Kullanılabilir revizyon yok",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Yeni Bilgi Tabanı ile tanışın ✨",
"newKnowledge.illustrationHeadline": "İçeriğinizi bir kez bağlayın — her uygulama en güncel bilgilerle yanıt versin.",
"newKnowledge.includeSubpages": "Alt sayfaları dahil et",
"newKnowledge.indexInformation": "Dizin bilgileri",
"newKnowledge.indexInformation": "Dizin",
"newKnowledge.interruptTask": "Kesinti",
"newKnowledge.invalidRootUrl": "Geçerli bir http(s) URLsi girin.",
"newKnowledge.keepEditing": "Düzenlemeye devam et",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "{{host}} üzerinde {{count}} sayfa tarandı",
"newKnowledge.pagesCrawled_other": "{{host}} üzerinde {{count}} sayfa tarandı",
"newKnowledge.pagesSelected": "{{count}} seçildi",
"newKnowledge.parentChildChunkCount": "{{parentCount}} üst / {{childCount}} alt",
"newKnowledge.partialDocumentResults": "Eşleşen başka belgeler olabilir. Aramaya devam etmek için daha fazla yükleyin.",
"newKnowledge.permission": "İzin",
"newKnowledge.permissionAllMembers": "Çalışma alanı · tüm üyeler görüntüleyebilir ve düzenleyebilir",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Yeniden indeksle",
"newKnowledge.removeSource": "Kaynağı kaldır",
"newKnowledge.retrievalCount": "Getirme sayısı",
"newKnowledge.retrievalCountValue": "Son 7 günde {{value}}",
"newKnowledge.retrievalTest.analyzing": "Kanıtları analiz et",
"newKnowledge.retrievalTest.cancel": "İptal",
"newKnowledge.retrievalTest.canceled": "İptal edildi",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Yükleniyor…",
"newKnowledge.usingDefaults": "Varsayılanlar kullanılıyor",
"newKnowledge.viewLabel": "Bilgi görünümü",
"newKnowledge.viewTask": "Görevi görüntüle",
"newKnowledge.websiteCrawl": "Web sitesi taraması",
"noExternalKnowledge": "Henüz Harici Bilgi API'si yok, oluşturmak için buraya tıklayın",
"parentMode.fullDoc": "Tam doküman",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Кінцева точка",
"newKnowledge.authenticationMethod": "Метод автентифікації",
"newKnowledge.averageChunkLength": "Середня довжина фрагмента",
"newKnowledge.averageChunkLengthValue": "{{value}} символів",
"newKnowledge.backToList": "Назад до баз знань",
"newKnowledge.backgroundTasks": "Фонові завдання",
"newKnowledge.backgroundTasksDescription": "Додавання документів, синхронізація джерела та повторне індексування завдань.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Так",
"newKnowledge.bulkDocumentActions": "Масові дії з документами",
"newKnowledge.cancelAddSource": "Скасувати",
"newKnowledge.cancelDocumentReindex": "Скасувати переіндексацію",
"newKnowledge.cardType": "Простір знань",
"newKnowledge.characterCount": "Символи",
"newKnowledge.checkReindexStatus": "Перевірити стан переіндексації",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Переіндексацію прийнято, але стан завдання затримується. Перевірте його перед повторним надсиланням.",
"newKnowledge.documentReindexFailed": "Повторне індексування завершилося помилкою. Остання готова редакція залишається доступною.",
"newKnowledge.documentReindexProgress": "Повторне індексування · {{progress}}%",
"newKnowledge.documentReindexStatus": "Цей документ переіндексовується — поточний індекс залишатиметься доступним, доки новий не буде готовий.",
"newKnowledge.documentRevision": "Редакція",
"newKnowledge.documentRevisionMissingDescription": "Цей документ ще не має готової редакції. Перевірте після завершення обробки.",
"newKnowledge.documentRevisionMissingTitle": "Немає доступної редакції",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Познайомтеся з новою базою знань ✨",
"newKnowledge.illustrationHeadline": "Підключіть вміст один раз — і кожна програма відповідатиме на основі найсвіжіших знань.",
"newKnowledge.includeSubpages": "Включати підсторінки",
"newKnowledge.indexInformation": "Відомості про індекс",
"newKnowledge.indexInformation": "Індекс",
"newKnowledge.interruptTask": "Переривати",
"newKnowledge.invalidRootUrl": "Введіть дійсну URL-адресу http(s).",
"newKnowledge.keepEditing": "Продовжити редагування",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "Проскановано сторінок на {{host}}: {{count}}",
"newKnowledge.pagesCrawled_other": "Проскановано сторінок на {{host}}: {{count}}",
"newKnowledge.pagesSelected": "Вибрано: {{count}}",
"newKnowledge.parentChildChunkCount": "{{parentCount}} батьківських / {{childCount}} дочірніх",
"newKnowledge.partialDocumentResults": "Може бути більше відповідних документів. Завантажте ще, щоб продовжити пошук.",
"newKnowledge.permission": "Дозвіл",
"newKnowledge.permissionAllMembers": "Робоча область · усі учасники можуть переглядати та редагувати",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Переіндексувати",
"newKnowledge.removeSource": "Видалити джерело",
"newKnowledge.retrievalCount": "Кількість отримань",
"newKnowledge.retrievalCountValue": "{{value}} за останні 7 днів",
"newKnowledge.retrievalTest.analyzing": "Аналіз доказів",
"newKnowledge.retrievalTest.cancel": "Скасувати",
"newKnowledge.retrievalTest.canceled": "Скасовано",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Завантаження…",
"newKnowledge.usingDefaults": "Використовуються стандартні налаштування",
"newKnowledge.viewLabel": "Вигляд бази знань",
"newKnowledge.viewTask": "Переглянути завдання",
"newKnowledge.websiteCrawl": "Сканування веб-сайту",
"noExternalKnowledge": "API зовнішніх знань поки що не існує, натисніть тут, щоб створити",
"parentMode.fullDoc": "Повний документ",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "Điểm cuối",
"newKnowledge.authenticationMethod": "Phương thức xác thực",
"newKnowledge.averageChunkLength": "Độ dài đoạn trung bình",
"newKnowledge.averageChunkLengthValue": "{{value}} ký tự",
"newKnowledge.backToList": "Quay lại cơ sở kiến thức",
"newKnowledge.backgroundTasks": "Tác vụ nền",
"newKnowledge.backgroundTasksDescription": "Tài liệu thêm, đồng bộ hóa nguồn và lập chỉ mục lại công việc.",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "Có",
"newKnowledge.bulkDocumentActions": "Hành động tài liệu hàng loạt",
"newKnowledge.cancelAddSource": "Hủy",
"newKnowledge.cancelDocumentReindex": "Hủy lập chỉ mục lại",
"newKnowledge.cardType": "Không gian kiến thức",
"newKnowledge.characterCount": "Ký tự",
"newKnowledge.checkReindexStatus": "Kiểm tra trạng thái lập chỉ mục lại",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "Yêu cầu lập chỉ mục lại đã được chấp nhận nhưng trạng thái tác vụ bị trễ. Hãy kiểm tra trước khi gửi lại.",
"newKnowledge.documentReindexFailed": "Lập chỉ mục lại thất bại. Bản sửa đổi sẵn sàng gần nhất vẫn khả dụng.",
"newKnowledge.documentReindexProgress": "Đang lập chỉ mục lại · {{progress}}%",
"newKnowledge.documentReindexStatus": "Tài liệu này đang được lập chỉ mục lại — chỉ mục hiện tại vẫn hoạt động cho đến khi chỉ mục mới sẵn sàng.",
"newKnowledge.documentRevision": "Bản sửa đổi",
"newKnowledge.documentRevisionMissingDescription": "Tài liệu này chưa có bản sửa đổi sẵn sàng. Hãy kiểm tra lại sau khi xử lý xong.",
"newKnowledge.documentRevisionMissingTitle": "Không có bản sửa đổi",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "Khám phá Cơ sở kiến thức mới ✨",
"newKnowledge.illustrationHeadline": "Kết nối nội dung một lần — mọi ứng dụng sẽ trả lời bằng kiến thức mới nhất.",
"newKnowledge.includeSubpages": "Bao gồm các trang con",
"newKnowledge.indexInformation": "Thông tin chỉ mục",
"newKnowledge.indexInformation": "Chỉ mục",
"newKnowledge.interruptTask": "Ngắt",
"newKnowledge.invalidRootUrl": "Nhập URL http(s) hợp lệ.",
"newKnowledge.keepEditing": "Tiếp tục chỉnh sửa",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "Đã thu thập {{count}} trang tại {{host}}",
"newKnowledge.pagesCrawled_other": "Đã thu thập {{count}} trang tại {{host}}",
"newKnowledge.pagesSelected": "Đã chọn {{count}}",
"newKnowledge.parentChildChunkCount": "{{parentCount}} cha / {{childCount}} con",
"newKnowledge.partialDocumentResults": "Có thể còn tài liệu phù hợp khác. Hãy tải thêm để tiếp tục tìm kiếm.",
"newKnowledge.permission": "Quyền",
"newKnowledge.permissionAllMembers": "Không gian làm việc · tất cả thành viên đều có thể xem và chỉnh sửa",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "Lập chỉ mục lại",
"newKnowledge.removeSource": "Xóa nguồn",
"newKnowledge.retrievalCount": "Số lần truy xuất",
"newKnowledge.retrievalCountValue": "{{value}} trong 7 ngày qua",
"newKnowledge.retrievalTest.analyzing": "Phân tích bằng chứng",
"newKnowledge.retrievalTest.cancel": "Hủy",
"newKnowledge.retrievalTest.canceled": "Đã hủy",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "Đang tải lên…",
"newKnowledge.usingDefaults": "Đang dùng giá trị mặc định",
"newKnowledge.viewLabel": "Chế độ xem kiến thức",
"newKnowledge.viewTask": "Xem tác vụ",
"newKnowledge.websiteCrawl": "Thu thập thông tin trang web",
"noExternalKnowledge": "Chưa có API Kiến thức Bên ngoài, hãy nhấp vào đây để tạo",
"parentMode.fullDoc": "Tài liệu đầy đủ",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "端点",
"newKnowledge.authenticationMethod": "认证方式",
"newKnowledge.averageChunkLength": "平均分段长度",
"newKnowledge.averageChunkLengthValue": "{{value}} 个字符",
"newKnowledge.backToList": "返回知识库列表",
"newKnowledge.backgroundTasks": "后台任务",
"newKnowledge.backgroundTasksDescription": "文档添加、数据源同步和重新索引任务。",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "是的",
"newKnowledge.bulkDocumentActions": "批量文档操作",
"newKnowledge.cancelAddSource": "取消",
"newKnowledge.cancelDocumentReindex": "取消重新索引",
"newKnowledge.cardType": "知识空间",
"newKnowledge.characterCount": "字符数",
"newKnowledge.checkReindexStatus": "检查重新索引状态",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "重新索引已受理,但任务状态同步延迟。再次提交前请先检查状态。",
"newKnowledge.documentReindexFailed": "重新索引失败,最后一个就绪的修订版本仍然可用。",
"newKnowledge.documentReindexProgress": "正在重新索引 · {{progress}}%",
"newKnowledge.documentReindexStatus": "正在重新索引此文档——新索引就绪前,当前索引会继续提供服务。",
"newKnowledge.documentRevision": "修订版本",
"newKnowledge.documentRevisionMissingDescription": "此文档还没有就绪的修订版本,请在处理完成后再查看。",
"newKnowledge.documentRevisionMissingTitle": "没有可用的修订版本",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "认识全新的知识库 ✨",
"newKnowledge.illustrationHeadline": "只需连接一次内容,每个应用都能基于最新知识回答。",
"newKnowledge.includeSubpages": "包含子页面",
"newKnowledge.indexInformation": "索引信息",
"newKnowledge.indexInformation": "索引",
"newKnowledge.interruptTask": "中断",
"newKnowledge.invalidRootUrl": "请输入有效的 http(s) URL。",
"newKnowledge.keepEditing": "继续编辑",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "已抓取 {{host}} 的 {{count}} 个页面",
"newKnowledge.pagesCrawled_other": "已抓取 {{host}} 的 {{count}} 个页面",
"newKnowledge.pagesSelected": "已选择 {{count}} 项",
"newKnowledge.parentChildChunkCount": "{{parentCount}} 个父分块 / {{childCount}} 个子分块",
"newKnowledge.partialDocumentResults": "可能还有匹配的文档。加载更多以继续搜索。",
"newKnowledge.permission": "权限",
"newKnowledge.permissionAllMembers": "工作区 · 所有成员均可查看和编辑",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "重新索引",
"newKnowledge.removeSource": "删除来源",
"newKnowledge.retrievalCount": "检索次数",
"newKnowledge.retrievalCountValue": "过去 7 天内 {{value}} 次",
"newKnowledge.retrievalTest.analyzing": "分析证据",
"newKnowledge.retrievalTest.cancel": "取消",
"newKnowledge.retrievalTest.canceled": "已取消",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "正在上传…",
"newKnowledge.usingDefaults": "使用默认设置",
"newKnowledge.viewLabel": "知识库视图",
"newKnowledge.viewTask": "查看任务",
"newKnowledge.websiteCrawl": "网站抓取",
"noExternalKnowledge": "还没有外部知识库 API点击此处创建",
"parentMode.fullDoc": "全文",

View File

@ -149,6 +149,7 @@
"newKnowledge.authKind.endpoint": "端點",
"newKnowledge.authenticationMethod": "認證方式",
"newKnowledge.averageChunkLength": "平均分段長度",
"newKnowledge.averageChunkLengthValue": "{{value}} 個字元",
"newKnowledge.backToList": "返回知識庫列表",
"newKnowledge.backgroundTasks": "背景任務",
"newKnowledge.backgroundTasksDescription": "文件新增、資料來源同步和重新索引任務。",
@ -156,6 +157,7 @@
"newKnowledge.booleanTrue": "是的",
"newKnowledge.bulkDocumentActions": "批次文件操作",
"newKnowledge.cancelAddSource": "取消",
"newKnowledge.cancelDocumentReindex": "取消重新索引",
"newKnowledge.cardType": "知識空間",
"newKnowledge.characterCount": "字元數",
"newKnowledge.checkReindexStatus": "檢查重新索引狀態",
@ -234,6 +236,7 @@
"newKnowledge.documentReindexConfirmationDelayed": "重新索引已受理,但任務狀態同步延遲。再次提交前請先檢查狀態。",
"newKnowledge.documentReindexFailed": "重新建立索引失敗,最後一個就緒的修訂版本仍然可用。",
"newKnowledge.documentReindexProgress": "正在重新建立索引 · {{progress}}%",
"newKnowledge.documentReindexStatus": "正在重新索引此文件——新索引就緒前,目前索引會繼續提供服務。",
"newKnowledge.documentRevision": "修訂版本",
"newKnowledge.documentRevisionMissingDescription": "此文件尚未有就緒的修訂版本,請在處理完成後再查看。",
"newKnowledge.documentRevisionMissingTitle": "沒有可用的修訂版本",
@ -287,7 +290,7 @@
"newKnowledge.guideTitle": "認識全新的知識庫 ✨",
"newKnowledge.illustrationHeadline": "只需連接一次內容,每個應用程式都能以最新知識回答。",
"newKnowledge.includeSubpages": "包含子頁面",
"newKnowledge.indexInformation": "索引資訊",
"newKnowledge.indexInformation": "索引",
"newKnowledge.interruptTask": "中斷",
"newKnowledge.invalidRootUrl": "請輸入有效的 http(s) URL。",
"newKnowledge.keepEditing": "繼續編輯",
@ -413,6 +416,7 @@
"newKnowledge.pagesCrawled_one": "已抓取 {{host}} 的 {{count}} 個頁面",
"newKnowledge.pagesCrawled_other": "已抓取 {{host}} 的 {{count}} 個頁面",
"newKnowledge.pagesSelected": "已選取 {{count}} 項",
"newKnowledge.parentChildChunkCount": "{{parentCount}} 個父分段 / {{childCount}} 個子分段",
"newKnowledge.partialDocumentResults": "可能還有符合的文件。載入更多以繼續搜尋。",
"newKnowledge.permission": "權限",
"newKnowledge.permissionAllMembers": "工作區 · 所有成員皆可檢視和編輯",
@ -498,6 +502,7 @@
"newKnowledge.reindexDocuments": "重新索引",
"newKnowledge.removeSource": "刪除來源",
"newKnowledge.retrievalCount": "檢索次數",
"newKnowledge.retrievalCountValue": "過去 7 天內 {{value}} 次",
"newKnowledge.retrievalTest.analyzing": "分析證據",
"newKnowledge.retrievalTest.cancel": "取消",
"newKnowledge.retrievalTest.canceled": "已取消",
@ -652,6 +657,7 @@
"newKnowledge.uploadingFiles": "正在上傳…",
"newKnowledge.usingDefaults": "使用預設設定",
"newKnowledge.viewLabel": "知識庫檢視",
"newKnowledge.viewTask": "查看任務",
"newKnowledge.websiteCrawl": "網站抓取",
"noExternalKnowledge": "目前還沒有外部知識 API按兩下此處創建",
"parentMode.fullDoc": "完整文件",