mirror of
https://github.com/langgenius/dify.git
synced 2026-07-25 21:48:30 +08:00
feat(dataset): add website crawl preview (#39324)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
922ed4d67d
commit
ba5b26be03
@ -2,7 +2,7 @@ import type {
|
||||
GetKnowledgeSpacesByIdSourceConnectionsResponse,
|
||||
GetSourceProvidersResponse,
|
||||
} from '@dify/contracts/knowledge-fs/types.gen'
|
||||
import { screen, waitFor } from '@testing-library/react'
|
||||
import { act, screen, waitFor, within } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { render } from '@/test/console/render'
|
||||
import { AddSourcePage } from '../add-source-page'
|
||||
@ -45,11 +45,22 @@ const queryState = vi.hoisted(() => ({
|
||||
}))
|
||||
|
||||
const clientMock = vi.hoisted(() => ({
|
||||
cancelRun: vi.fn(),
|
||||
createConnection: vi.fn(),
|
||||
createSource: vi.fn(),
|
||||
deleteConnection: vi.fn(),
|
||||
deleteSource: vi.fn(),
|
||||
getPages: vi.fn(),
|
||||
getRun: vi.fn(),
|
||||
getSource: vi.fn(),
|
||||
listSources: vi.fn(),
|
||||
refreshConnection: vi.fn(),
|
||||
retryRun: vi.fn(),
|
||||
startPreview: vi.fn(),
|
||||
}))
|
||||
|
||||
const routerMock = vi.hoisted(() => ({ replace: vi.fn() }))
|
||||
|
||||
const queryClientMock = vi.hoisted(() => ({
|
||||
invalidateQueries: vi.fn(),
|
||||
}))
|
||||
@ -73,8 +84,17 @@ vi.mock('@/service/client', () => ({
|
||||
consoleClient: {
|
||||
knowledgeFs: {
|
||||
deleteKnowledgeSpacesByIdSourceConnectionsByConnectionId: clientMock.deleteConnection,
|
||||
deleteKnowledgeSpacesByIdSourcesBySourceId: clientMock.deleteSource,
|
||||
getKnowledgeSpacesByIdSources: clientMock.listSources,
|
||||
getKnowledgeSpacesByIdSourcesBySourceId: clientMock.getSource,
|
||||
getKnowledgeSpacesByIdSourceWorkflowsByRunId: clientMock.getRun,
|
||||
getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages: clientMock.getPages,
|
||||
postKnowledgeSpacesByIdSourceConnections: clientMock.createConnection,
|
||||
postKnowledgeSpacesByIdSourceConnectionsByConnectionIdRefresh: clientMock.refreshConnection,
|
||||
postKnowledgeSpacesByIdSources: clientMock.createSource,
|
||||
postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview: clientMock.startPreview,
|
||||
postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel: clientMock.cancelRun,
|
||||
postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry: clientMock.retryRun,
|
||||
},
|
||||
},
|
||||
consoleQuery: {
|
||||
@ -90,6 +110,10 @@ vi.mock('@/service/client', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/next/navigation', () => ({
|
||||
useRouter: () => routerMock,
|
||||
}))
|
||||
|
||||
const firecrawlProvider: GetSourceProvidersResponse['items'][number] = {
|
||||
authKinds: ['api-key', 'endpoint'],
|
||||
available: true,
|
||||
@ -186,12 +210,48 @@ const connection = (
|
||||
...overrides,
|
||||
})
|
||||
|
||||
const provisionalSource = {
|
||||
connectionId: 'connection-1',
|
||||
createdAt: '2026-07-20T10:00:00Z',
|
||||
id: 'source-1',
|
||||
knowledgeSpaceId: 'space-1',
|
||||
metadata: { preview: true },
|
||||
name: 'Dify docs',
|
||||
status: 'disabled' as const,
|
||||
type: 'web' as const,
|
||||
updatedAt: '2026-07-20T10:00:00Z',
|
||||
uri: 'https://docs.dify.ai/',
|
||||
version: 1,
|
||||
}
|
||||
|
||||
const previewRun = {
|
||||
checkpoint: 'queued',
|
||||
createdAt: '2026-07-20T10:00:00Z',
|
||||
executionAttempts: 1,
|
||||
id: 'run-1',
|
||||
knowledgeSpaceId: 'space-1',
|
||||
kind: 'crawl-preview',
|
||||
maxExecutionAttempts: 3,
|
||||
progressCompleted: 0,
|
||||
progressFailed: 0,
|
||||
progressSkipped: 0,
|
||||
sourceId: 'source-1',
|
||||
state: 'running',
|
||||
updatedAt: '2026-07-20T10:00:00Z',
|
||||
}
|
||||
|
||||
function deferred<T>() {
|
||||
let resolve!: (value: T) => void
|
||||
const promise = new Promise<T>((nextResolve) => {
|
||||
resolve = nextResolve
|
||||
})
|
||||
return { promise, resolve }
|
||||
}
|
||||
|
||||
describe('AddSourcePage', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
clientMock.createConnection.mockReset()
|
||||
clientMock.deleteConnection.mockReset()
|
||||
clientMock.refreshConnection.mockReset()
|
||||
for (const mock of Object.values(clientMock)) mock.mockReset()
|
||||
queryState.connections.refetch.mockReset()
|
||||
queryState.providers.refetch.mockReset()
|
||||
queryState.providers.data = { items: [firecrawlProvider, jinaProvider] }
|
||||
@ -203,6 +263,13 @@ describe('AddSourcePage', () => {
|
||||
queryState.connections.isFetchNextPageError = false
|
||||
queryState.connections.isFetchingNextPage = false
|
||||
queryState.connections.isPending = false
|
||||
clientMock.createSource.mockResolvedValue(provisionalSource)
|
||||
clientMock.deleteSource.mockResolvedValue({ id: 'deletion-1' })
|
||||
clientMock.getPages.mockResolvedValue({ items: [] })
|
||||
clientMock.getRun.mockResolvedValue({ ...previewRun, state: 'preview_ready' })
|
||||
clientMock.getSource.mockResolvedValue(provisionalSource)
|
||||
clientMock.listSources.mockResolvedValue({ items: [] })
|
||||
clientMock.startPreview.mockResolvedValue(previewRun)
|
||||
})
|
||||
|
||||
it('loads the provider catalog and every scoped connection cursor page', () => {
|
||||
@ -254,13 +321,10 @@ describe('AddSourcePage', () => {
|
||||
|
||||
expect(screen.getByText(/dataset\.newKnowledge\.providerConnected/)).toBeInTheDocument()
|
||||
expect(screen.getByRole('radio', { name: 'Firecrawl' })).toBeChecked()
|
||||
expect(screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ })).toBeEnabled()
|
||||
expect(
|
||||
screen.getByText('dataset.newKnowledge.crawlSetupUnavailableDescription'),
|
||||
).toBeInTheDocument()
|
||||
expect(screen.queryByRole('textbox')).not.toBeInTheDocument()
|
||||
expect(
|
||||
screen.queryByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }),
|
||||
).not.toBeInTheDocument()
|
||||
screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }),
|
||||
).toBeEnabled()
|
||||
})
|
||||
|
||||
it('creates the exact Firecrawl provider connection without leaking credentials', async () => {
|
||||
@ -760,6 +824,265 @@ describe('AddSourcePage', () => {
|
||||
expect(toastInfoMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('asks before discarding an edited source draft', async () => {
|
||||
const user = userEvent.setup()
|
||||
queryState.connections.data = { pages: [{ items: [connection('active')] }] }
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' }))
|
||||
|
||||
const dialog = await screen.findByRole('alertdialog', {
|
||||
name: 'dataset.newKnowledge.discardSourceDraftTitle',
|
||||
})
|
||||
expect(dialog).toHaveTextContent('dataset.newKnowledge.discardSourceDraftDescription')
|
||||
await user.click(within(dialog).getByRole('button', { name: 'common.operation.cancel' }))
|
||||
expect(routerMock.replace).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('asks before discarding provider connection credentials', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /dataset\.newKnowledge\.configureProvider/ }),
|
||||
)
|
||||
await user.type(screen.getByLabelText(/Api Key/), 'unsaved-secret')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' }))
|
||||
|
||||
expect(
|
||||
await screen.findByRole('alertdialog', {
|
||||
name: 'dataset.newKnowledge.discardSourceDraftTitle',
|
||||
}),
|
||||
).toBeInTheDocument()
|
||||
expect(routerMock.replace).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('guards client-side marketplace navigation while the source draft is dirty', async () => {
|
||||
const user = userEvent.setup()
|
||||
const historyBack = vi.spyOn(window.history, 'back').mockImplementation(() => undefined)
|
||||
queryState.connections.data = { pages: [{ items: [connection('active')] }] }
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
await user.click(screen.getByRole('link', { name: /dataset\.newKnowledge\.moreProviders/ }))
|
||||
|
||||
const dialog = await screen.findByRole('alertdialog', {
|
||||
name: 'dataset.newKnowledge.discardSourceDraftTitle',
|
||||
})
|
||||
expect(routerMock.replace).not.toHaveBeenCalled()
|
||||
await user.click(
|
||||
within(dialog).getByRole('button', { name: 'dataset.newKnowledge.discardDraftConfirm' }),
|
||||
)
|
||||
await waitFor(() => expect(historyBack).toHaveBeenCalledOnce())
|
||||
|
||||
act(() => window.dispatchEvent(new PopStateEvent('popstate')))
|
||||
expect(routerMock.replace).toHaveBeenCalledWith('/marketplace?category=datasource')
|
||||
})
|
||||
|
||||
it('guards client-side navigation from links outside the add source form', async () => {
|
||||
const user = userEvent.setup()
|
||||
queryState.connections.data = { pages: [{ items: [connection('active')] }] }
|
||||
|
||||
render(
|
||||
<>
|
||||
<a href="/datasets/space-1/documents">Documents</a>
|
||||
<AddSourcePage knowledgeSpaceId="space-1" />
|
||||
</>,
|
||||
)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
await user.click(screen.getByRole('link', { name: 'Documents' }))
|
||||
|
||||
expect(
|
||||
await screen.findByRole('alertdialog', {
|
||||
name: 'dataset.newKnowledge.discardSourceDraftTitle',
|
||||
}),
|
||||
).toBeInTheDocument()
|
||||
expect(routerMock.replace).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('waits for source creation before deleting the provisional source on discard', async () => {
|
||||
const user = userEvent.setup()
|
||||
const sourceRequest = deferred<typeof provisionalSource>()
|
||||
queryState.connections.data = { pages: [{ items: [connection('active')] }] }
|
||||
clientMock.createSource.mockReturnValue(sourceRequest.promise)
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.sourceName/ }),
|
||||
'Dify docs',
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await waitFor(() => expect(clientMock.createSource).toHaveBeenCalledOnce())
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' }))
|
||||
const dialog = await screen.findByRole('alertdialog', {
|
||||
name: 'dataset.newKnowledge.discardSourceDraftTitle',
|
||||
})
|
||||
await user.click(
|
||||
within(dialog).getByRole('button', { name: 'dataset.newKnowledge.discardDraftConfirm' }),
|
||||
)
|
||||
expect(clientMock.deleteSource).not.toHaveBeenCalled()
|
||||
|
||||
await act(async () => sourceRequest.resolve(provisionalSource))
|
||||
|
||||
await waitFor(() => expect(clientMock.deleteSource).toHaveBeenCalledOnce())
|
||||
})
|
||||
|
||||
it('starts with a fresh preview draft after switching active providers', async () => {
|
||||
const user = userEvent.setup()
|
||||
const jinaConnection = connection('active', 2, {
|
||||
configuration: { provider: 'jina' },
|
||||
id: 'jina-connection',
|
||||
name: 'Jina Reader',
|
||||
providerId: 'jina-reader',
|
||||
})
|
||||
const jinaSource = {
|
||||
...provisionalSource,
|
||||
connectionId: jinaConnection.id,
|
||||
id: 'source-2',
|
||||
}
|
||||
queryState.connections.data = {
|
||||
pages: [{ items: [connection('active'), jinaConnection] }],
|
||||
}
|
||||
clientMock.createSource
|
||||
.mockResolvedValueOnce(provisionalSource)
|
||||
.mockResolvedValueOnce(jinaSource)
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.sourceName/ }),
|
||||
'Dify docs',
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByText(/^dataset\.newKnowledge\.noPagesFound:/)
|
||||
|
||||
await user.click(screen.getByRole('radio', { name: 'Jina Reader' }))
|
||||
|
||||
expect(screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ })).toHaveValue('')
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://jina.ai',
|
||||
)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.sourceName/ }),
|
||||
'Jina docs',
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.createSource).toHaveBeenCalledTimes(2))
|
||||
expect(clientMock.createSource.mock.calls[1]?.[0].body.connectionId).toBe('jina-connection')
|
||||
})
|
||||
|
||||
it('reconciles a response-lost provisional source deletion before leaving', async () => {
|
||||
const user = userEvent.setup()
|
||||
const historyBack = vi.spyOn(window.history, 'back').mockImplementation(() => undefined)
|
||||
queryState.connections.data = { pages: [{ items: [connection('active')] }] }
|
||||
clientMock.deleteSource.mockRejectedValue(new Error('response lost'))
|
||||
clientMock.getSource.mockRejectedValue(
|
||||
Object.assign(new Error('source not found'), { status: 404 }),
|
||||
)
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.sourceName/ }),
|
||||
'Dify docs',
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await waitFor(() => expect(clientMock.createSource).toHaveBeenCalledOnce())
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' }))
|
||||
const dialog = await screen.findByRole('alertdialog', {
|
||||
name: 'dataset.newKnowledge.discardSourceDraftTitle',
|
||||
})
|
||||
await user.click(
|
||||
within(dialog).getByRole('button', { name: 'dataset.newKnowledge.discardDraftConfirm' }),
|
||||
)
|
||||
|
||||
await waitFor(() =>
|
||||
expect(clientMock.deleteSource).toHaveBeenCalledWith({
|
||||
body: { expectedRevision: 1 },
|
||||
headers: { 'idempotency-key': expect.any(String) },
|
||||
params: { id: 'space-1', sourceId: 'source-1' },
|
||||
query: { documents: 'cascade' },
|
||||
}),
|
||||
)
|
||||
expect(clientMock.getSource).toHaveBeenCalledWith({
|
||||
params: { id: 'space-1', sourceId: 'source-1' },
|
||||
})
|
||||
expect(historyBack).toHaveBeenCalledOnce()
|
||||
act(() => window.dispatchEvent(new PopStateEvent('popstate')))
|
||||
expect(routerMock.replace).toHaveBeenCalledWith('/datasets/new/space-1/sources')
|
||||
})
|
||||
|
||||
it('protects an edited source draft from browser unload', async () => {
|
||||
const user = userEvent.setup()
|
||||
queryState.connections.data = { pages: [{ items: [connection('active')] }] }
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
const event = new Event('beforeunload', { cancelable: true })
|
||||
|
||||
act(() => window.dispatchEvent(event))
|
||||
|
||||
expect(event.defaultPrevented).toBe(true)
|
||||
})
|
||||
|
||||
it('deletes a known provisional source with keepalive when the page unloads', async () => {
|
||||
const user = userEvent.setup()
|
||||
queryState.connections.data = { pages: [{ items: [connection('active')] }] }
|
||||
|
||||
render(<AddSourcePage knowledgeSpaceId="space-1" />)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }),
|
||||
'https://docs.dify.ai',
|
||||
)
|
||||
await user.type(
|
||||
screen.getByRole('textbox', { name: /dataset\.newKnowledge\.sourceName/ }),
|
||||
'Dify docs',
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await waitFor(() => expect(clientMock.createSource).toHaveBeenCalledOnce())
|
||||
|
||||
act(() => window.dispatchEvent(new Event('pagehide')))
|
||||
|
||||
await waitFor(() =>
|
||||
expect(clientMock.deleteSource).toHaveBeenCalledWith(
|
||||
{
|
||||
body: { expectedRevision: 1 },
|
||||
headers: { 'idempotency-key': expect.any(String) },
|
||||
params: { id: 'space-1', sourceId: 'source-1' },
|
||||
query: { documents: 'cascade' },
|
||||
},
|
||||
{ context: { keepalive: true, silent: true } },
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
it('shows catalog unavailability instead of offering a fake connection', () => {
|
||||
queryState.providers.data = {
|
||||
items: [{ ...firecrawlProvider, available: false, unavailableReason: 'Disabled by admin' }],
|
||||
|
||||
877
web/features/new-rag/__tests__/website-crawl-preview.spec.tsx
Normal file
877
web/features/new-rag/__tests__/website-crawl-preview.spec.tsx
Normal file
@ -0,0 +1,877 @@
|
||||
import type { Source, SourceWorkflowRun } from '@dify/contracts/knowledge-fs/types.gen'
|
||||
import { act, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { render } from '@/test/console/render'
|
||||
import { WebsiteCrawlPreview } from '../website-crawl-preview'
|
||||
|
||||
const clientMock = vi.hoisted(() => ({
|
||||
cancel: vi.fn(),
|
||||
createSource: vi.fn(),
|
||||
getPages: vi.fn(),
|
||||
getRun: vi.fn(),
|
||||
listSources: vi.fn(),
|
||||
retry: vi.fn(),
|
||||
startPreview: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/service/client', () => ({
|
||||
consoleClient: {
|
||||
knowledgeFs: {
|
||||
getKnowledgeSpacesByIdSources: clientMock.listSources,
|
||||
getKnowledgeSpacesByIdSourceWorkflowsByRunId: clientMock.getRun,
|
||||
getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages: clientMock.getPages,
|
||||
postKnowledgeSpacesByIdSources: clientMock.createSource,
|
||||
postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview: clientMock.startPreview,
|
||||
postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel: clientMock.cancel,
|
||||
postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry: clientMock.retry,
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
const connection = {
|
||||
id: 'connection-1',
|
||||
providerId: 'plugin-daemon-website',
|
||||
}
|
||||
|
||||
const source = (metadata: Source['metadata'] = {}): Source => ({
|
||||
connectionId: connection.id,
|
||||
createdAt: '2026-07-20T10:00:00Z',
|
||||
id: 'source-1',
|
||||
knowledgeSpaceId: 'space-1',
|
||||
metadata,
|
||||
name: 'Dify docs',
|
||||
status: 'disabled',
|
||||
type: 'web',
|
||||
updatedAt: '2026-07-20T10:00:00Z',
|
||||
uri: 'https://docs.dify.ai/',
|
||||
})
|
||||
|
||||
const run = (state: string, overrides: Partial<SourceWorkflowRun> = {}): SourceWorkflowRun => ({
|
||||
checkpoint: 'crawl',
|
||||
createdAt: '2026-07-20T10:00:00Z',
|
||||
executionAttempts: 1,
|
||||
id: 'run-1',
|
||||
knowledgeSpaceId: 'space-1',
|
||||
kind: 'crawl-preview',
|
||||
maxExecutionAttempts: 3,
|
||||
progressCompleted: 0,
|
||||
progressFailed: 0,
|
||||
progressSkipped: 0,
|
||||
sourceId: 'source-1',
|
||||
state,
|
||||
updatedAt: '2026-07-20T10:00:00Z',
|
||||
...overrides,
|
||||
})
|
||||
|
||||
async function fillValidForm() {
|
||||
const user = userEvent.setup()
|
||||
await user.type(screen.getByLabelText(/^dataset\.newKnowledge\.rootUrl/), 'https://docs.dify.ai')
|
||||
await user.type(screen.getByLabelText(/^dataset\.newKnowledge\.sourceName/), 'Dify docs')
|
||||
return user
|
||||
}
|
||||
|
||||
function deferred<T>() {
|
||||
let resolve!: (value: T) => void
|
||||
const promise = new Promise<T>((nextResolve) => {
|
||||
resolve = nextResolve
|
||||
})
|
||||
return { promise, resolve }
|
||||
}
|
||||
|
||||
describe('WebsiteCrawlPreview', () => {
|
||||
beforeEach(() => {
|
||||
vi.useRealTimers()
|
||||
for (const mock of Object.values(clientMock)) mock.mockReset()
|
||||
clientMock.createSource.mockResolvedValue(source())
|
||||
clientMock.startPreview.mockResolvedValue(run('running'))
|
||||
clientMock.getRun.mockResolvedValue(
|
||||
run('preview_ready', {
|
||||
checkpoint: 'preview-staged',
|
||||
progressCompleted: 1,
|
||||
progressTotal: 1,
|
||||
}),
|
||||
)
|
||||
clientMock.getPages.mockResolvedValue({
|
||||
items: [
|
||||
{
|
||||
pageId: 'page-1',
|
||||
sourceUrl: 'https://docs.dify.ai/getting-started',
|
||||
title: 'Getting started',
|
||||
},
|
||||
],
|
||||
})
|
||||
clientMock.listSources.mockResolvedValue({ items: [] })
|
||||
})
|
||||
|
||||
afterEach(() => vi.useRealTimers())
|
||||
|
||||
it('validates the URL and starts a real crawl preview with a provisional source', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
|
||||
const start = screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' })
|
||||
const rootUrl = screen.getByLabelText(/^dataset\.newKnowledge\.rootUrl/)
|
||||
expect(start).toBeEnabled()
|
||||
await user.click(start)
|
||||
expect(rootUrl).toHaveFocus()
|
||||
expect(rootUrl).toHaveAttribute('aria-invalid', 'true')
|
||||
await user.type(rootUrl, 'ftp://docs.dify.ai')
|
||||
await user.tab()
|
||||
expect(rootUrl).toHaveAttribute('aria-invalid', 'true')
|
||||
await user.clear(rootUrl)
|
||||
await user.type(rootUrl, 'https://docs.dify.ai')
|
||||
await user.type(screen.getByLabelText(/^dataset\.newKnowledge\.sourceName/), 'Dify docs')
|
||||
await user.click(start)
|
||||
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce())
|
||||
expect(clientMock.createSource).toHaveBeenCalledWith({
|
||||
body: {
|
||||
connectionId: 'connection-1',
|
||||
metadata: {
|
||||
clientRequestId: expect.any(String),
|
||||
crawlOptions: { includeSubpages: true, limit: 100 },
|
||||
preview: true,
|
||||
providerId: 'plugin-daemon-website',
|
||||
},
|
||||
name: 'Dify docs',
|
||||
status: 'disabled',
|
||||
type: 'web',
|
||||
uri: 'https://docs.dify.ai/',
|
||||
},
|
||||
params: { id: 'space-1' },
|
||||
})
|
||||
expect(clientMock.startPreview).toHaveBeenCalledWith({
|
||||
headers: { 'Idempotency-Key': expect.any(String) },
|
||||
params: { id: 'space-1', sourceId: 'source-1' },
|
||||
})
|
||||
expect(await screen.findByText('Getting started')).toBeInTheDocument()
|
||||
expect(screen.getByText(/^dataset\.newKnowledge\.pagesCrawled/)).toHaveAttribute(
|
||||
'role',
|
||||
'status',
|
||||
)
|
||||
expect(screen.getByRole('button', { name: 'dataset.newKnowledge.reCrawl' })).toBeInTheDocument()
|
||||
expect(
|
||||
screen.queryByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }),
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('uses the shared form controls with stable field names and autocomplete metadata', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByLabelText(/^dataset\.newKnowledge\.rootUrl/)).toHaveAttribute(
|
||||
'name',
|
||||
'root-url',
|
||||
)
|
||||
expect(screen.getByLabelText(/^dataset\.newKnowledge\.rootUrl/)).toHaveAttribute(
|
||||
'autocomplete',
|
||||
'off',
|
||||
)
|
||||
expect(screen.getByLabelText(/^dataset\.newKnowledge\.sourceName/)).toHaveAttribute(
|
||||
'name',
|
||||
'source-name',
|
||||
)
|
||||
expect(screen.getByLabelText(/^dataset\.newKnowledge\.sourceName/)).toHaveAttribute(
|
||||
'autocomplete',
|
||||
'off',
|
||||
)
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /dataset\.newKnowledge\.crawlOptions/ }))
|
||||
|
||||
expect(
|
||||
screen.getByRole('checkbox', { name: 'dataset.newKnowledge.includeSubpages' }),
|
||||
).toBeInTheDocument()
|
||||
expect(document.querySelector('input[name="include-subpages"]')).toBeInTheDocument()
|
||||
expect(screen.getByRole('textbox', { name: 'dataset.newKnowledge.maxPages' })).toHaveAttribute(
|
||||
'name',
|
||||
'page-limit',
|
||||
)
|
||||
})
|
||||
|
||||
it('only labels collapsed crawl options as defaults when they are unchanged', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByText('dataset.newKnowledge.usingDefaults')).toBeInTheDocument()
|
||||
await user.click(screen.getByRole('button', { name: /dataset\.newKnowledge\.crawlOptions/ }))
|
||||
await user.click(screen.getByRole('checkbox', { name: 'dataset.newKnowledge.includeSubpages' }))
|
||||
await user.click(screen.getByRole('button', { name: /dataset\.newKnowledge\.crawlOptions/ }))
|
||||
|
||||
expect(screen.queryByText('dataset.newKnowledge.usingDefaults')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('keeps completed results associated with the submitted URL while the draft is edited', async () => {
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByText('Getting started')
|
||||
|
||||
const rootUrl = screen.getByLabelText(/^dataset\.newKnowledge\.rootUrl/)
|
||||
await user.clear(rootUrl)
|
||||
await user.type(rootUrl, 'https://example.com')
|
||||
|
||||
const completedStatus = screen.getByText(/^dataset\.newKnowledge\.pagesCrawled/)
|
||||
expect(completedStatus).toHaveTextContent('docs.dify.ai')
|
||||
expect(completedStatus).not.toHaveTextContent('example.com')
|
||||
})
|
||||
|
||||
it('submits the crawl form with Enter and enforces the source name contract limit', async () => {
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
const name = screen.getByLabelText(/^dataset\.newKnowledge\.sourceName/)
|
||||
expect(name).toHaveAttribute('maxlength', '200')
|
||||
await user.clear(name)
|
||||
await user.type(name, 'x'.repeat(201))
|
||||
expect(name).toHaveValue('x'.repeat(200))
|
||||
await user.type(name, '{enter}')
|
||||
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce())
|
||||
})
|
||||
|
||||
it('shows pending feedback while a completed crawl is being restarted', async () => {
|
||||
const restartRequest = deferred<SourceWorkflowRun>()
|
||||
clientMock.startPreview
|
||||
.mockResolvedValueOnce(run('running'))
|
||||
.mockReturnValueOnce(restartRequest.promise)
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
const reCrawl = await screen.findByRole('button', { name: 'dataset.newKnowledge.reCrawl' })
|
||||
await user.click(reCrawl)
|
||||
|
||||
expect(screen.getByRole('button', { name: 'dataset.newKnowledge.crawling' })).toHaveAttribute(
|
||||
'aria-disabled',
|
||||
'true',
|
||||
)
|
||||
await act(async () =>
|
||||
restartRequest.resolve(
|
||||
run('running', {
|
||||
id: 'run-2',
|
||||
updatedAt: '2026-07-20T10:01:00Z',
|
||||
}),
|
||||
),
|
||||
)
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledTimes(2))
|
||||
const firstKey = clientMock.startPreview.mock.calls[0]?.[0].headers['Idempotency-Key']
|
||||
const secondKey = clientMock.startPreview.mock.calls[1]?.[0].headers['Idempotency-Key']
|
||||
expect(secondKey).not.toBe(firstKey)
|
||||
expect(clientMock.createSource).toHaveBeenCalledOnce()
|
||||
expect(clientMock.retry).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('streams page cursors while running and replaces them with the final snapshot', async () => {
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true })
|
||||
clientMock.getRun
|
||||
.mockResolvedValueOnce(run('running', { progressCompleted: 2, progressTotal: 4 }))
|
||||
.mockResolvedValueOnce(run('succeeded', { progressCompleted: 4, progressTotal: 4 }))
|
||||
clientMock.getPages
|
||||
.mockResolvedValueOnce({
|
||||
items: [{ pageId: 'page-1', sourceUrl: 'https://docs.dify.ai/one', title: 'Old one' }],
|
||||
nextCursor: 'page-2',
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
items: [
|
||||
{ pageId: 'page-2', sourceUrl: 'https://docs.dify.ai/two', title: 'Two' },
|
||||
{
|
||||
pageId: 'page-deleted',
|
||||
sourceUrl: 'https://docs.dify.ai/deleted',
|
||||
title: 'Deleted page',
|
||||
},
|
||||
],
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
items: [
|
||||
{ pageId: 'page-0', sourceUrl: 'https://docs.dify.ai/new', title: 'New first' },
|
||||
{ pageId: 'page-2', sourceUrl: 'https://docs.dify.ai/two', title: 'Two' },
|
||||
],
|
||||
nextCursor: 'final-page-2',
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
items: [
|
||||
{ pageId: 'page-1', sourceUrl: 'https://docs.dify.ai/one', title: 'Updated one' },
|
||||
{ pageId: 'page-3', sourceUrl: 'https://docs.dify.ai/three', title: 'Three' },
|
||||
],
|
||||
})
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
|
||||
expect(await screen.findByText('Two')).toBeInTheDocument()
|
||||
expect(clientMock.getRun).toHaveBeenNthCalledWith(1, {
|
||||
params: { id: 'space-1', runId: 'run-1' },
|
||||
})
|
||||
expect(clientMock.getPages).toHaveBeenNthCalledWith(1, {
|
||||
params: { id: 'space-1', runId: 'run-1' },
|
||||
query: { limit: 200 },
|
||||
})
|
||||
expect(clientMock.getPages).toHaveBeenNthCalledWith(2, {
|
||||
params: { id: 'space-1', runId: 'run-1' },
|
||||
query: { cursor: 'page-2', limit: 200 },
|
||||
})
|
||||
expect(
|
||||
screen.getByRole('progressbar', {
|
||||
name: 'dataset.newKnowledge.crawlProgress:{"host":"docs.dify.ai"}',
|
||||
}),
|
||||
).toHaveValue(3)
|
||||
const status = screen.getByText(/^dataset\.newKnowledge\.crawlingPages/)
|
||||
expect(status).toHaveAttribute('role', 'status')
|
||||
expect(status.querySelector('button')).not.toBeInTheDocument()
|
||||
const skeletons = screen.getAllByTestId('crawl-page-skeleton')
|
||||
expect(skeletons).toHaveLength(2)
|
||||
expect(skeletons[0]?.closest('ul')).toBe(screen.getByRole('list'))
|
||||
await act(async () => vi.advanceTimersByTime(1500))
|
||||
expect(await screen.findByText('Three')).toBeInTheDocument()
|
||||
expect(screen.getByText('New first')).toBeInTheDocument()
|
||||
expect(screen.getByText('Updated one')).toBeInTheDocument()
|
||||
expect(screen.queryByText('Old one')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('Deleted page')).not.toBeInTheDocument()
|
||||
expect(clientMock.getPages).toHaveBeenNthCalledWith(3, {
|
||||
params: { id: 'space-1', runId: 'run-1' },
|
||||
query: { limit: 200 },
|
||||
})
|
||||
expect(clientMock.getPages).toHaveBeenNthCalledWith(4, {
|
||||
params: { id: 'space-1', runId: 'run-1' },
|
||||
query: { cursor: 'final-page-2', limit: 200 },
|
||||
})
|
||||
expect(
|
||||
screen.getAllByRole('checkbox').map((checkbox) => checkbox.getAttribute('aria-label')),
|
||||
).toEqual(['New first', 'Two', 'Updated one', 'Three'])
|
||||
expect(
|
||||
screen.queryByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }),
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('stops the active run once and keeps pages already discovered', async () => {
|
||||
clientMock.getRun.mockResolvedValue(run('running', { progressCompleted: 1 }))
|
||||
clientMock.cancel.mockResolvedValue(run('canceled', { progressCompleted: 1 }))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByText('Getting started')
|
||||
const stop = screen.getByRole('button', { name: 'dataset.newKnowledge.stopCrawl' })
|
||||
await user.dblClick(stop)
|
||||
|
||||
await waitFor(() => expect(clientMock.cancel).toHaveBeenCalledOnce())
|
||||
expect(clientMock.cancel).toHaveBeenCalledWith({
|
||||
body: { reason: 'user_requested' },
|
||||
params: { id: 'space-1', runId: 'run-1' },
|
||||
})
|
||||
expect(screen.getByText('Getting started')).toBeInTheDocument()
|
||||
expect(await screen.findByText('dataset.newKnowledge.crawlStopped')).toHaveAttribute(
|
||||
'role',
|
||||
'status',
|
||||
)
|
||||
})
|
||||
|
||||
it('reconciles a lost Stop response without sending cancel twice', async () => {
|
||||
clientMock.getRun
|
||||
.mockResolvedValueOnce(run('running', { progressCompleted: 1 }))
|
||||
.mockResolvedValueOnce(run('canceled', { progressCompleted: 1 }))
|
||||
clientMock.cancel.mockRejectedValue(new Error('response lost'))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByText('Getting started')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }))
|
||||
|
||||
expect(await screen.findByText('dataset.newKnowledge.crawlStopped')).toHaveAttribute(
|
||||
'role',
|
||||
'status',
|
||||
)
|
||||
expect(clientMock.cancel).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('only reconciles Stop while an ambiguous cancel response remains stale', async () => {
|
||||
clientMock.getRun.mockResolvedValue(run('running', { progressCompleted: 1 }))
|
||||
clientMock.cancel.mockRejectedValue(
|
||||
Object.assign(new Error('proxy connection lost'), { status: 502 }),
|
||||
)
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByText('Getting started')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }))
|
||||
clientMock.getRun.mockRejectedValueOnce(
|
||||
Object.assign(new Error('reconciliation unavailable'), { status: 503 }),
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }))
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.getRun.mock.calls.length).toBeGreaterThanOrEqual(3))
|
||||
expect(clientMock.cancel).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('allows Stop to be retried after a definitive HTTP rejection', async () => {
|
||||
clientMock.getRun.mockResolvedValue(run('running', { progressCompleted: 1 }))
|
||||
clientMock.cancel
|
||||
.mockRejectedValueOnce(Object.assign(new Error('rate limited'), { status: 429 }))
|
||||
.mockResolvedValueOnce(run('canceled', { progressCompleted: 1 }))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByText('Getting started')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }))
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }))
|
||||
|
||||
expect(await screen.findByText('dataset.newKnowledge.crawlStopped')).toBeInTheDocument()
|
||||
expect(clientMock.cancel).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('shows provider failures and retries the same workflow without duplicate requests', async () => {
|
||||
clientMock.getRun.mockResolvedValue(
|
||||
run('failed', { lastErrorCode: 'PROVIDER_403', progressFailed: 1 }),
|
||||
)
|
||||
clientMock.getPages.mockResolvedValue({ items: [] })
|
||||
clientMock.retry.mockResolvedValue(run('running'))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
expect(await screen.findByRole('alert')).toHaveTextContent(
|
||||
'dataset.newKnowledge.crawlFailed403',
|
||||
)
|
||||
const retry = screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' })
|
||||
await user.dblClick(retry)
|
||||
|
||||
await waitFor(() => expect(clientMock.retry).toHaveBeenCalledOnce())
|
||||
expect(clientMock.retry).toHaveBeenCalledWith({
|
||||
params: { id: 'space-1', runId: 'run-1' },
|
||||
})
|
||||
expect(clientMock.createSource).toHaveBeenCalledOnce()
|
||||
expect(clientMock.startPreview).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('reconciles a lost Retry response without sending retry twice', async () => {
|
||||
clientMock.getRun
|
||||
.mockResolvedValueOnce(run('failed', { lastErrorCode: 'PROVIDER_403' }))
|
||||
.mockResolvedValueOnce(
|
||||
run('running', {
|
||||
executionAttempts: 2,
|
||||
updatedAt: '2026-07-20T10:01:00Z',
|
||||
}),
|
||||
)
|
||||
.mockResolvedValueOnce(
|
||||
run('succeeded', {
|
||||
executionAttempts: 2,
|
||||
progressCompleted: 1,
|
||||
updatedAt: '2026-07-20T10:02:00Z',
|
||||
}),
|
||||
)
|
||||
clientMock.retry.mockRejectedValue(new Error('response lost'))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByRole('alert')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
expect(
|
||||
await screen.findByRole('button', { name: 'dataset.newKnowledge.reCrawl' }),
|
||||
).toBeInTheDocument()
|
||||
expect(clientMock.retry).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('only reconciles Retry while an ambiguous retry response remains stale', async () => {
|
||||
const failedRun = run('failed', { lastErrorCode: 'PROVIDER_403', progressFailed: 1 })
|
||||
clientMock.getRun
|
||||
.mockResolvedValueOnce(failedRun)
|
||||
.mockResolvedValueOnce(failedRun)
|
||||
.mockRejectedValueOnce(
|
||||
Object.assign(new Error('reconciliation unavailable'), { status: 503 }),
|
||||
)
|
||||
.mockResolvedValue(failedRun)
|
||||
clientMock.getPages.mockResolvedValue({ items: [] })
|
||||
clientMock.retry.mockRejectedValue(Object.assign(new Error('proxy timeout'), { status: 504 }))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByRole('alert')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.getRun).toHaveBeenCalledTimes(4))
|
||||
expect(clientMock.retry).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('allows Retry to be repeated after a definitive HTTP rejection', async () => {
|
||||
clientMock.getRun.mockResolvedValue(
|
||||
run('failed', { lastErrorCode: 'PROVIDER_403', progressFailed: 1 }),
|
||||
)
|
||||
clientMock.getPages.mockResolvedValue({ items: [] })
|
||||
clientMock.retry
|
||||
.mockRejectedValueOnce(Object.assign(new Error('rate limited'), { status: 429 }))
|
||||
.mockResolvedValueOnce(run('running', { executionAttempts: 2 }))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByRole('alert')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.retry).toHaveBeenCalledTimes(2))
|
||||
})
|
||||
|
||||
it.each([
|
||||
['failed', 'PROVIDER_TIMEOUT', 'dataset.newKnowledge.crawlFailedTimeout'],
|
||||
['failed', 'PROVIDER_UNAVAILABLE', 'dataset.newKnowledge.crawlFailedProvider'],
|
||||
['timed_out', undefined, 'dataset.newKnowledge.crawlFailedTimeout'],
|
||||
])('shows a recovery message for %s / %s', async (state, lastErrorCode, message) => {
|
||||
clientMock.getRun.mockResolvedValue(run(state, { lastErrorCode }))
|
||||
clientMock.getPages.mockResolvedValue({ items: [] })
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Jina Reader"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
|
||||
const alert = await screen.findByRole('alert')
|
||||
expect(alert).toHaveTextContent(message)
|
||||
if (lastErrorCode === 'PROVIDER_UNAVAILABLE')
|
||||
expect(alert).toHaveTextContent('"provider":"Jina Reader"')
|
||||
})
|
||||
|
||||
it('offers an adjust-and-recrawl path after a successful zero-result crawl', async () => {
|
||||
clientMock.getRun.mockResolvedValue(run('succeeded'))
|
||||
clientMock.getPages.mockResolvedValue({ items: [] })
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
|
||||
const noPages = await screen.findByText(/^dataset\.newKnowledge\.noPagesFound:/)
|
||||
expect(noPages.closest('[role="status"]')).toHaveAttribute('aria-live', 'polite')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.adjustAndRecrawl' }))
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledTimes(2))
|
||||
const firstKey = clientMock.startPreview.mock.calls[0]?.[0].headers['Idempotency-Key']
|
||||
const secondKey = clientMock.startPreview.mock.calls[1]?.[0].headers['Idempotency-Key']
|
||||
expect(secondKey).not.toBe(firstKey)
|
||||
expect(clientMock.createSource).toHaveBeenCalledOnce()
|
||||
expect(clientMock.retry).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('reports draft and provisional source lifecycle to the parent flow', async () => {
|
||||
const onDraftChange = vi.fn()
|
||||
const onProvisionalSource = vi.fn()
|
||||
const view = render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
onDraftChange={onDraftChange}
|
||||
onProvisionalSource={onProvisionalSource}
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
|
||||
const user = await fillValidForm()
|
||||
expect(onDraftChange).toHaveBeenLastCalledWith(true)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await waitFor(() => expect(onProvisionalSource).toHaveBeenCalledWith(source()))
|
||||
|
||||
view.unmount()
|
||||
expect(onDraftChange).toHaveBeenLastCalledWith(false)
|
||||
})
|
||||
|
||||
it('treats a superseded workflow as terminal and stops polling', async () => {
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true })
|
||||
clientMock.getRun.mockResolvedValue(run('superseded'))
|
||||
clientMock.getPages.mockResolvedValue({ items: [] })
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
expect(await screen.findByText('dataset.newKnowledge.crawlStopped')).toHaveAttribute(
|
||||
'role',
|
||||
'status',
|
||||
)
|
||||
await act(async () => vi.advanceTimersByTime(6000))
|
||||
|
||||
expect(clientMock.getRun).toHaveBeenCalledOnce()
|
||||
expect(
|
||||
screen.queryByRole('button', { name: 'dataset.newKnowledge.stopCrawl' }),
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('resumes polling after a transient status request failure without retrying the workflow', async () => {
|
||||
clientMock.getRun
|
||||
.mockRejectedValueOnce(new Error('temporary network failure'))
|
||||
.mockResolvedValueOnce(run('succeeded', { progressCompleted: 1 }))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
expect(await screen.findByRole('alert')).toHaveTextContent(
|
||||
'dataset.newKnowledge.crawlFailedDescription',
|
||||
)
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.getRun).toHaveBeenCalledTimes(2))
|
||||
expect(clientMock.retry).not.toHaveBeenCalled()
|
||||
expect(await screen.findByText('Getting started')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('reuses the idempotency key when the preview start response is lost', async () => {
|
||||
clientMock.startPreview
|
||||
.mockRejectedValueOnce(new Error('response lost'))
|
||||
.mockResolvedValueOnce(run('running'))
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByRole('alert')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledTimes(2))
|
||||
expect(clientMock.createSource).toHaveBeenCalledOnce()
|
||||
expect(clientMock.startPreview.mock.calls[0]?.[0].headers).toEqual(
|
||||
clientMock.startPreview.mock.calls[1]?.[0].headers,
|
||||
)
|
||||
})
|
||||
|
||||
it('reconciles a response-lost provisional source by its client request id', async () => {
|
||||
clientMock.createSource.mockRejectedValue(new Error('response lost'))
|
||||
clientMock.listSources.mockImplementation(
|
||||
async ({ query }: { query?: { cursor?: string } }) => {
|
||||
const clientRequestId =
|
||||
clientMock.createSource.mock.calls[0]?.[0].body.metadata.clientRequestId
|
||||
return query?.cursor
|
||||
? { items: [source({ clientRequestId })] }
|
||||
: { items: [], nextCursor: 'next' }
|
||||
},
|
||||
)
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.listSources).toHaveBeenCalledTimes(2))
|
||||
expect(clientMock.startPreview).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('checks for a response-lost source before repeating its create request', async () => {
|
||||
clientMock.createSource.mockRejectedValue(new Error('response lost'))
|
||||
clientMock.listSources.mockResolvedValueOnce({ items: [] }).mockImplementationOnce(async () => {
|
||||
const clientRequestId =
|
||||
clientMock.createSource.mock.calls[0]?.[0].body.metadata.clientRequestId
|
||||
return { items: [source({ clientRequestId })] }
|
||||
})
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByRole('alert')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce())
|
||||
expect(clientMock.createSource).toHaveBeenCalledOnce()
|
||||
expect(clientMock.listSources).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('retries source creation after bounded reconciliation of an ambiguous result', async () => {
|
||||
clientMock.createSource
|
||||
.mockRejectedValueOnce(Object.assign(new Error('proxy timeout'), { status: 504 }))
|
||||
.mockResolvedValueOnce(source())
|
||||
clientMock.listSources.mockResolvedValue({ items: [] })
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByRole('alert')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
await waitFor(() => expect(clientMock.listSources).toHaveBeenCalledTimes(2))
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce())
|
||||
expect(clientMock.listSources).toHaveBeenCalledTimes(3)
|
||||
expect(clientMock.createSource).toHaveBeenCalledTimes(2)
|
||||
expect(clientMock.createSource.mock.calls[0]?.[0].body.metadata.clientRequestId).toBe(
|
||||
clientMock.createSource.mock.calls[1]?.[0].body.metadata.clientRequestId,
|
||||
)
|
||||
})
|
||||
|
||||
it('retries source creation after a definitive HTTP rejection', async () => {
|
||||
clientMock.createSource
|
||||
.mockRejectedValueOnce(Object.assign(new Error('rate limited'), { status: 429 }))
|
||||
.mockResolvedValueOnce(source())
|
||||
|
||||
render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await screen.findByRole('alert')
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.retryCrawl' }))
|
||||
|
||||
await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce())
|
||||
expect(clientMock.createSource).toHaveBeenCalledTimes(2)
|
||||
expect(clientMock.listSources).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('cleans up polling when the component unmounts', async () => {
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true })
|
||||
clientMock.getRun.mockResolvedValue(run('running'))
|
||||
const view = render(
|
||||
<WebsiteCrawlPreview
|
||||
connection={connection}
|
||||
knowledgeSpaceId="space-1"
|
||||
providerName="Firecrawl"
|
||||
/>,
|
||||
)
|
||||
const user = await fillValidForm()
|
||||
await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' }))
|
||||
await waitFor(() => expect(clientMock.getRun).toHaveBeenCalledOnce())
|
||||
view.unmount()
|
||||
await act(async () => vi.advanceTimersByTime(6000))
|
||||
|
||||
expect(clientMock.getRun).toHaveBeenCalledOnce()
|
||||
})
|
||||
})
|
||||
@ -3,16 +3,20 @@
|
||||
import type {
|
||||
GetKnowledgeSpacesByIdSourceConnectionsResponse,
|
||||
GetSourceProvidersResponse,
|
||||
Source,
|
||||
} from '@dify/contracts/knowledge-fs/types.gen'
|
||||
import { Button } from '@langgenius/dify-ui/button'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { useInfiniteQuery, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useCallback, useEffect, useId, useMemo, useState } from 'react'
|
||||
import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import Link from '@/next/link'
|
||||
import { useRouter } from '@/next/navigation'
|
||||
import { consoleClient, consoleQuery } from '@/service/client'
|
||||
import { AddSourceExitDialog } from './components/add-source-exit-dialog'
|
||||
import { newKnowledgeDetailPath } from './routes'
|
||||
import { WebsiteCrawlPreview } from './website-crawl-preview'
|
||||
|
||||
type Provider = GetSourceProvidersResponse['items'][number]
|
||||
type ProviderField = Provider['configuration'][number]
|
||||
@ -23,6 +27,7 @@ type SourceType = 'onlineDocuments' | 'onlineDrive' | 'websiteCrawl'
|
||||
const CONNECTION_PAGE_SIZE = 200
|
||||
const CONNECTION_RECONCILIATION_RETRY_DELAYS = [0, 100, 300]
|
||||
const FIRECRAWL_PROVIDER_ID = 'plugin-daemon-website'
|
||||
const SOURCE_MARKETPLACE_PATH = '/marketplace?category=datasource'
|
||||
const FIRECRAWL_CONFIGURATION = {
|
||||
datasource: 'crawl',
|
||||
pluginId: 'langgenius/firecrawl_datasource',
|
||||
@ -81,6 +86,15 @@ function findConnectionById(connections: Connection[], connectionId: string) {
|
||||
)[0]
|
||||
}
|
||||
|
||||
function responseStatus(error: unknown) {
|
||||
if (error instanceof Response) return error.status
|
||||
if (!error || typeof error !== 'object') return undefined
|
||||
if ('status' in error && typeof error.status === 'number') return error.status
|
||||
if ('data' in error && error.data && typeof error.data === 'object' && 'status' in error.data) {
|
||||
return typeof error.data.status === 'number' ? error.data.status : undefined
|
||||
}
|
||||
}
|
||||
|
||||
function getAuthFields(provider: Provider, authKind: ConnectionAuthKind) {
|
||||
const configurableFields = provider.configuration.filter(
|
||||
(field) =>
|
||||
@ -153,10 +167,12 @@ function SourceTypeSelector({
|
||||
}
|
||||
|
||||
function ProviderSelector({
|
||||
onNavigate,
|
||||
onChange,
|
||||
providers,
|
||||
value,
|
||||
}: {
|
||||
onNavigate: (path: string) => void
|
||||
onChange: (providerId: string) => void
|
||||
providers: Provider[]
|
||||
value?: string
|
||||
@ -171,8 +187,21 @@ function ProviderSelector({
|
||||
{t(($) => $['newKnowledge.providerLabel'])}
|
||||
</span>
|
||||
<Link
|
||||
href="/marketplace?category=datasource"
|
||||
href={SOURCE_MARKETPLACE_PATH}
|
||||
className="inline-flex items-center gap-0.5 rounded-sm system-xs-medium text-text-accent outline-hidden hover:underline focus-visible:ring-2 focus-visible:ring-state-accent-solid"
|
||||
onClick={(event) => {
|
||||
if (
|
||||
event.defaultPrevented ||
|
||||
event.button !== 0 ||
|
||||
event.metaKey ||
|
||||
event.ctrlKey ||
|
||||
event.shiftKey ||
|
||||
event.altKey
|
||||
)
|
||||
return
|
||||
event.preventDefault()
|
||||
onNavigate(SOURCE_MARKETPLACE_PATH)
|
||||
}}
|
||||
>
|
||||
{t(($) => $['newKnowledge.moreProviders'])}
|
||||
<span aria-hidden className="i-ri-arrow-right-up-line size-3.5" />
|
||||
@ -270,48 +299,43 @@ function ProviderFieldControl({
|
||||
)
|
||||
}
|
||||
|
||||
function ProviderConnected({ provider }: { provider: Provider }) {
|
||||
const { t } = useTranslation('dataset')
|
||||
|
||||
return (
|
||||
<div role="status" className="rounded-xl bg-background-section p-4">
|
||||
<span className="flex size-9 items-center justify-center rounded-lg border border-divider-subtle bg-background-default">
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn(providerIconClass(provider), 'size-[18px] text-text-tertiary')}
|
||||
/>
|
||||
</span>
|
||||
<h3 className="mt-3 system-sm-semibold text-text-primary">
|
||||
{t(($) => $['newKnowledge.providerConnected'], {
|
||||
provider: provider.displayName,
|
||||
})}
|
||||
</h3>
|
||||
<p className="mt-1 system-xs-regular text-text-tertiary">
|
||||
{t(($) => $['newKnowledge.crawlSetupUnavailableDescription'])}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ConnectionForm({
|
||||
knowledgeSpaceId,
|
||||
onConnected,
|
||||
onDraftChange,
|
||||
onReconcile,
|
||||
provider,
|
||||
}: {
|
||||
knowledgeSpaceId: string
|
||||
onConnected: (connection: Connection) => void
|
||||
onDraftChange?: (dirty: boolean) => void
|
||||
onReconcile: () => Promise<Connection | undefined>
|
||||
provider: Provider
|
||||
}) {
|
||||
const { t } = useTranslation('dataset')
|
||||
const supportedAuthKinds = getSupportedAuthKinds(provider)
|
||||
const [authKind, setAuthKind] = useState<ConnectionAuthKind>(supportedAuthKinds[0] ?? 'api-key')
|
||||
const defaultAuthKind = supportedAuthKinds[0] ?? 'api-key'
|
||||
const [authKind, setAuthKind] = useState<ConnectionAuthKind>(defaultAuthKind)
|
||||
const [configuration, setConfiguration] = useState<Record<string, string>>({})
|
||||
const [credentials, setCredentials] = useState<Record<string, string>>({})
|
||||
const [error, setError] = useState(false)
|
||||
const [pending, setPending] = useState(false)
|
||||
const visibleFields = getAuthFields(provider, authKind)
|
||||
const hasDraftChanges =
|
||||
authKind !== defaultAuthKind ||
|
||||
Object.values(configuration).some((value) => Boolean(value.trim())) ||
|
||||
Object.values(credentials).some((value) => Boolean(value.trim()))
|
||||
|
||||
useEffect(() => {
|
||||
onDraftChange?.(hasDraftChanges)
|
||||
}, [hasDraftChanges, onDraftChange])
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
onDraftChange?.(false)
|
||||
},
|
||||
[onDraftChange],
|
||||
)
|
||||
|
||||
const changeAuthKind = (nextAuthKind: ConnectionAuthKind) => {
|
||||
if (nextAuthKind !== authKind) setCredentials({})
|
||||
@ -437,11 +461,13 @@ function ConnectionForm({
|
||||
function UnconfiguredProvider({
|
||||
knowledgeSpaceId,
|
||||
onConnected,
|
||||
onDraftChange,
|
||||
onReconcile,
|
||||
provider,
|
||||
}: {
|
||||
knowledgeSpaceId: string
|
||||
onConnected: (connection: Connection) => void
|
||||
onDraftChange?: (dirty: boolean) => void
|
||||
onReconcile: () => Promise<Connection | undefined>
|
||||
provider: Provider
|
||||
}) {
|
||||
@ -453,6 +479,7 @@ function UnconfiguredProvider({
|
||||
<ConnectionForm
|
||||
knowledgeSpaceId={knowledgeSpaceId}
|
||||
onConnected={onConnected}
|
||||
onDraftChange={onDraftChange}
|
||||
onReconcile={onReconcile}
|
||||
provider={provider}
|
||||
/>
|
||||
@ -626,10 +653,30 @@ function ProvisioningConnection({
|
||||
|
||||
export function AddSourcePage({ knowledgeSpaceId }: { knowledgeSpaceId: string }) {
|
||||
const { t } = useTranslation('dataset')
|
||||
const router = useRouter()
|
||||
const queryClient = useQueryClient()
|
||||
const [sourceType, setSourceType] = useState<SourceType>('websiteCrawl')
|
||||
const [selectedProviderId, setSelectedProviderId] = useState<string>()
|
||||
const [ignoredConnectionIds, setIgnoredConnectionIds] = useState<Set<string>>(() => new Set())
|
||||
const [crawlDraftDirty, setCrawlDraftDirty] = useState(false)
|
||||
const [provisionalSourceCount, setProvisionalSourceCount] = useState(0)
|
||||
const [exitOpen, setExitOpen] = useState(false)
|
||||
const [discarding, setDiscarding] = useState(false)
|
||||
const [discardError, setDiscardError] = useState(false)
|
||||
const detailPath = newKnowledgeDetailPath(knowledgeSpaceId)
|
||||
const provisionalSourcesRef = useRef(new Map<string, Source>())
|
||||
const pendingPreviewOperationsRef = useRef(new Set<Promise<void>>())
|
||||
const deletionKeysRef = useRef(new Map<string, string>())
|
||||
const historyGuardArmedRef = useRef(false)
|
||||
const browserBackExitRef = useRef(false)
|
||||
const pendingNavigationRef = useRef<string | undefined>(undefined)
|
||||
const exitDestinationRef = useRef(detailPath)
|
||||
const hasUnsavedChanges = Boolean(
|
||||
crawlDraftDirty ||
|
||||
provisionalSourceCount ||
|
||||
sourceType !== 'websiteCrawl' ||
|
||||
selectedProviderId,
|
||||
)
|
||||
const providersQuery = useQuery(
|
||||
consoleQuery.knowledgeFs.getSourceProviders.queryOptions({
|
||||
input: {},
|
||||
@ -699,6 +746,229 @@ export function AddSourcePage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
|
||||
refetch: refetchConnections,
|
||||
} = connectionsQuery
|
||||
|
||||
const armHistoryGuard = useCallback(() => {
|
||||
globalThis.history.pushState(globalThis.history.state, '', globalThis.location.href)
|
||||
historyGuardArmedRef.current = true
|
||||
}, [])
|
||||
|
||||
const replaceAfterHistoryGuard = useCallback(
|
||||
(path: string) => {
|
||||
if (!historyGuardArmedRef.current) {
|
||||
router.replace(path)
|
||||
return
|
||||
}
|
||||
|
||||
pendingNavigationRef.current = path
|
||||
globalThis.history.back()
|
||||
},
|
||||
[router],
|
||||
)
|
||||
|
||||
const requestNavigation = useCallback(
|
||||
(path: string) => {
|
||||
if (discarding) return
|
||||
if (hasUnsavedChanges) {
|
||||
exitDestinationRef.current = path
|
||||
browserBackExitRef.current = false
|
||||
setDiscardError(false)
|
||||
setExitOpen(true)
|
||||
return
|
||||
}
|
||||
replaceAfterHistoryGuard(path)
|
||||
},
|
||||
[discarding, hasUnsavedChanges, replaceAfterHistoryGuard],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!hasUnsavedChanges ||
|
||||
historyGuardArmedRef.current ||
|
||||
browserBackExitRef.current ||
|
||||
pendingNavigationRef.current
|
||||
)
|
||||
return
|
||||
|
||||
armHistoryGuard()
|
||||
}, [armHistoryGuard, hasUnsavedChanges])
|
||||
|
||||
useEffect(() => {
|
||||
const handlePopState = () => {
|
||||
if (!historyGuardArmedRef.current) return
|
||||
|
||||
historyGuardArmedRef.current = false
|
||||
const pendingNavigation = pendingNavigationRef.current
|
||||
if (pendingNavigation) {
|
||||
pendingNavigationRef.current = undefined
|
||||
router.replace(pendingNavigation)
|
||||
return
|
||||
}
|
||||
if (!hasUnsavedChanges) {
|
||||
router.replace(detailPath)
|
||||
return
|
||||
}
|
||||
|
||||
browserBackExitRef.current = true
|
||||
exitDestinationRef.current = detailPath
|
||||
setDiscardError(false)
|
||||
setExitOpen(true)
|
||||
}
|
||||
|
||||
globalThis.addEventListener('popstate', handlePopState)
|
||||
return () => globalThis.removeEventListener('popstate', handlePopState)
|
||||
}, [detailPath, hasUnsavedChanges, router])
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasUnsavedChanges) return
|
||||
|
||||
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
|
||||
event.preventDefault()
|
||||
event.returnValue = ''
|
||||
}
|
||||
|
||||
globalThis.addEventListener('beforeunload', handleBeforeUnload)
|
||||
return () => globalThis.removeEventListener('beforeunload', handleBeforeUnload)
|
||||
}, [hasUnsavedChanges])
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasUnsavedChanges) return
|
||||
|
||||
const handleDocumentClick = (event: MouseEvent) => {
|
||||
if (
|
||||
event.defaultPrevented ||
|
||||
event.button !== 0 ||
|
||||
event.metaKey ||
|
||||
event.ctrlKey ||
|
||||
event.shiftKey ||
|
||||
event.altKey
|
||||
)
|
||||
return
|
||||
|
||||
const anchor = event
|
||||
.composedPath()
|
||||
.find((target): target is HTMLAnchorElement => target instanceof HTMLAnchorElement)
|
||||
if (
|
||||
!anchor ||
|
||||
anchor.hasAttribute('download') ||
|
||||
(anchor.target && anchor.target !== '_self')
|
||||
)
|
||||
return
|
||||
|
||||
const destination = new URL(anchor.href, globalThis.location.href)
|
||||
if (destination.origin !== globalThis.location.origin) return
|
||||
|
||||
const current = new URL(globalThis.location.href)
|
||||
if (destination.pathname === current.pathname && destination.search === current.search) return
|
||||
|
||||
event.preventDefault()
|
||||
requestNavigation(`${destination.pathname}${destination.search}${destination.hash}`)
|
||||
}
|
||||
|
||||
document.addEventListener('click', handleDocumentClick, true)
|
||||
return () => document.removeEventListener('click', handleDocumentClick, true)
|
||||
}, [hasUnsavedChanges, requestNavigation])
|
||||
|
||||
const rememberProvisionalSource = useCallback((source: Source) => {
|
||||
provisionalSourcesRef.current.set(source.id, source)
|
||||
setProvisionalSourceCount(provisionalSourcesRef.current.size)
|
||||
}, [])
|
||||
|
||||
const getDeletionKey = useCallback((sourceId: string) => {
|
||||
let idempotencyKey = deletionKeysRef.current.get(sourceId)
|
||||
if (!idempotencyKey) {
|
||||
idempotencyKey = globalThis.crypto.randomUUID()
|
||||
deletionKeysRef.current.set(sourceId, idempotencyKey)
|
||||
}
|
||||
return idempotencyKey
|
||||
}, [])
|
||||
|
||||
const rememberPendingPreviewOperation = useCallback((operation: Promise<void>) => {
|
||||
pendingPreviewOperationsRef.current.add(operation)
|
||||
void operation.then(
|
||||
() => pendingPreviewOperationsRef.current.delete(operation),
|
||||
() => pendingPreviewOperationsRef.current.delete(operation),
|
||||
)
|
||||
}, [])
|
||||
|
||||
const requestExit = () => requestNavigation(detailPath)
|
||||
|
||||
const cancelExit = () => {
|
||||
setExitOpen(false)
|
||||
setDiscardError(false)
|
||||
exitDestinationRef.current = detailPath
|
||||
if (!browserBackExitRef.current) return
|
||||
|
||||
browserBackExitRef.current = false
|
||||
armHistoryGuard()
|
||||
}
|
||||
|
||||
const confirmExit = async () => {
|
||||
if (discarding) return
|
||||
setDiscarding(true)
|
||||
setDiscardError(false)
|
||||
try {
|
||||
await Promise.allSettled([...pendingPreviewOperationsRef.current])
|
||||
for (const source of provisionalSourcesRef.current.values()) {
|
||||
try {
|
||||
await consoleClient.knowledgeFs.deleteKnowledgeSpacesByIdSourcesBySourceId({
|
||||
body: { expectedRevision: source.version ?? 1 },
|
||||
headers: { 'idempotency-key': getDeletionKey(source.id) },
|
||||
params: { id: knowledgeSpaceId, sourceId: source.id },
|
||||
query: { documents: 'cascade' },
|
||||
})
|
||||
} catch (deletionError) {
|
||||
let deletionConfirmed = false
|
||||
try {
|
||||
await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSourcesBySourceId({
|
||||
params: { id: knowledgeSpaceId, sourceId: source.id },
|
||||
})
|
||||
} catch (reconciliationError) {
|
||||
deletionConfirmed = responseStatus(reconciliationError) === 404
|
||||
}
|
||||
if (!deletionConfirmed) throw deletionError
|
||||
}
|
||||
provisionalSourcesRef.current.delete(source.id)
|
||||
deletionKeysRef.current.delete(source.id)
|
||||
setProvisionalSourceCount(provisionalSourcesRef.current.size)
|
||||
}
|
||||
setCrawlDraftDirty(false)
|
||||
setExitOpen(false)
|
||||
browserBackExitRef.current = false
|
||||
const exitDestination = exitDestinationRef.current
|
||||
exitDestinationRef.current = detailPath
|
||||
replaceAfterHistoryGuard(exitDestination)
|
||||
} catch {
|
||||
setDiscardError(true)
|
||||
} finally {
|
||||
setDiscarding(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const handlePageHide = () => {
|
||||
for (const source of provisionalSourcesRef.current.values()) {
|
||||
void consoleClient.knowledgeFs
|
||||
.deleteKnowledgeSpacesByIdSourcesBySourceId(
|
||||
{
|
||||
body: { expectedRevision: source.version ?? 1 },
|
||||
headers: { 'idempotency-key': getDeletionKey(source.id) },
|
||||
params: { id: knowledgeSpaceId, sourceId: source.id },
|
||||
query: { documents: 'cascade' },
|
||||
},
|
||||
{
|
||||
context: {
|
||||
keepalive: true,
|
||||
silent: true,
|
||||
},
|
||||
},
|
||||
)
|
||||
.catch(() => {})
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.addEventListener('pagehide', handlePageHide)
|
||||
return () => globalThis.removeEventListener('pagehide', handlePageHide)
|
||||
}, [getDeletionKey, knowledgeSpaceId])
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
hasNextConnectionPage &&
|
||||
@ -814,6 +1084,7 @@ export function AddSourcePage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
|
||||
{sourceType === 'websiteCrawl' ? (
|
||||
<>
|
||||
<ProviderSelector
|
||||
onNavigate={requestNavigation}
|
||||
providers={providers}
|
||||
value={provider?.id}
|
||||
onChange={setSelectedProviderId}
|
||||
@ -844,7 +1115,15 @@ export function AddSourcePage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
|
||||
</p>
|
||||
</div>
|
||||
) : connection?.status === 'active' ? (
|
||||
<ProviderConnected key={provider.id} provider={provider} />
|
||||
<WebsiteCrawlPreview
|
||||
key={connection.id}
|
||||
connection={connection}
|
||||
knowledgeSpaceId={knowledgeSpaceId}
|
||||
onDraftChange={setCrawlDraftDirty}
|
||||
onPendingOperation={rememberPendingPreviewOperation}
|
||||
onProvisionalSource={rememberProvisionalSource}
|
||||
providerName={provider.displayName}
|
||||
/>
|
||||
) : connection?.status === 'provisioning' ? (
|
||||
<ProvisioningConnection
|
||||
key={provider.id}
|
||||
@ -866,6 +1145,7 @@ export function AddSourcePage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
|
||||
key={provider.id}
|
||||
knowledgeSpaceId={knowledgeSpaceId}
|
||||
onConnected={rememberConnection}
|
||||
onDraftChange={setCrawlDraftDirty}
|
||||
onReconcile={reconcileConnection}
|
||||
provider={provider}
|
||||
/>
|
||||
@ -882,17 +1162,36 @@ export function AddSourcePage({ knowledgeSpaceId }: { knowledgeSpaceId: string }
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-end gap-2 border-t border-divider-subtle pt-5">
|
||||
<Link
|
||||
href={newKnowledgeDetailPath(knowledgeSpaceId)}
|
||||
className="inline-flex h-8 items-center justify-center rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3.5 system-sm-medium text-components-button-secondary-text shadow-xs outline-hidden hover:bg-components-button-secondary-bg-hover focus-visible:ring-2 focus-visible:ring-state-accent-solid"
|
||||
>
|
||||
<Button type="button" onClick={requestExit}>
|
||||
{t(($) => $['newKnowledge.cancelAddSource'])}
|
||||
</Link>
|
||||
<Button variant="primary" disabled>
|
||||
{t(($) => $['newKnowledge.addSource'])}
|
||||
</Button>
|
||||
{sourceType === 'websiteCrawl' ? (
|
||||
<>
|
||||
<span id="add-source-selection-requirement" className="sr-only">
|
||||
{t(($) => $['newKnowledge.addSourceRequiresSelection'])}
|
||||
</span>
|
||||
<Button
|
||||
variant="primary"
|
||||
disabled
|
||||
aria-describedby="add-source-selection-requirement"
|
||||
>
|
||||
{t(($) => $['newKnowledge.addSource'])}
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Button variant="primary" disabled>
|
||||
{t(($) => $['newKnowledge.addSource'])}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<AddSourceExitDialog
|
||||
discarding={discarding}
|
||||
error={discardError}
|
||||
onCancel={cancelExit}
|
||||
onConfirm={() => void confirmExit()}
|
||||
open={exitOpen}
|
||||
/>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
65
web/features/new-rag/components/add-source-exit-dialog.tsx
Normal file
65
web/features/new-rag/components/add-source-exit-dialog.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogActions,
|
||||
AlertDialogCancelButton,
|
||||
AlertDialogConfirmButton,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogTitle,
|
||||
} from '@langgenius/dify-ui/alert-dialog'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export function AddSourceExitDialog({
|
||||
discarding,
|
||||
error,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
open,
|
||||
}: {
|
||||
discarding: boolean
|
||||
error: boolean
|
||||
onCancel: () => void
|
||||
onConfirm: () => void
|
||||
open: boolean
|
||||
}) {
|
||||
const { t } = useTranslation('dataset')
|
||||
const { t: tCommon } = useTranslation('common')
|
||||
|
||||
return (
|
||||
<AlertDialog
|
||||
open={open}
|
||||
onOpenChange={(nextOpen) => {
|
||||
if (!nextOpen && !discarding) onCancel()
|
||||
}}
|
||||
>
|
||||
<AlertDialogContent className="w-120 rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-0! text-left align-middle shadow-lg">
|
||||
<div className="flex flex-col items-start gap-2 self-stretch p-6 pb-4">
|
||||
<AlertDialogTitle className="title-2xl-semi-bold text-text-primary">
|
||||
{t(($) => $['newKnowledge.discardSourceDraftTitle'])}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription
|
||||
render={<div />}
|
||||
className="system-md-regular text-text-secondary"
|
||||
>
|
||||
{t(($) => $['newKnowledge.discardSourceDraftDescription'])}
|
||||
</AlertDialogDescription>
|
||||
{error && (
|
||||
<p role="alert" className="system-sm-regular text-text-destructive">
|
||||
{t(($) => $['newKnowledge.discardSourceDraftFailed'])}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<AlertDialogActions className="gap-2 p-6">
|
||||
<AlertDialogCancelButton variant="secondary" disabled={discarding}>
|
||||
{tCommon(($) => $['operation.cancel'])}
|
||||
</AlertDialogCancelButton>
|
||||
<AlertDialogConfirmButton loading={discarding} disabled={discarding} onClick={onConfirm}>
|
||||
{t(($) => $['newKnowledge.discardDraftConfirm'])}
|
||||
</AlertDialogConfirmButton>
|
||||
</AlertDialogActions>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)
|
||||
}
|
||||
971
web/features/new-rag/website-crawl-preview.tsx
Normal file
971
web/features/new-rag/website-crawl-preview.tsx
Normal file
@ -0,0 +1,971 @@
|
||||
'use client'
|
||||
|
||||
import type {
|
||||
GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponse,
|
||||
Source,
|
||||
SourceWorkflowRun,
|
||||
} from '@dify/contracts/knowledge-fs/types.gen'
|
||||
import { Button } from '@langgenius/dify-ui/button'
|
||||
import { Checkbox } from '@langgenius/dify-ui/checkbox'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { Field, FieldError, FieldLabel } from '@langgenius/dify-ui/field'
|
||||
import { Form } from '@langgenius/dify-ui/form'
|
||||
import { Input } from '@langgenius/dify-ui/input'
|
||||
import { NumberField, NumberFieldGroup, NumberFieldInput } from '@langgenius/dify-ui/number-field'
|
||||
import { memo, useCallback, useEffect, useId, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { consoleClient } from '@/service/client'
|
||||
|
||||
type ConnectionReference = {
|
||||
id: string
|
||||
providerId: string
|
||||
}
|
||||
|
||||
type PreviewPage = GetKnowledgeSpacesByIdSourceWorkflowsByRunIdPagesResponse['items'][number]
|
||||
|
||||
type CrawlConfiguration = {
|
||||
includeSubpages: boolean
|
||||
limit: number
|
||||
name: string
|
||||
url: string
|
||||
}
|
||||
|
||||
type PreviewDraft = {
|
||||
clientRequestId: string
|
||||
configurationKey: string
|
||||
creationAttempted?: boolean
|
||||
previewRequestId: string
|
||||
reconciliationAttempts?: number
|
||||
source?: Source
|
||||
}
|
||||
|
||||
function previewPagesEqual(left: PreviewPage, right: PreviewPage) {
|
||||
return (
|
||||
left.pageId === right.pageId &&
|
||||
left.description === right.description &&
|
||||
left.etag === right.etag &&
|
||||
left.sourceUrl === right.sourceUrl &&
|
||||
left.title === right.title
|
||||
)
|
||||
}
|
||||
|
||||
const PAGE_SIZE = 200
|
||||
const MAX_CURSOR_PAGES = 100
|
||||
const POLL_INTERVAL_MS = 1500
|
||||
const DEFAULT_PAGE_LIMIT = 100
|
||||
const MAX_PAGE_LIMIT = 1000
|
||||
const MAX_SOURCE_NAME_LENGTH = 200
|
||||
const MAX_SOURCE_RECONCILIATION_ATTEMPTS = 3
|
||||
const SUCCESS_STATES = new Set(['complete', 'completed', 'preview_ready', 'success', 'succeeded'])
|
||||
const FAILURE_STATES = new Set(['error', 'exhausted', 'failed', 'timed_out', 'timeout'])
|
||||
const CANCELED_STATES = new Set(['canceled', 'cancelled', 'superseded'])
|
||||
|
||||
function normalizedState(state: string) {
|
||||
return state.trim().toLowerCase().replaceAll('-', '_').replaceAll(' ', '_')
|
||||
}
|
||||
|
||||
function isSuccessful(state: string) {
|
||||
return SUCCESS_STATES.has(normalizedState(state))
|
||||
}
|
||||
|
||||
function isFailed(state: string) {
|
||||
return FAILURE_STATES.has(normalizedState(state))
|
||||
}
|
||||
|
||||
function isCanceled(state: string) {
|
||||
return CANCELED_STATES.has(normalizedState(state))
|
||||
}
|
||||
|
||||
function isTerminal(state: string) {
|
||||
return isSuccessful(state) || isFailed(state) || isCanceled(state)
|
||||
}
|
||||
|
||||
function normalizeURL(value: string) {
|
||||
try {
|
||||
const url = new URL(value.trim())
|
||||
if (
|
||||
!['http:', 'https:'].includes(url.protocol) ||
|
||||
!url.hostname ||
|
||||
url.username ||
|
||||
url.password
|
||||
)
|
||||
return undefined
|
||||
url.hash = ''
|
||||
return url
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function configurationKey(configuration: CrawlConfiguration) {
|
||||
return JSON.stringify(configuration)
|
||||
}
|
||||
|
||||
function workflowAttemptKey(run: SourceWorkflowRun) {
|
||||
return `${run.id}:${run.executionAttempts}`
|
||||
}
|
||||
|
||||
function responseStatus(error: unknown) {
|
||||
if (error instanceof Response) return error.status
|
||||
if (!error || typeof error !== 'object') return undefined
|
||||
if ('status' in error && typeof error.status === 'number') return error.status
|
||||
if ('data' in error && error.data && typeof error.data === 'object' && 'status' in error.data) {
|
||||
return typeof error.data.status === 'number' ? error.data.status : undefined
|
||||
}
|
||||
}
|
||||
|
||||
function isDefinitiveRequestFailure(error: unknown) {
|
||||
const status = responseStatus(error)
|
||||
return status !== undefined && [400, 401, 403, 404, 409, 422, 429].includes(status)
|
||||
}
|
||||
|
||||
function isRetryConfirmed(previous: SourceWorkflowRun, current: SourceWorkflowRun) {
|
||||
return (
|
||||
previous.id === current.id &&
|
||||
(current.executionAttempts > previous.executionAttempts ||
|
||||
(isTerminal(previous.state) && !isTerminal(current.state)))
|
||||
)
|
||||
}
|
||||
|
||||
function isCancelConfirmed(current: SourceWorkflowRun) {
|
||||
return isTerminal(current.state)
|
||||
}
|
||||
|
||||
function createRequestId() {
|
||||
return globalThis.crypto.randomUUID()
|
||||
}
|
||||
|
||||
async function listWorkflowPageUpdates(
|
||||
knowledgeSpaceId: string,
|
||||
runId: string,
|
||||
initialCursor?: string,
|
||||
) {
|
||||
const pages = new Map<string, PreviewPage>()
|
||||
const seenCursors = new Set(initialCursor ? [initialCursor] : [])
|
||||
let cursor = initialCursor
|
||||
let resumeCursor = initialCursor
|
||||
let pageCount = 0
|
||||
|
||||
do {
|
||||
pageCount += 1
|
||||
if (pageCount > MAX_CURSOR_PAGES) throw new Error('Workflow page cursor limit exceeded')
|
||||
const response =
|
||||
await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSourceWorkflowsByRunIdPages({
|
||||
params: { id: knowledgeSpaceId, runId },
|
||||
query: { ...(cursor ? { cursor } : {}), limit: PAGE_SIZE },
|
||||
})
|
||||
for (const page of response.items) pages.set(page.pageId, page)
|
||||
const nextCursor = response.nextCursor
|
||||
if (!nextCursor || seenCursors.has(nextCursor)) break
|
||||
seenCursors.add(nextCursor)
|
||||
cursor = nextCursor
|
||||
resumeCursor = nextCursor
|
||||
} while (cursor)
|
||||
|
||||
return { items: [...pages.values()], resumeCursor }
|
||||
}
|
||||
|
||||
async function findProvisionalSource(knowledgeSpaceId: string, clientRequestId: string) {
|
||||
const seenCursors = new Set<string>()
|
||||
let cursor: string | undefined
|
||||
let pageCount = 0
|
||||
|
||||
do {
|
||||
pageCount += 1
|
||||
if (pageCount > MAX_CURSOR_PAGES) throw new Error('Source cursor limit exceeded')
|
||||
const response = await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSources({
|
||||
params: { id: knowledgeSpaceId },
|
||||
query: { ...(cursor ? { cursor } : {}), limit: PAGE_SIZE },
|
||||
})
|
||||
const source = response.items.find(
|
||||
(candidate) => candidate.metadata.clientRequestId === clientRequestId,
|
||||
)
|
||||
if (source) return source
|
||||
const nextCursor = response.nextCursor
|
||||
if (!nextCursor || seenCursors.has(nextCursor)) return undefined
|
||||
seenCursors.add(nextCursor)
|
||||
cursor = nextCursor
|
||||
} while (cursor)
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const CrawlPageList = memo(
|
||||
({ loading = false, pages }: { loading?: boolean; pages: PreviewPage[] }) => {
|
||||
if (!pages.length && !loading) return null
|
||||
|
||||
return (
|
||||
<ul className="max-h-64 divide-y divide-divider-subtle overflow-y-auto" aria-live="polite">
|
||||
{pages.map((page) => (
|
||||
<li
|
||||
key={page.pageId}
|
||||
className="flex items-start gap-2.5 px-4 py-2.5 [contain-intrinsic-size:auto_40px] [content-visibility:auto]"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
disabled
|
||||
aria-label={page.title || page.sourceUrl}
|
||||
className="mt-0.5 size-4"
|
||||
/>
|
||||
<span className="min-w-0">
|
||||
<span className="block truncate system-xs-medium text-text-primary">
|
||||
{page.title || page.sourceUrl}
|
||||
</span>
|
||||
<span className="block truncate system-2xs-regular text-text-tertiary">
|
||||
{page.sourceUrl}
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
{loading &&
|
||||
[0, 1].map((placeholder) => (
|
||||
<li
|
||||
key={`placeholder-${placeholder}`}
|
||||
data-testid="crawl-page-skeleton"
|
||||
aria-hidden
|
||||
className="flex items-start gap-2.5 px-4 py-2.5"
|
||||
>
|
||||
<span className="size-4 animate-pulse rounded bg-background-section motion-reduce:animate-none" />
|
||||
<span className="min-w-0 flex-1 space-y-1.5">
|
||||
<span className="block h-3 w-2/3 animate-pulse rounded bg-background-section motion-reduce:animate-none" />
|
||||
<span className="block h-2.5 w-full animate-pulse rounded bg-background-section motion-reduce:animate-none" />
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
function EmptyPreview() {
|
||||
const { t } = useTranslation('dataset')
|
||||
return (
|
||||
<div className="flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed border-divider-regular px-6 text-center">
|
||||
<span className="flex size-10 items-center justify-center rounded-lg bg-background-section">
|
||||
<span aria-hidden className="i-ri-global-line size-5 text-text-tertiary" />
|
||||
</span>
|
||||
<p className="mt-2 system-xs-semibold text-text-primary">
|
||||
{t(($) => $['newKnowledge.pagesAppearTitle'])}
|
||||
</p>
|
||||
<p className="mt-2 system-xs-regular text-text-tertiary">
|
||||
{t(($) => $['newKnowledge.pagesAppearDescription'])}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function WebsiteCrawlPreview({
|
||||
connection,
|
||||
knowledgeSpaceId,
|
||||
onDraftChange,
|
||||
onPendingOperation,
|
||||
onProvisionalSource,
|
||||
providerName,
|
||||
}: {
|
||||
connection: ConnectionReference
|
||||
knowledgeSpaceId: string
|
||||
onDraftChange?: (dirty: boolean) => void
|
||||
onPendingOperation?: (operation: Promise<void>) => void
|
||||
onProvisionalSource?: (source: Source) => void
|
||||
providerName: string
|
||||
}) {
|
||||
const { t } = useTranslation('dataset')
|
||||
const rootUrlErrorId = useId()
|
||||
const [rootUrl, setRootUrl] = useState('')
|
||||
const [sourceName, setSourceName] = useState('')
|
||||
const [urlTouched, setUrlTouched] = useState(false)
|
||||
const [optionsExpanded, setOptionsExpanded] = useState(false)
|
||||
const [includeSubpages, setIncludeSubpages] = useState(true)
|
||||
const [pageLimit, setPageLimit] = useState(DEFAULT_PAGE_LIMIT)
|
||||
const [run, setRun] = useState<SourceWorkflowRun>()
|
||||
const [previewConfiguration, setPreviewConfiguration] = useState<CrawlConfiguration>()
|
||||
const [pages, setPages] = useState<PreviewPage[]>([])
|
||||
const [pagesLoaded, setPagesLoaded] = useState(false)
|
||||
const [starting, setStarting] = useState(false)
|
||||
const [stopping, setStopping] = useState(false)
|
||||
const [pollPaused, setPollPaused] = useState(false)
|
||||
const [requestError, setRequestError] = useState<string>()
|
||||
const draftRef = useRef<PreviewDraft | undefined>(undefined)
|
||||
const actionPendingRef = useRef(false)
|
||||
const retryFingerprintRef = useRef<string | undefined>(undefined)
|
||||
const cancelFingerprintRef = useRef<string | undefined>(undefined)
|
||||
const rootUrlInputRef = useRef<HTMLInputElement>(null)
|
||||
const sourceNameInputRef = useRef<HTMLInputElement>(null)
|
||||
const pageMapRef = useRef(new Map<string, PreviewPage>())
|
||||
const pageCursorRef = useRef<string | undefined>(undefined)
|
||||
|
||||
const resetPreviewPages = useCallback(() => {
|
||||
pageMapRef.current.clear()
|
||||
pageCursorRef.current = undefined
|
||||
setPages([])
|
||||
setPagesLoaded(false)
|
||||
}, [])
|
||||
|
||||
const normalizedURL = useMemo(() => normalizeURL(rootUrl), [rootUrl])
|
||||
const normalizedLimit = Math.min(Math.max(Math.trunc(pageLimit) || 1, 1), MAX_PAGE_LIMIT)
|
||||
const configuration = useMemo<CrawlConfiguration | undefined>(
|
||||
() =>
|
||||
normalizedURL && sourceName.trim() && sourceName.trim().length <= MAX_SOURCE_NAME_LENGTH
|
||||
? {
|
||||
includeSubpages,
|
||||
limit: normalizedLimit,
|
||||
name: sourceName.trim(),
|
||||
url: normalizedURL.toString(),
|
||||
}
|
||||
: undefined,
|
||||
[includeSubpages, normalizedLimit, normalizedURL, sourceName],
|
||||
)
|
||||
const active = Boolean(run && !isTerminal(run.state))
|
||||
const shouldPoll = Boolean(
|
||||
run && !starting && !stopping && !pollPaused && (active || !pagesLoaded),
|
||||
)
|
||||
const runId = run?.id
|
||||
const locked = starting || stopping || active
|
||||
const draftHost = normalizedURL?.host ?? ''
|
||||
const previewHost = previewConfiguration ? new URL(previewConfiguration.url).host : draftHost
|
||||
const completedCount = Math.max(run?.progressCompleted ?? 0, pages.length)
|
||||
const crawlingStatusText = t(($) => $['newKnowledge.crawlingPages'], {
|
||||
count: completedCount,
|
||||
host: previewHost,
|
||||
})
|
||||
const completedStatusText = t(($) => $['newKnowledge.pagesCrawled'], {
|
||||
count: pages.length,
|
||||
host: previewHost,
|
||||
})
|
||||
const hasDraftChanges = Boolean(
|
||||
rootUrl ||
|
||||
sourceName ||
|
||||
!includeSubpages ||
|
||||
pageLimit !== DEFAULT_PAGE_LIMIT ||
|
||||
run ||
|
||||
requestError,
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
onDraftChange?.(hasDraftChanges)
|
||||
}, [hasDraftChanges, onDraftChange])
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
onDraftChange?.(false)
|
||||
},
|
||||
[onDraftChange],
|
||||
)
|
||||
|
||||
const ensureProvisionalSource = useCallback(
|
||||
async (nextConfiguration: CrawlConfiguration) => {
|
||||
const nextConfigurationKey = configurationKey(nextConfiguration)
|
||||
let draft = draftRef.current
|
||||
if (!draft || draft.configurationKey !== nextConfigurationKey) {
|
||||
draft = {
|
||||
clientRequestId: createRequestId(),
|
||||
configurationKey: nextConfigurationKey,
|
||||
previewRequestId: createRequestId(),
|
||||
}
|
||||
draftRef.current = draft
|
||||
}
|
||||
if (draft.source) return draft
|
||||
|
||||
if (draft.creationAttempted) {
|
||||
const reconciled = await findProvisionalSource(knowledgeSpaceId, draft.clientRequestId)
|
||||
if (reconciled) {
|
||||
draft.source = reconciled
|
||||
onProvisionalSource?.(reconciled)
|
||||
return draft
|
||||
}
|
||||
draft.reconciliationAttempts = (draft.reconciliationAttempts ?? 0) + 1
|
||||
if (draft.reconciliationAttempts < MAX_SOURCE_RECONCILIATION_ATTEMPTS)
|
||||
throw new Error('Provisional source creation is still reconciling')
|
||||
draft.creationAttempted = false
|
||||
draft.reconciliationAttempts = 0
|
||||
}
|
||||
|
||||
draft.creationAttempted = true
|
||||
try {
|
||||
draft.source = await consoleClient.knowledgeFs.postKnowledgeSpacesByIdSources({
|
||||
body: {
|
||||
connectionId: connection.id,
|
||||
metadata: {
|
||||
clientRequestId: draft.clientRequestId,
|
||||
crawlOptions: {
|
||||
includeSubpages: nextConfiguration.includeSubpages,
|
||||
limit: nextConfiguration.limit,
|
||||
},
|
||||
preview: true,
|
||||
providerId: connection.providerId,
|
||||
},
|
||||
name: nextConfiguration.name,
|
||||
status: 'disabled',
|
||||
type: 'web',
|
||||
uri: nextConfiguration.url,
|
||||
},
|
||||
params: { id: knowledgeSpaceId },
|
||||
})
|
||||
onProvisionalSource?.(draft.source)
|
||||
} catch (error) {
|
||||
if (isDefinitiveRequestFailure(error)) {
|
||||
draft.creationAttempted = false
|
||||
draft.reconciliationAttempts = 0
|
||||
throw error
|
||||
}
|
||||
const reconciled = await findProvisionalSource(knowledgeSpaceId, draft.clientRequestId)
|
||||
if (!reconciled) {
|
||||
draft.reconciliationAttempts = (draft.reconciliationAttempts ?? 0) + 1
|
||||
throw error
|
||||
}
|
||||
draft.source = reconciled
|
||||
onProvisionalSource?.(reconciled)
|
||||
}
|
||||
return draft
|
||||
},
|
||||
[connection.id, connection.providerId, knowledgeSpaceId, onProvisionalSource],
|
||||
)
|
||||
|
||||
const startPreview = useCallback(
|
||||
async (nextConfiguration: CrawlConfiguration, forceNewRun = false) => {
|
||||
if (actionPendingRef.current) return
|
||||
actionPendingRef.current = true
|
||||
setStarting(true)
|
||||
setRequestError(undefined)
|
||||
setPollPaused(false)
|
||||
setPreviewConfiguration(nextConfiguration)
|
||||
resetPreviewPages()
|
||||
setRun(undefined)
|
||||
try {
|
||||
const draft = await ensureProvisionalSource(nextConfiguration)
|
||||
if (!draft.source) throw new Error('Provisional source is missing')
|
||||
if (forceNewRun) draft.previewRequestId = createRequestId()
|
||||
const nextRun =
|
||||
await consoleClient.knowledgeFs.postKnowledgeSpacesByIdSourcesBySourceIdCrawlPreview({
|
||||
headers: { 'Idempotency-Key': draft.previewRequestId },
|
||||
params: { id: knowledgeSpaceId, sourceId: draft.source.id },
|
||||
})
|
||||
setRun(nextRun)
|
||||
} catch {
|
||||
setRequestError('START_FAILED')
|
||||
} finally {
|
||||
actionPendingRef.current = false
|
||||
setStarting(false)
|
||||
}
|
||||
},
|
||||
[ensureProvisionalSource, knowledgeSpaceId, resetPreviewPages],
|
||||
)
|
||||
|
||||
const retryRun = useCallback(async () => {
|
||||
if (!run || actionPendingRef.current) return
|
||||
const attemptKey = workflowAttemptKey(run)
|
||||
const retryAlreadySent = retryFingerprintRef.current === attemptKey
|
||||
actionPendingRef.current = true
|
||||
setStarting(true)
|
||||
setRequestError(undefined)
|
||||
setPollPaused(false)
|
||||
try {
|
||||
if (retryAlreadySent) {
|
||||
try {
|
||||
const reconciled =
|
||||
await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSourceWorkflowsByRunId({
|
||||
params: { id: knowledgeSpaceId, runId: run.id },
|
||||
})
|
||||
if (!isRetryConfirmed(run, reconciled)) {
|
||||
setRequestError('RETRY_FAILED')
|
||||
return
|
||||
}
|
||||
resetPreviewPages()
|
||||
setRun(reconciled)
|
||||
} catch {
|
||||
setRequestError('RETRY_FAILED')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
retryFingerprintRef.current = attemptKey
|
||||
try {
|
||||
const retried =
|
||||
await consoleClient.knowledgeFs.postKnowledgeSpacesByIdSourceWorkflowsByRunIdRetry({
|
||||
params: { id: knowledgeSpaceId, runId: run.id },
|
||||
})
|
||||
resetPreviewPages()
|
||||
setRun(retried)
|
||||
} catch (error) {
|
||||
if (isDefinitiveRequestFailure(error)) {
|
||||
retryFingerprintRef.current = undefined
|
||||
setRequestError('RETRY_FAILED')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const reconciled =
|
||||
await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSourceWorkflowsByRunId({
|
||||
params: { id: knowledgeSpaceId, runId: run.id },
|
||||
})
|
||||
if (!isRetryConfirmed(run, reconciled)) {
|
||||
setRequestError('RETRY_FAILED')
|
||||
} else {
|
||||
resetPreviewPages()
|
||||
setRun(reconciled)
|
||||
}
|
||||
} catch {
|
||||
setRequestError('RETRY_FAILED')
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
actionPendingRef.current = false
|
||||
setStarting(false)
|
||||
}
|
||||
}, [knowledgeSpaceId, resetPreviewPages, run])
|
||||
|
||||
useEffect(() => {
|
||||
if (!runId || !shouldPoll) return
|
||||
let disposed = false
|
||||
let timer: ReturnType<typeof setTimeout> | undefined
|
||||
|
||||
const poll = async () => {
|
||||
try {
|
||||
const nextRun =
|
||||
await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSourceWorkflowsByRunId({
|
||||
params: { id: knowledgeSpaceId, runId },
|
||||
})
|
||||
if (disposed) return
|
||||
let pageUpdates: Awaited<ReturnType<typeof listWorkflowPageUpdates>>
|
||||
const finalSnapshot = isSuccessful(nextRun.state)
|
||||
try {
|
||||
pageUpdates = await listWorkflowPageUpdates(
|
||||
knowledgeSpaceId,
|
||||
runId,
|
||||
finalSnapshot ? undefined : pageCursorRef.current,
|
||||
)
|
||||
} catch (error) {
|
||||
if (isFailed(nextRun.state) || isCanceled(nextRun.state)) {
|
||||
setRun(nextRun)
|
||||
setPagesLoaded(true)
|
||||
setRequestError(undefined)
|
||||
return
|
||||
}
|
||||
throw error
|
||||
}
|
||||
if (disposed) return
|
||||
let pagesChanged = false
|
||||
if (finalSnapshot) {
|
||||
const currentPages = [...pageMapRef.current.values()]
|
||||
const finalPageMap = new Map(pageUpdates.items.map((page) => [page.pageId, page]))
|
||||
pagesChanged =
|
||||
currentPages.length !== pageUpdates.items.length ||
|
||||
pageUpdates.items.some(
|
||||
(page, index) =>
|
||||
!currentPages[index] || !previewPagesEqual(currentPages[index], page),
|
||||
)
|
||||
pageMapRef.current = finalPageMap
|
||||
} else {
|
||||
for (const page of pageUpdates.items) {
|
||||
const current = pageMapRef.current.get(page.pageId)
|
||||
if (!current || !previewPagesEqual(current, page)) {
|
||||
pageMapRef.current.set(page.pageId, page)
|
||||
pagesChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
pageCursorRef.current = pageUpdates.resumeCursor
|
||||
setRun(nextRun)
|
||||
if (pagesChanged) setPages([...pageMapRef.current.values()])
|
||||
setPagesLoaded(true)
|
||||
setRequestError(undefined)
|
||||
if (!isTerminal(nextRun.state)) timer = setTimeout(() => void poll(), POLL_INTERVAL_MS)
|
||||
} catch {
|
||||
if (disposed) return
|
||||
setRequestError('POLL_FAILED')
|
||||
setPollPaused(true)
|
||||
}
|
||||
}
|
||||
|
||||
void poll()
|
||||
return () => {
|
||||
disposed = true
|
||||
if (timer) clearTimeout(timer)
|
||||
}
|
||||
}, [knowledgeSpaceId, runId, shouldPoll])
|
||||
|
||||
const stop = async () => {
|
||||
if (!run || actionPendingRef.current || !active) return
|
||||
const attemptKey = workflowAttemptKey(run)
|
||||
const cancelAlreadySent = cancelFingerprintRef.current === attemptKey
|
||||
actionPendingRef.current = true
|
||||
setStopping(true)
|
||||
setRequestError(undefined)
|
||||
try {
|
||||
if (cancelAlreadySent) {
|
||||
try {
|
||||
const reconciled =
|
||||
await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSourceWorkflowsByRunId({
|
||||
params: { id: knowledgeSpaceId, runId: run.id },
|
||||
})
|
||||
if (!isCancelConfirmed(reconciled)) {
|
||||
setRequestError('CANCEL_FAILED')
|
||||
return
|
||||
}
|
||||
cancelFingerprintRef.current = undefined
|
||||
setRun(reconciled)
|
||||
} catch {
|
||||
setRequestError('CANCEL_FAILED')
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
cancelFingerprintRef.current = attemptKey
|
||||
try {
|
||||
const canceled =
|
||||
await consoleClient.knowledgeFs.postKnowledgeSpacesByIdSourceWorkflowsByRunIdCancel({
|
||||
body: { reason: 'user_requested' },
|
||||
params: { id: knowledgeSpaceId, runId: run.id },
|
||||
})
|
||||
cancelFingerprintRef.current = undefined
|
||||
setRun(canceled)
|
||||
} catch (error) {
|
||||
if (isDefinitiveRequestFailure(error)) {
|
||||
cancelFingerprintRef.current = undefined
|
||||
setRequestError('CANCEL_FAILED')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const reconciled =
|
||||
await consoleClient.knowledgeFs.getKnowledgeSpacesByIdSourceWorkflowsByRunId({
|
||||
params: { id: knowledgeSpaceId, runId: run.id },
|
||||
})
|
||||
if (!isCancelConfirmed(reconciled)) {
|
||||
setRequestError('CANCEL_FAILED')
|
||||
} else {
|
||||
cancelFingerprintRef.current = undefined
|
||||
setRun(reconciled)
|
||||
}
|
||||
} catch {
|
||||
setRequestError('CANCEL_FAILED')
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
actionPendingRef.current = false
|
||||
setStopping(false)
|
||||
}
|
||||
}
|
||||
|
||||
const dispatchOperation = (operation: Promise<void>) => {
|
||||
onPendingOperation?.(operation)
|
||||
void operation
|
||||
}
|
||||
|
||||
const handlePrimaryAction = () => {
|
||||
if (!configuration) {
|
||||
setUrlTouched(true)
|
||||
if (!normalizedURL) rootUrlInputRef.current?.focus()
|
||||
else sourceNameInputRef.current?.focus()
|
||||
return
|
||||
}
|
||||
if (requestError === 'POLL_FAILED' && run) {
|
||||
setRequestError(undefined)
|
||||
setPollPaused(false)
|
||||
return
|
||||
}
|
||||
if (run && isSuccessful(run.state)) {
|
||||
const currentKey = configurationKey(configuration)
|
||||
dispatchOperation(
|
||||
startPreview(configuration, draftRef.current?.configurationKey === currentKey),
|
||||
)
|
||||
return
|
||||
}
|
||||
if (run && (isFailed(run.state) || isCanceled(run.state))) {
|
||||
const currentKey = configurationKey(configuration)
|
||||
if (draftRef.current?.configurationKey === currentKey) {
|
||||
dispatchOperation(retryRun())
|
||||
return
|
||||
}
|
||||
}
|
||||
dispatchOperation(startPreview(configuration))
|
||||
}
|
||||
|
||||
const handleSubmit = () => handlePrimaryAction()
|
||||
|
||||
const primaryLabel =
|
||||
starting || (active && !pollPaused)
|
||||
? t(($) => $['newKnowledge.crawling'])
|
||||
: (requestError && requestError !== 'CANCEL_FAILED') ||
|
||||
(run && (isFailed(run.state) || isCanceled(run.state)))
|
||||
? t(($) => $['newKnowledge.retryCrawl'])
|
||||
: run && isSuccessful(run.state) && pagesLoaded && pages.length === 0
|
||||
? t(($) => $['newKnowledge.adjustAndRecrawl'])
|
||||
: t(($) => $['newKnowledge.crawlAndPreview'])
|
||||
|
||||
const showFailure = Boolean(
|
||||
requestError === 'START_FAILED' ||
|
||||
requestError === 'RETRY_FAILED' ||
|
||||
requestError === 'POLL_FAILED' ||
|
||||
(run && isFailed(run.state)),
|
||||
)
|
||||
const showZero = Boolean(run && isSuccessful(run.state) && pagesLoaded && pages.length === 0)
|
||||
const showSuccess = Boolean(run && isSuccessful(run.state) && pages.length > 0)
|
||||
const showCanceled = Boolean(run && isCanceled(run.state))
|
||||
const errorCode = run?.lastErrorCode ?? requestError
|
||||
const is403 = errorCode?.includes('403')
|
||||
const isTimeout =
|
||||
errorCode?.toUpperCase().includes('TIMEOUT') ||
|
||||
(run ? ['timed_out', 'timeout'].includes(normalizedState(run.state)) : false)
|
||||
const isProviderError = errorCode?.toUpperCase().includes('PROVIDER')
|
||||
|
||||
return (
|
||||
<section aria-label={t(($) => $['newKnowledge.crawlAndPreview'])}>
|
||||
<p role="status" className="sr-only">
|
||||
{t(($) => $['newKnowledge.providerConnected'], { provider: providerName })}
|
||||
</p>
|
||||
<Form onFormSubmit={handleSubmit}>
|
||||
<div className={cn('mt-4 space-y-4', locked && 'opacity-70')}>
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
<Field
|
||||
name="root-url"
|
||||
className="gap-1.5"
|
||||
disabled={locked}
|
||||
invalid={urlTouched && !normalizedURL}
|
||||
touched={urlTouched}
|
||||
>
|
||||
<FieldLabel>
|
||||
{t(($) => $['newKnowledge.rootUrl'])}
|
||||
<span aria-hidden className="ml-0.5 text-text-destructive">
|
||||
*
|
||||
</span>
|
||||
</FieldLabel>
|
||||
<Input
|
||||
ref={rootUrlInputRef}
|
||||
name="root-url"
|
||||
type="url"
|
||||
required
|
||||
value={rootUrl}
|
||||
autoComplete="off"
|
||||
placeholder={t(($) => $['newKnowledge.rootUrlPlaceholder'])}
|
||||
onBlur={() => setUrlTouched(true)}
|
||||
onValueChange={setRootUrl}
|
||||
/>
|
||||
<FieldError id={rootUrlErrorId} match={urlTouched && !normalizedURL}>
|
||||
{t(($) => $['newKnowledge.invalidRootUrl'])}
|
||||
</FieldError>
|
||||
</Field>
|
||||
<Field name="source-name" className="gap-1.5" disabled={locked}>
|
||||
<FieldLabel>
|
||||
{t(($) => $['newKnowledge.sourceName'])}
|
||||
<span aria-hidden className="ml-0.5 text-text-destructive">
|
||||
*
|
||||
</span>
|
||||
</FieldLabel>
|
||||
<Input
|
||||
ref={sourceNameInputRef}
|
||||
name="source-name"
|
||||
type="text"
|
||||
required
|
||||
maxLength={MAX_SOURCE_NAME_LENGTH}
|
||||
value={sourceName}
|
||||
autoComplete="off"
|
||||
placeholder={t(($) => $['newKnowledge.sourceNamePlaceholder'])}
|
||||
onValueChange={setSourceName}
|
||||
/>
|
||||
<FieldError match="valueMissing">
|
||||
{t(($) => $['newKnowledge.sourceNameRequired'])}
|
||||
</FieldError>
|
||||
</Field>
|
||||
</div>
|
||||
<div className="overflow-hidden rounded-lg border border-components-option-card-option-border bg-background-default">
|
||||
<button
|
||||
type="button"
|
||||
aria-expanded={optionsExpanded}
|
||||
disabled={locked}
|
||||
className="flex h-9 w-full items-center gap-2 px-3 text-left outline-hidden focus-visible:ring-2 focus-visible:ring-state-accent-solid focus-visible:ring-inset"
|
||||
onClick={() => setOptionsExpanded((expanded) => !expanded)}
|
||||
>
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn(
|
||||
'i-ri-arrow-right-s-line size-4 text-text-tertiary transition-transform',
|
||||
optionsExpanded && 'rotate-90',
|
||||
)}
|
||||
/>
|
||||
<span className="system-xs-medium text-text-primary">
|
||||
{t(($) => $['newKnowledge.crawlOptions'])}
|
||||
</span>
|
||||
{!optionsExpanded && includeSubpages && pageLimit === DEFAULT_PAGE_LIMIT && (
|
||||
<span className="ml-auto system-xs-regular text-text-tertiary">
|
||||
{t(($) => $['newKnowledge.usingDefaults'])}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
{optionsExpanded && (
|
||||
<div className="grid grid-cols-1 gap-3 border-t border-divider-subtle p-3 sm:grid-cols-2">
|
||||
<Field name="include-subpages" className="block" disabled={locked}>
|
||||
<FieldLabel className="flex h-9 items-center gap-2 system-xs-regular text-text-secondary">
|
||||
<Checkbox
|
||||
name="include-subpages"
|
||||
checked={includeSubpages}
|
||||
onCheckedChange={setIncludeSubpages}
|
||||
/>
|
||||
{t(($) => $['newKnowledge.includeSubpages'])}
|
||||
</FieldLabel>
|
||||
</Field>
|
||||
<Field
|
||||
name="page-limit"
|
||||
className="grid grid-cols-[1fr_6rem] items-center gap-2"
|
||||
disabled={locked}
|
||||
>
|
||||
<FieldLabel className="system-xs-regular text-text-secondary">
|
||||
{t(($) => $['newKnowledge.maxPages'])}
|
||||
</FieldLabel>
|
||||
<NumberField
|
||||
disabled={locked}
|
||||
min={1}
|
||||
max={MAX_PAGE_LIMIT}
|
||||
value={pageLimit}
|
||||
onValueChange={(value) => setPageLimit(value ?? 1)}
|
||||
>
|
||||
<NumberFieldGroup>
|
||||
<NumberFieldInput name="page-limit" autoComplete="off" />
|
||||
</NumberFieldGroup>
|
||||
</NumberField>
|
||||
</Field>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!showSuccess && (
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
className="mt-4 w-full"
|
||||
disabled={locked && requestError !== 'POLL_FAILED'}
|
||||
loading={starting}
|
||||
>
|
||||
{primaryLabel}
|
||||
</Button>
|
||||
)}
|
||||
</Form>
|
||||
|
||||
<div className="mt-4">
|
||||
{!run && !requestError && <EmptyPreview />}
|
||||
{run && active && !pollPaused && (
|
||||
<div className="overflow-hidden rounded-xl border border-divider-regular">
|
||||
<div className="flex flex-wrap items-center gap-2 px-4 py-3">
|
||||
<span
|
||||
aria-hidden
|
||||
className="i-ri-loader-4-line size-4 animate-spin text-text-accent motion-reduce:animate-none"
|
||||
/>
|
||||
<span
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
className="min-w-0 flex-1 truncate system-xs-medium text-text-primary"
|
||||
title={crawlingStatusText}
|
||||
>
|
||||
{crawlingStatusText}
|
||||
</span>
|
||||
<Button
|
||||
type="button"
|
||||
variant="tertiary"
|
||||
size="small"
|
||||
className="ml-auto shrink-0"
|
||||
disabled={stopping}
|
||||
onClick={() => dispatchOperation(stop())}
|
||||
>
|
||||
{stopping
|
||||
? t(($) => $['newKnowledge.stoppingCrawl'])
|
||||
: t(($) => $['newKnowledge.stopCrawl'])}
|
||||
</Button>
|
||||
</div>
|
||||
{requestError === 'CANCEL_FAILED' && (
|
||||
<p role="alert" className="px-4 pb-3 system-xs-regular text-text-destructive">
|
||||
{t(($) => $['newKnowledge.crawlFailedDescription'])}
|
||||
</p>
|
||||
)}
|
||||
{run.progressTotal !== undefined && run.progressTotal > 0 && (
|
||||
<progress
|
||||
max={run.progressTotal}
|
||||
value={Math.min(completedCount, run.progressTotal)}
|
||||
aria-label={t(($) => $['newKnowledge.crawlProgress'], { host: previewHost })}
|
||||
className="block h-1 w-full accent-state-accent-solid"
|
||||
/>
|
||||
)}
|
||||
<CrawlPageList pages={pages} loading />
|
||||
</div>
|
||||
)}
|
||||
{showSuccess && (
|
||||
<div className="overflow-hidden rounded-xl border border-divider-regular">
|
||||
<div className="flex flex-wrap items-center gap-2 px-4 py-3">
|
||||
<p
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
className="min-w-0 flex-1 truncate system-xs-semibold text-text-primary"
|
||||
title={completedStatusText}
|
||||
>
|
||||
{completedStatusText}
|
||||
</p>
|
||||
<Button
|
||||
type="button"
|
||||
variant="tertiary"
|
||||
size="small"
|
||||
className="ml-auto shrink-0"
|
||||
disabled={starting || !configuration}
|
||||
loading={starting}
|
||||
onClick={handlePrimaryAction}
|
||||
>
|
||||
{t(($) => $['newKnowledge.reCrawl'])}
|
||||
</Button>
|
||||
</div>
|
||||
<CrawlPageList pages={pages} />
|
||||
</div>
|
||||
)}
|
||||
{showCanceled && (
|
||||
<div className="overflow-hidden rounded-xl border border-divider-regular">
|
||||
<p
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
className="px-4 py-3 system-xs-semibold text-text-primary"
|
||||
>
|
||||
{t(($) => $['newKnowledge.crawlStopped'])}
|
||||
</p>
|
||||
<CrawlPageList pages={pages} />
|
||||
</div>
|
||||
)}
|
||||
{showFailure && (
|
||||
<div
|
||||
role="alert"
|
||||
className="flex min-h-36 flex-col items-center justify-center rounded-xl border border-divider-regular px-6 text-center"
|
||||
>
|
||||
<span aria-hidden className="i-ri-error-warning-fill size-6 text-text-destructive" />
|
||||
<p className="mt-2 system-sm-semibold text-text-primary">
|
||||
{t(($) => $['newKnowledge.crawlFailed'], { host: previewHost })}
|
||||
</p>
|
||||
<p className="mt-1 max-w-lg system-xs-regular text-text-tertiary">
|
||||
{is403
|
||||
? t(($) => $['newKnowledge.crawlFailed403'])
|
||||
: isTimeout
|
||||
? t(($) => $['newKnowledge.crawlFailedTimeout'])
|
||||
: isProviderError
|
||||
? t(($) => $['newKnowledge.crawlFailedProvider'], {
|
||||
provider: providerName,
|
||||
})
|
||||
: requestError === 'START_FAILED'
|
||||
? t(($) => $['newKnowledge.crawlStartFailed'])
|
||||
: t(($) => $['newKnowledge.crawlFailedDescription'])}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{showZero && !showFailure && (
|
||||
<div
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
className="flex min-h-40 flex-col items-center justify-center rounded-xl border border-divider-regular px-6 text-center"
|
||||
>
|
||||
<span className="flex size-10 items-center justify-center rounded-lg bg-background-section">
|
||||
<span aria-hidden className="i-ri-global-line size-5 text-text-tertiary" />
|
||||
</span>
|
||||
<p className="mt-2 system-xs-semibold text-text-primary">
|
||||
{t(($) => $['newKnowledge.noPagesFound'], { host: previewHost })}
|
||||
</p>
|
||||
<p className="mt-2 max-w-lg system-xs-regular text-text-tertiary">
|
||||
{t(($) => $['newKnowledge.noPagesFoundDescription'])}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "الإجراءات",
|
||||
"newKnowledge.addSource": "أضف المصدر",
|
||||
"newKnowledge.addSourceDescription": "قم بتوصيل مصدر بقاعدة المعرفة هذه - تتم مزامنته تلقائيًا ويظل محدثًا.",
|
||||
"newKnowledge.addSourceRequiresSelection": "حدّد صفحة واحدة على الأقل من الصفحات التي تم الزحف إليها قبل إضافة المصدر.",
|
||||
"newKnowledge.adjustAndRecrawl": "الضبط وإعادة الزحف",
|
||||
"newKnowledge.allSources": "جميع المصادر",
|
||||
"newKnowledge.appsUnavailable": "— تطبيقات",
|
||||
"newKnowledge.authKind.api-key": "مفتاح API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "قم بتحديث الاتصال قبل إضافة مصدر موقع الويب.",
|
||||
"newKnowledge.connectionProvisioning": "جارٍ الاتصال بـ {{provider}}",
|
||||
"newKnowledge.connectionRefreshFailed": "لم نتمكن من تحديث هذا الاتصال. حاول ثانية.",
|
||||
"newKnowledge.crawlAndPreview": "الزحف والمعاينة",
|
||||
"newKnowledge.crawlFailed": "تعذّر الزحف إلى {{host}}",
|
||||
"newKnowledge.crawlFailed403": "أعاد الموقع الخطأ 403 — قد يحظر برامج الزحف أو يتطلب المصادقة. تحقّق من عنوان URL أو عدّل خيارات الزحف أو جرّب موفّرًا آخر.",
|
||||
"newKnowledge.crawlFailedDescription": "تعذّر على برنامج الزحف إكمال هذه المعاينة. تحقّق من عنوان URL أو عدّل خيارات الزحف أو أعد المحاولة.",
|
||||
"newKnowledge.crawlFailedProvider": "أبلغ {{provider}} عن خطأ. تحقّق من اتصال الموفّر وأعد المحاولة.",
|
||||
"newKnowledge.crawlFailedTimeout": "انتهت مهلة الزحف. جرّب عنوان URL أكثر تحديدًا أو قلّل الحد الأقصى لعدد الصفحات.",
|
||||
"newKnowledge.crawlOptions": "خيارات الزحف",
|
||||
"newKnowledge.crawlProgress": "تقدّم الزحف إلى {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "يتم تعطيل تكوين الزحف إلى موقع الويب حتى يتوفر سير عمل الزحف.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "الزحف الناري جاهز",
|
||||
"newKnowledge.crawlStartFailed": "تعذّر بدء معاينة الزحف. أعد المحاولة.",
|
||||
"newKnowledge.crawlStopped": "تم إيقاف الزحف",
|
||||
"newKnowledge.crawling": "جارٍ الزحف…",
|
||||
"newKnowledge.crawlingPages": "جارٍ الزحف إلى {{host}}… تم العثور على {{count}} صفحة",
|
||||
"newKnowledge.createFailed": "لم نتمكن من إنشاء قاعدة المعرفة هذه. تحقق من وصولك وحاول مرة أخرى.",
|
||||
"newKnowledge.createTitle": "خلق المعرفة",
|
||||
"newKnowledge.creators": "المنشئون",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "تجاهل المسودة",
|
||||
"newKnowledge.discardDraftDescription": "ستُفقد تغييراتك على مسودة قاعدة المعرفة هذه.",
|
||||
"newKnowledge.discardDraftTitle": "تجاهل مسودة قاعدة المعرفة هذه؟",
|
||||
"newKnowledge.discardSourceDraftDescription": "ستتم إزالة إعداد المصدر ومعاينة الزحف.",
|
||||
"newKnowledge.discardSourceDraftFailed": "تعذّر تجاهل مسودة المصدر. أعد المحاولة.",
|
||||
"newKnowledge.discardSourceDraftTitle": "هل تريد تجاهل مسودة المصدر هذه؟",
|
||||
"newKnowledge.documents": "المستندات",
|
||||
"newKnowledge.documentsUnavailable": "— مستندات",
|
||||
"newKnowledge.emptyDescription": "أضف مستنداتك ليتمكن الوكلاء من قراءتها مباشرة — من دون إعداد الفهرسة.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "اربط مصدرًا وستبقى مستنداته متزامنة ومفهرسة تلقائيًا وجاهزة للاستخدام، من دون إعدادات تحتاج إلى إدارة. ستواصل قواعد المعرفة السابقة العمل كما هي.",
|
||||
"newKnowledge.guideTitle": "تعرّف على قاعدة المعرفة الجديدة ✨",
|
||||
"newKnowledge.illustrationHeadline": "اربط محتواك مرة واحدة — ليجيب كل تطبيق بأحدث معرفة.",
|
||||
"newKnowledge.includeSubpages": "تضمين الصفحات الفرعية",
|
||||
"newKnowledge.invalidRootUrl": "أدخل عنوان URL صالحًا يبدأ بـ http(s).",
|
||||
"newKnowledge.lastSyncColumn": "آخر مزامنة",
|
||||
"newKnowledge.learnMore": "معرفة المزيد",
|
||||
"newKnowledge.leavePartialSetupConfirm": "مغادرة الإعداد",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "مغادرة الإعداد غير المكتمل؟",
|
||||
"newKnowledge.legacy": "قديم",
|
||||
"newKnowledge.loadMore": "تحميل المزيد",
|
||||
"newKnowledge.maxPages": "الحد الأقصى للصفحات",
|
||||
"newKnowledge.moreProviders": "عرض المزيد",
|
||||
"newKnowledge.name": "اسم المعرفة",
|
||||
"newKnowledge.namePlaceholder": "على سبيل المثال دليل دعم العملاء",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "جديد",
|
||||
"newKnowledge.noDescription": "لا يوجد وصف",
|
||||
"newKnowledge.noMatchingSources": "لا توجد مصادر تطابق هذا البحث.",
|
||||
"newKnowledge.noPagesFound": "لم يتم العثور على صفحات في {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "وصل برنامج الزحف إلى الموقع لكنه لم يجد صفحات قابلة للفهرسة. جرّب عنوان URL مختلفًا أو وسّع خيارات الزحف.",
|
||||
"newKnowledge.notFoundDescription": "ربما تم حذف قاعدة المعرفة هذه أو ربما لا يمكنك الوصول إليها.",
|
||||
"newKnowledge.notFoundTitle": "لم يتم العثور على قاعدة المعرفة",
|
||||
"newKnowledge.onlineDocuments": "المستندات عبر الإنترنت",
|
||||
"newKnowledge.onlineDrive": "محرك الأقراص عبر الإنترنت",
|
||||
"newKnowledge.pagesAppearDescription": "ازحف إلى الموقع لمراجعة الصفحات التي ستتم إضافتها.",
|
||||
"newKnowledge.pagesAppearTitle": "ستظهر الصفحات هنا",
|
||||
"newKnowledge.pagesCrawled": "تم الزحف إلى {{count}} صفحة في {{host}}",
|
||||
"newKnowledge.permission": "إذن",
|
||||
"newKnowledge.permissionAllMembers": "مساحة العمل · يمكن لجميع الأعضاء العرض والتحرير",
|
||||
"newKnowledge.permissionOnlyMe": "أنا فقط",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} لم يتم تكوينه",
|
||||
"newKnowledge.providerNotConfiguredDescription": "أضف مفتاح API أو عنوان URL لنقطة النهاية للزحف إلى مواقع الويب باستخدام {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "هذا الموفر غير متوفر.",
|
||||
"newKnowledge.reCrawl": "إعادة الزحف",
|
||||
"newKnowledge.readOnlyEmpty": "اطلب من محرر مساحة العمل إنشاء أول قاعدة معرفة.",
|
||||
"newKnowledge.refreshConnectionStatus": "تحديث الحالة",
|
||||
"newKnowledge.refreshingConnection": "منعش…",
|
||||
"newKnowledge.removeSource": "قم بإزالة المصدر",
|
||||
"newKnowledge.retryCrawl": "إعادة محاولة الزحف",
|
||||
"newKnowledge.retryProviderLoad": "أعد المحاولة",
|
||||
"newKnowledge.rootUrl": "عنوان URL الجذر",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "سيصبح هذا القسم متاحًا في خطوة الإعداد التالية.",
|
||||
"newKnowledge.searchSources": "مصادر البحث",
|
||||
"newKnowledge.sourceActions": "إجراءات {{name}}",
|
||||
"newKnowledge.sourceColumn": "المصدر",
|
||||
"newKnowledge.sourceFilterLabel": "تصفية المصادر حسب الحالة",
|
||||
"newKnowledge.sourceName": "اسم المصدر",
|
||||
"newKnowledge.sourceNamePlaceholder": "مثال: الزحف إلى وثائق المنتج",
|
||||
"newKnowledge.sourceNameRequired": "أدخل اسمًا للمصدر.",
|
||||
"newKnowledge.sourceStatus.active": "نشط",
|
||||
"newKnowledge.sourceStatus.disabled": "معطل",
|
||||
"newKnowledge.sourceStatus.error": "خطأ",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "ابدأ ب",
|
||||
"newKnowledge.startWithHelp": "يمكنك إضافة المزيد من المصادر أو المستندات في أي وقت.",
|
||||
"newKnowledge.statusColumn": "الحالة",
|
||||
"newKnowledge.stopCrawl": "إيقاف",
|
||||
"newKnowledge.stoppingCrawl": "جارٍ الإيقاف…",
|
||||
"newKnowledge.syncNow": "المزامنة الآن",
|
||||
"newKnowledge.syncPolicyColumn": "سياسة المزامنة",
|
||||
"newKnowledge.tags": "الوسوم",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "تم التحديث في {{date}}",
|
||||
"newKnowledge.uploadFiles": "رفع الملفات",
|
||||
"newKnowledge.uploadFilesDescription": "أضف ملفات من جهازك — ستتم فهرستها بمجرد إنشائها.",
|
||||
"newKnowledge.usingDefaults": "استخدام الإعدادات الافتراضية",
|
||||
"newKnowledge.viewLabel": "عرض المعرفة",
|
||||
"newKnowledge.websiteCrawl": "الزحف إلى موقع الويب",
|
||||
"noExternalKnowledge": "لا توجد واجهة برمجة تطبيقات معرفة خارجية حتى الآن، انقر هنا لإنشاء",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Aktionen",
|
||||
"newKnowledge.addSource": "Quelle hinzufügen",
|
||||
"newKnowledge.addSourceDescription": "Verbinden Sie eine Quelle mit dieser Wissensdatenbank – sie wird automatisch synchronisiert und bleibt aktuell.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Wähle mindestens eine gecrawlte Seite aus, bevor du die Quelle hinzufügst.",
|
||||
"newKnowledge.adjustAndRecrawl": "Anpassen und erneut crawlen",
|
||||
"newKnowledge.allSources": "Alle Quellen",
|
||||
"newKnowledge.appsUnavailable": "— Apps",
|
||||
"newKnowledge.authKind.api-key": "API-Schlüssel",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Aktualisieren Sie die Verbindung, bevor Sie eine Website-Quelle hinzufügen.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} stellt eine Verbindung her",
|
||||
"newKnowledge.connectionRefreshFailed": "Wir konnten diese Verbindung nicht aktualisieren. Versuchen Sie es erneut.",
|
||||
"newKnowledge.crawlAndPreview": "Crawlen und Vorschau",
|
||||
"newKnowledge.crawlFailed": "{{host}} konnte nicht gecrawlt werden",
|
||||
"newKnowledge.crawlFailed403": "Die Website hat 403 zurückgegeben – möglicherweise blockiert sie Crawler oder erfordert eine Authentifizierung. Prüfe die URL, passe die Crawl-Optionen an oder versuche einen anderen Anbieter.",
|
||||
"newKnowledge.crawlFailedDescription": "Der Crawler konnte diese Vorschau nicht abschließen. Prüfe die URL, passe die Crawl-Optionen an oder versuche es erneut.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} hat einen Fehler gemeldet. Prüfe die Anbieterverbindung und versuche es erneut.",
|
||||
"newKnowledge.crawlFailedTimeout": "Zeitüberschreitung beim Crawlen. Versuche eine spezifischere URL oder reduziere die maximale Seitenzahl.",
|
||||
"newKnowledge.crawlOptions": "Crawl-Optionen",
|
||||
"newKnowledge.crawlProgress": "Crawl-Fortschritt für {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Die Website-Crawling-Konfiguration ist deaktiviert, bis der Crawl-Workflow verfügbar ist.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl ist bereit",
|
||||
"newKnowledge.crawlStartFailed": "Die Crawl-Vorschau konnte nicht gestartet werden. Versuche es erneut.",
|
||||
"newKnowledge.crawlStopped": "Crawl gestoppt",
|
||||
"newKnowledge.crawling": "Wird gecrawlt…",
|
||||
"newKnowledge.crawlingPages": "{{host}} wird gecrawlt… {{count}} Seiten gefunden",
|
||||
"newKnowledge.createFailed": "Wir konnten diese Wissensdatenbank nicht erstellen. Überprüfen Sie Ihren Zugang und versuchen Sie es erneut.",
|
||||
"newKnowledge.createTitle": "Wissen schaffen",
|
||||
"newKnowledge.creators": "Ersteller",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Entwurf verwerfen",
|
||||
"newKnowledge.discardDraftDescription": "Ihre Änderungen an diesem Wissensdatenbank-Entwurf gehen verloren.",
|
||||
"newKnowledge.discardDraftTitle": "Diesen Wissensdatenbank-Entwurf verwerfen?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Die Quellenkonfiguration und die Crawl-Vorschau werden entfernt.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Der Quellenentwurf konnte nicht verworfen werden. Versuche es erneut.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Diesen Quellenentwurf verwerfen?",
|
||||
"newKnowledge.documents": "Dokumente",
|
||||
"newKnowledge.documentsUnavailable": "— Dokumente",
|
||||
"newKnowledge.emptyDescription": "Fügen Sie Ihre Dokumente hinzu, damit Agents sie direkt lesen können — ohne eine Indizierung einzurichten.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Verbinden Sie eine Quelle, und ihre Dokumente bleiben synchron — automatisch indiziert und sofort einsatzbereit, ohne Verwaltungsaufwand. Ihre bisherigen Wissensdatenbanken funktionieren unverändert weiter.",
|
||||
"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.invalidRootUrl": "Gib eine gültige http(s)-URL ein.",
|
||||
"newKnowledge.lastSyncColumn": "Letzte Synchronisierung",
|
||||
"newKnowledge.learnMore": "Mehr erfahren",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Einrichtung verlassen",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Unvollständige Einrichtung verlassen?",
|
||||
"newKnowledge.legacy": "Legacy",
|
||||
"newKnowledge.loadMore": "Mehr laden",
|
||||
"newKnowledge.maxPages": "Maximale Seitenzahl",
|
||||
"newKnowledge.moreProviders": "Mehr anzeigen",
|
||||
"newKnowledge.name": "Wissensname",
|
||||
"newKnowledge.namePlaceholder": "z.B. Kundendiensthandbuch",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Neu",
|
||||
"newKnowledge.noDescription": "Keine Beschreibung",
|
||||
"newKnowledge.noMatchingSources": "Keine Quellen passen zu dieser Suche.",
|
||||
"newKnowledge.noPagesFound": "Keine Seiten unter {{host}} gefunden",
|
||||
"newKnowledge.noPagesFoundDescription": "Der Crawler hat die Website erreicht, aber keine indexierbaren Seiten gefunden. Versuche eine andere URL oder erweitere die Crawl-Optionen.",
|
||||
"newKnowledge.notFoundDescription": "Diese Wissensdatenbank wurde möglicherweise gelöscht oder Sie haben keinen Zugriff darauf.",
|
||||
"newKnowledge.notFoundTitle": "Wissensdatenbank nicht gefunden",
|
||||
"newKnowledge.onlineDocuments": "Online-Dokumente",
|
||||
"newKnowledge.onlineDrive": "Online-Laufwerk",
|
||||
"newKnowledge.pagesAppearDescription": "Crawle die Website, um zu prüfen, welche Seiten hinzugefügt werden.",
|
||||
"newKnowledge.pagesAppearTitle": "Seiten werden hier angezeigt",
|
||||
"newKnowledge.pagesCrawled": "{{count}} Seiten unter {{host}} gecrawlt",
|
||||
"newKnowledge.permission": "Erlaubnis",
|
||||
"newKnowledge.permissionAllMembers": "Arbeitsbereich · Alle Mitglieder können ihn ansehen und bearbeiten",
|
||||
"newKnowledge.permissionOnlyMe": "Nur ich",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} ist nicht konfiguriert",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Fügen Sie einen API-Schlüssel oder eine Endpunkt-URL hinzu, um Websites mit {{provider}} zu crawlen.",
|
||||
"newKnowledge.providerUnavailable": "Dieser Anbieter ist nicht verfügbar.",
|
||||
"newKnowledge.reCrawl": "Erneut crawlen",
|
||||
"newKnowledge.readOnlyEmpty": "Bitten Sie einen Arbeitsbereich-Editor, die erste Wissensdatenbank zu erstellen.",
|
||||
"newKnowledge.refreshConnectionStatus": "Status aktualisieren",
|
||||
"newKnowledge.refreshingConnection": "Erfrischend…",
|
||||
"newKnowledge.removeSource": "Quelle entfernen",
|
||||
"newKnowledge.retryCrawl": "Crawl wiederholen",
|
||||
"newKnowledge.retryProviderLoad": "Wiederholen",
|
||||
"newKnowledge.rootUrl": "Stamm-URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Dieser Abschnitt wird im nächsten Einrichtungsschritt verfügbar.",
|
||||
"newKnowledge.searchSources": "Quellen durchsuchen",
|
||||
"newKnowledge.sourceActions": "Aktionen für {{name}}",
|
||||
"newKnowledge.sourceColumn": "Quelle",
|
||||
"newKnowledge.sourceFilterLabel": "Quellen nach Status filtern",
|
||||
"newKnowledge.sourceName": "Quellenname",
|
||||
"newKnowledge.sourceNamePlaceholder": "z. B. Crawl der Produktdokumentation",
|
||||
"newKnowledge.sourceNameRequired": "Gib einen Quellennamen ein.",
|
||||
"newKnowledge.sourceStatus.active": "Aktiv",
|
||||
"newKnowledge.sourceStatus.disabled": "Deaktiviert",
|
||||
"newKnowledge.sourceStatus.error": "Fehler",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Beginnen Sie mit",
|
||||
"newKnowledge.startWithHelp": "Sie können jederzeit weitere Quellen oder Dokumente hinzufügen.",
|
||||
"newKnowledge.statusColumn": "Status",
|
||||
"newKnowledge.stopCrawl": "Stoppen",
|
||||
"newKnowledge.stoppingCrawl": "Wird gestoppt…",
|
||||
"newKnowledge.syncNow": "Jetzt synchronisieren",
|
||||
"newKnowledge.syncPolicyColumn": "Synchronisierungsrichtlinie",
|
||||
"newKnowledge.tags": "Tags",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Aktualisiert am {{date}}",
|
||||
"newKnowledge.uploadFiles": "Dateien hochladen",
|
||||
"newKnowledge.uploadFilesDescription": "Fügen Sie Dateien von Ihrem Computer hinzu — sie werden beim Erstellen sofort indiziert.",
|
||||
"newKnowledge.usingDefaults": "Standardeinstellungen werden verwendet",
|
||||
"newKnowledge.viewLabel": "Wissensansicht",
|
||||
"newKnowledge.websiteCrawl": "Website-Crawling",
|
||||
"noExternalKnowledge": "Es gibt noch keine External Knowledge API, klicken Sie hier, um zu erstellen",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Actions",
|
||||
"newKnowledge.addSource": "Add source",
|
||||
"newKnowledge.addSourceDescription": "Connect a source to this knowledge base — it syncs automatically and stays fresh.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Select at least one crawled page before adding the source.",
|
||||
"newKnowledge.adjustAndRecrawl": "Adjust & re-crawl",
|
||||
"newKnowledge.allSources": "All sources",
|
||||
"newKnowledge.appsUnavailable": "— apps",
|
||||
"newKnowledge.authKind.api-key": "API key",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Refresh the connection before adding a website source.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} is connecting",
|
||||
"newKnowledge.connectionRefreshFailed": "We couldn't refresh this connection. Try again.",
|
||||
"newKnowledge.crawlAndPreview": "Crawl & preview",
|
||||
"newKnowledge.crawlFailed": "Couldn't crawl {{host}}",
|
||||
"newKnowledge.crawlFailed403": "The site returned 403 — it may block crawlers or require authentication. Check the URL, adjust crawl options, or try another provider.",
|
||||
"newKnowledge.crawlFailedDescription": "The crawler couldn't finish this preview. Check the URL, adjust crawl options, or try again.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} reported an error. Check the provider connection and try again.",
|
||||
"newKnowledge.crawlFailedTimeout": "The crawl timed out. Try a narrower URL or reduce the maximum page count.",
|
||||
"newKnowledge.crawlOptions": "Crawl options",
|
||||
"newKnowledge.crawlProgress": "Crawl progress for {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Website crawl configuration is disabled until the crawl workflow is available.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl is ready",
|
||||
"newKnowledge.crawlStartFailed": "The crawl preview couldn't start. Try again.",
|
||||
"newKnowledge.crawlStopped": "Crawl stopped",
|
||||
"newKnowledge.crawling": "Crawling…",
|
||||
"newKnowledge.crawlingPages": "Crawling {{host}}… {{count}} pages found",
|
||||
"newKnowledge.createFailed": "We couldn't create this knowledge base. Check your access and try again.",
|
||||
"newKnowledge.createTitle": "Create Knowledge",
|
||||
"newKnowledge.creators": "Creators",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Discard draft",
|
||||
"newKnowledge.discardDraftDescription": "Your changes to this knowledge base draft will be lost.",
|
||||
"newKnowledge.discardDraftTitle": "Discard this knowledge base draft?",
|
||||
"newKnowledge.discardSourceDraftDescription": "The source configuration and crawl preview will be removed.",
|
||||
"newKnowledge.discardSourceDraftFailed": "We couldn’t discard the source draft. Try again.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Discard this source draft?",
|
||||
"newKnowledge.documents": "Documents",
|
||||
"newKnowledge.documentsUnavailable": "— documents",
|
||||
"newKnowledge.emptyDescription": "Add your documents and agents can read them directly — no indexing to configure.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Connect a Source and its Documents stay in sync — indexed automatically and ready to use, with no setup to manage. Your Legacy knowledge bases keep working as-is.",
|
||||
"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.invalidRootUrl": "Enter a valid http(s) URL.",
|
||||
"newKnowledge.lastSyncColumn": "Last sync",
|
||||
"newKnowledge.learnMore": "Learn more",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Leave setup",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Leave incomplete setup?",
|
||||
"newKnowledge.legacy": "Legacy",
|
||||
"newKnowledge.loadMore": "Load more",
|
||||
"newKnowledge.maxPages": "Maximum pages",
|
||||
"newKnowledge.moreProviders": "More providers",
|
||||
"newKnowledge.name": "Knowledge name",
|
||||
"newKnowledge.namePlaceholder": "e.g. Customer Support Handbook",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "New",
|
||||
"newKnowledge.noDescription": "No description",
|
||||
"newKnowledge.noMatchingSources": "No sources match this search.",
|
||||
"newKnowledge.noPagesFound": "No pages found at {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "The crawler reached the site but found no indexable pages. Try a different URL, or expand crawl options.",
|
||||
"newKnowledge.notFoundDescription": "This knowledge base may have been deleted or you may not have access.",
|
||||
"newKnowledge.notFoundTitle": "Knowledge base not found",
|
||||
"newKnowledge.onlineDocuments": "Online documents",
|
||||
"newKnowledge.onlineDrive": "Online drive",
|
||||
"newKnowledge.pagesAppearDescription": "Crawl the site to review which pages get added.",
|
||||
"newKnowledge.pagesAppearTitle": "Pages will appear here",
|
||||
"newKnowledge.pagesCrawled": "{{count}} pages crawled at {{host}}",
|
||||
"newKnowledge.permission": "Permission",
|
||||
"newKnowledge.permissionAllMembers": "Workspace · all members can view and edit",
|
||||
"newKnowledge.permissionOnlyMe": "Only me",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} is not configured",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Add an API key or endpoint URL to crawl websites with {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "This provider is unavailable.",
|
||||
"newKnowledge.reCrawl": "Re-crawl",
|
||||
"newKnowledge.readOnlyEmpty": "Ask a workspace editor to create the first knowledge base.",
|
||||
"newKnowledge.refreshConnectionStatus": "Refresh status",
|
||||
"newKnowledge.refreshingConnection": "Refreshing…",
|
||||
"newKnowledge.removeSource": "Remove source",
|
||||
"newKnowledge.retryCrawl": "Retry crawl",
|
||||
"newKnowledge.retryProviderLoad": "Retry",
|
||||
"newKnowledge.rootUrl": "Root URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "This section will become available in the next setup step.",
|
||||
"newKnowledge.searchSources": "Search sources",
|
||||
"newKnowledge.sourceActions": "Actions for {{name}}",
|
||||
"newKnowledge.sourceColumn": "Source",
|
||||
"newKnowledge.sourceFilterLabel": "Filter sources by status",
|
||||
"newKnowledge.sourceName": "Source name",
|
||||
"newKnowledge.sourceNamePlaceholder": "e.g. Product docs crawl",
|
||||
"newKnowledge.sourceNameRequired": "Enter a source name.",
|
||||
"newKnowledge.sourceStatus.active": "Active",
|
||||
"newKnowledge.sourceStatus.disabled": "Disabled",
|
||||
"newKnowledge.sourceStatus.error": "Error",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Start with",
|
||||
"newKnowledge.startWithHelp": "You can add more Sources or Documents anytime.",
|
||||
"newKnowledge.statusColumn": "Status",
|
||||
"newKnowledge.stopCrawl": "Stop",
|
||||
"newKnowledge.stoppingCrawl": "Stopping…",
|
||||
"newKnowledge.syncNow": "Sync now",
|
||||
"newKnowledge.syncPolicyColumn": "Sync policy",
|
||||
"newKnowledge.tags": "Tags",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Updated {{date}}",
|
||||
"newKnowledge.uploadFiles": "Upload files",
|
||||
"newKnowledge.uploadFilesDescription": "Add files from your computer — they're indexed as soon as you create.",
|
||||
"newKnowledge.usingDefaults": "Using defaults",
|
||||
"newKnowledge.viewLabel": "Knowledge view",
|
||||
"newKnowledge.websiteCrawl": "Website crawl",
|
||||
"noExternalKnowledge": "There is no External Knowledge API yet, click here to create",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Acciones",
|
||||
"newKnowledge.addSource": "Agregar fuente",
|
||||
"newKnowledge.addSourceDescription": "Conecte una fuente a esta base de conocimientos: se sincroniza automáticamente y se mantiene actualizada.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Selecciona al menos una página rastreada antes de añadir la fuente.",
|
||||
"newKnowledge.adjustAndRecrawl": "Ajustar y volver a rastrear",
|
||||
"newKnowledge.allSources": "Todas las fuentes",
|
||||
"newKnowledge.appsUnavailable": "— aplicaciones",
|
||||
"newKnowledge.authKind.api-key": "Clave API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Actualiza la conexión antes de agregar una fuente de sitio web.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} se está conectando",
|
||||
"newKnowledge.connectionRefreshFailed": "No pudimos actualizar esta conexión. Intentar otra vez.",
|
||||
"newKnowledge.crawlAndPreview": "Rastreo y vista previa",
|
||||
"newKnowledge.crawlFailed": "No se pudo rastrear {{host}}",
|
||||
"newKnowledge.crawlFailed403": "El sitio devolvió un error 403; puede que bloquee rastreadores o requiera autenticación. Comprueba la URL, ajusta las opciones de rastreo o prueba otro proveedor.",
|
||||
"newKnowledge.crawlFailedDescription": "El rastreador no pudo completar esta vista previa. Comprueba la URL, ajusta las opciones de rastreo o vuelve a intentarlo.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} informó de un error. Comprueba la conexión del proveedor y vuelve a intentarlo.",
|
||||
"newKnowledge.crawlFailedTimeout": "El rastreo agotó el tiempo de espera. Prueba una URL más específica o reduce el número máximo de páginas.",
|
||||
"newKnowledge.crawlOptions": "Opciones de rastreo",
|
||||
"newKnowledge.crawlProgress": "Progreso del rastreo de {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "La configuración de rastreo del sitio web está deshabilitada hasta que el flujo de trabajo de rastreo esté disponible.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl está listo",
|
||||
"newKnowledge.crawlStartFailed": "No se pudo iniciar la vista previa del rastreo. Vuelve a intentarlo.",
|
||||
"newKnowledge.crawlStopped": "Rastreo detenido",
|
||||
"newKnowledge.crawling": "Rastreando…",
|
||||
"newKnowledge.crawlingPages": "Rastreando {{host}}… {{count}} páginas encontradas",
|
||||
"newKnowledge.createFailed": "No pudimos crear esta base de conocimientos. Comprueba tu acceso y vuelve a intentarlo.",
|
||||
"newKnowledge.createTitle": "Crear conocimiento",
|
||||
"newKnowledge.creators": "Creadores",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Descartar borrador",
|
||||
"newKnowledge.discardDraftDescription": "Se perderán los cambios realizados en este borrador de base de conocimientos.",
|
||||
"newKnowledge.discardDraftTitle": "¿Descartar este borrador de base de conocimientos?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Se eliminarán la configuración de la fuente y la vista previa del rastreo.",
|
||||
"newKnowledge.discardSourceDraftFailed": "No se pudo descartar el borrador de la fuente. Vuelve a intentarlo.",
|
||||
"newKnowledge.discardSourceDraftTitle": "¿Descartar este borrador de fuente?",
|
||||
"newKnowledge.documents": "Documentos",
|
||||
"newKnowledge.documentsUnavailable": "— documentos",
|
||||
"newKnowledge.emptyDescription": "Añade tus documentos y los agentes podrán leerlos directamente, sin configurar la indexación.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Conecta una fuente y sus documentos se mantendrán sincronizados, indexados automáticamente y listos para usar, sin nada que administrar. Tus bases de conocimiento anteriores seguirán funcionando igual.",
|
||||
"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.invalidRootUrl": "Introduce una URL http(s) válida.",
|
||||
"newKnowledge.lastSyncColumn": "Última sincronización",
|
||||
"newKnowledge.learnMore": "Más información",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Salir de la configuración",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "¿Salir de la configuración incompleta?",
|
||||
"newKnowledge.legacy": "Anterior",
|
||||
"newKnowledge.loadMore": "Cargar más",
|
||||
"newKnowledge.maxPages": "Máximo de páginas",
|
||||
"newKnowledge.moreProviders": "Ver más",
|
||||
"newKnowledge.name": "Nombre del conocimiento",
|
||||
"newKnowledge.namePlaceholder": "por ej. Manual de atención al cliente",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Nuevo",
|
||||
"newKnowledge.noDescription": "Sin descripción",
|
||||
"newKnowledge.noMatchingSources": "Ninguna fuente coincide con esta búsqueda.",
|
||||
"newKnowledge.noPagesFound": "No se encontraron páginas en {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "El rastreador accedió al sitio, pero no encontró páginas indexables. Prueba otra URL o amplía las opciones de rastreo.",
|
||||
"newKnowledge.notFoundDescription": "Es posible que esta base de conocimientos haya sido eliminada o que no tengas acceso.",
|
||||
"newKnowledge.notFoundTitle": "Base de conocimientos no encontrada",
|
||||
"newKnowledge.onlineDocuments": "Documentos en línea",
|
||||
"newKnowledge.onlineDrive": "Unidad en línea",
|
||||
"newKnowledge.pagesAppearDescription": "Rastrea el sitio para revisar qué páginas se añadirán.",
|
||||
"newKnowledge.pagesAppearTitle": "Las páginas aparecerán aquí",
|
||||
"newKnowledge.pagesCrawled": "{{count}} páginas rastreadas en {{host}}",
|
||||
"newKnowledge.permission": "Permiso",
|
||||
"newKnowledge.permissionAllMembers": "Espacio de trabajo · todos los miembros pueden ver y editar",
|
||||
"newKnowledge.permissionOnlyMe": "solo yo",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} no está configurado",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Agregue una clave API o una URL de punto final para rastrear sitios web con {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Este proveedor no está disponible.",
|
||||
"newKnowledge.reCrawl": "Volver a rastrear",
|
||||
"newKnowledge.readOnlyEmpty": "Pide a un editor del espacio de trabajo que cree la primera base de conocimiento.",
|
||||
"newKnowledge.refreshConnectionStatus": "Estado de actualización",
|
||||
"newKnowledge.refreshingConnection": "Refrescante…",
|
||||
"newKnowledge.removeSource": "Eliminar fuente",
|
||||
"newKnowledge.retryCrawl": "Reintentar rastreo",
|
||||
"newKnowledge.retryProviderLoad": "Reintentar",
|
||||
"newKnowledge.rootUrl": "URL raíz",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Esta sección estará disponible en el siguiente paso de configuración.",
|
||||
"newKnowledge.searchSources": "Buscar fuentes",
|
||||
"newKnowledge.sourceActions": "Acciones para {{name}}",
|
||||
"newKnowledge.sourceColumn": "Fuente",
|
||||
"newKnowledge.sourceFilterLabel": "Filtrar fuentes por estado",
|
||||
"newKnowledge.sourceName": "Nombre de la fuente",
|
||||
"newKnowledge.sourceNamePlaceholder": "p. ej., rastreo de documentación del producto",
|
||||
"newKnowledge.sourceNameRequired": "Introduce un nombre para la fuente.",
|
||||
"newKnowledge.sourceStatus.active": "Activo",
|
||||
"newKnowledge.sourceStatus.disabled": "Deshabilitado",
|
||||
"newKnowledge.sourceStatus.error": "Error",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Empezar con",
|
||||
"newKnowledge.startWithHelp": "Puede agregar más fuentes o documentos en cualquier momento.",
|
||||
"newKnowledge.statusColumn": "Estado",
|
||||
"newKnowledge.stopCrawl": "Detener",
|
||||
"newKnowledge.stoppingCrawl": "Deteniendo…",
|
||||
"newKnowledge.syncNow": "Sincronizar ahora",
|
||||
"newKnowledge.syncPolicyColumn": "Política de sincronización",
|
||||
"newKnowledge.tags": "Etiquetas",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Actualizado el {{date}}",
|
||||
"newKnowledge.uploadFiles": "Subir archivos",
|
||||
"newKnowledge.uploadFilesDescription": "Añade archivos desde tu ordenador; se indexarán en cuanto los crees.",
|
||||
"newKnowledge.usingDefaults": "Usando valores predeterminados",
|
||||
"newKnowledge.viewLabel": "Vista de conocimiento",
|
||||
"newKnowledge.websiteCrawl": "Rastreo del sitio web",
|
||||
"noExternalKnowledge": "Todavía no hay una API de conocimiento externo, haga clic aquí para crear",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "اقدامات",
|
||||
"newKnowledge.addSource": "اضافه کردن منبع",
|
||||
"newKnowledge.addSourceDescription": "منبعی را به این پایگاه دانش متصل کنید - به طور خودکار همگامسازی میشود و تازه میماند.",
|
||||
"newKnowledge.addSourceRequiresSelection": "پیش از افزودن منبع، حداقل یک صفحهٔ پیمایششده را انتخاب کنید.",
|
||||
"newKnowledge.adjustAndRecrawl": "تنظیم و پیمایش دوباره",
|
||||
"newKnowledge.allSources": "همه منابع",
|
||||
"newKnowledge.appsUnavailable": "— برنامه",
|
||||
"newKnowledge.authKind.api-key": "کلید API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "قبل از افزودن منبع وب سایت، اتصال را تازه کنید.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} در حال اتصال است",
|
||||
"newKnowledge.connectionRefreshFailed": "ما نتوانستیم این اتصال را بازخوانی کنیم. دوباره امتحان کنید.",
|
||||
"newKnowledge.crawlAndPreview": "خزیدن و پیشنمایش",
|
||||
"newKnowledge.crawlFailed": "پیمایش {{host}} ممکن نشد",
|
||||
"newKnowledge.crawlFailed403": "سایت خطای 403 برگرداند؛ ممکن است خزندهها را مسدود کند یا به احراز هویت نیاز داشته باشد. نشانی را بررسی کنید، گزینههای پیمایش را تغییر دهید یا ارائهدهندهٔ دیگری را امتحان کنید.",
|
||||
"newKnowledge.crawlFailedDescription": "خزنده نتوانست این پیشنمایش را کامل کند. نشانی را بررسی کنید، گزینههای پیمایش را تغییر دهید یا دوباره تلاش کنید.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} خطایی گزارش کرد. اتصال ارائهدهنده را بررسی کنید و دوباره تلاش کنید.",
|
||||
"newKnowledge.crawlFailedTimeout": "زمان پیمایش به پایان رسید. نشانی دقیقتری را امتحان کنید یا حداکثر تعداد صفحهها را کاهش دهید.",
|
||||
"newKnowledge.crawlOptions": "گزینههای پیمایش",
|
||||
"newKnowledge.crawlProgress": "پیشرفت پیمایش {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "پیکربندی خزیدن وبسایت تا زمانی که گردش کار خزیدن در دسترس نباشد، غیرفعال است.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl آماده است",
|
||||
"newKnowledge.crawlStartFailed": "پیشنمایش پیمایش آغاز نشد. دوباره تلاش کنید.",
|
||||
"newKnowledge.crawlStopped": "پیمایش متوقف شد",
|
||||
"newKnowledge.crawling": "در حال پیمایش…",
|
||||
"newKnowledge.crawlingPages": "در حال پیمایش {{host}}… {{count}} صفحه پیدا شد",
|
||||
"newKnowledge.createFailed": "ما نتوانستیم این پایگاه دانش را ایجاد کنیم. دسترسی خود را بررسی کنید و دوباره امتحان کنید.",
|
||||
"newKnowledge.createTitle": "ایجاد دانش",
|
||||
"newKnowledge.creators": "ایجادکنندگان",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "حذف پیشنویس",
|
||||
"newKnowledge.discardDraftDescription": "تغییرات شما در این پیشنویس پایگاه دانش از بین خواهد رفت.",
|
||||
"newKnowledge.discardDraftTitle": "این پیشنویس پایگاه دانش حذف شود؟",
|
||||
"newKnowledge.discardSourceDraftDescription": "پیکربندی منبع و پیشنمایش پیمایش حذف خواهند شد.",
|
||||
"newKnowledge.discardSourceDraftFailed": "حذف پیشنویس منبع ممکن نشد. دوباره تلاش کنید.",
|
||||
"newKnowledge.discardSourceDraftTitle": "این پیشنویس منبع حذف شود؟",
|
||||
"newKnowledge.documents": "اسناد",
|
||||
"newKnowledge.documentsUnavailable": "— سند",
|
||||
"newKnowledge.emptyDescription": "اسناد خود را اضافه کنید تا عاملها بتوانند مستقیماً آنها را بخوانند — بدون نیاز به تنظیم نمایهسازی.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "یک منبع را متصل کنید تا اسناد آن همگام، خودکار نمایهسازی و آماده استفاده بمانند؛ بدون تنظیماتی برای مدیریت. پایگاههای دانش قبلی شما همچنان مانند گذشته کار میکنند.",
|
||||
"newKnowledge.guideTitle": "با پایگاه دانش جدید آشنا شوید ✨",
|
||||
"newKnowledge.illustrationHeadline": "محتوای خود را یکبار متصل کنید تا هر برنامه با تازهترین دانش پاسخ دهد.",
|
||||
"newKnowledge.includeSubpages": "شامل صفحههای فرعی",
|
||||
"newKnowledge.invalidRootUrl": "یک نشانی معتبر http(s) وارد کنید.",
|
||||
"newKnowledge.lastSyncColumn": "آخرین همگام سازی",
|
||||
"newKnowledge.learnMore": "بیشتر بدانید",
|
||||
"newKnowledge.leavePartialSetupConfirm": "خروج از راهاندازی",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "از راهاندازی ناتمام خارج میشوید؟",
|
||||
"newKnowledge.legacy": "قدیمی",
|
||||
"newKnowledge.loadMore": "بارگذاری بیشتر",
|
||||
"newKnowledge.maxPages": "حداکثر صفحهها",
|
||||
"newKnowledge.moreProviders": "بیشتر ببینید",
|
||||
"newKnowledge.name": "نام دانش",
|
||||
"newKnowledge.namePlaceholder": "به عنوان مثال راهنمای پشتیبانی مشتری",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "جدید",
|
||||
"newKnowledge.noDescription": "بدون توضیح",
|
||||
"newKnowledge.noMatchingSources": "هیچ منبعی با این جستجو مطابقت ندارد.",
|
||||
"newKnowledge.noPagesFound": "صفحهای در {{host}} پیدا نشد",
|
||||
"newKnowledge.noPagesFoundDescription": "خزنده به سایت رسید اما صفحهٔ قابل نمایهسازی پیدا نکرد. نشانی دیگری را امتحان کنید یا گزینههای پیمایش را گسترش دهید.",
|
||||
"newKnowledge.notFoundDescription": "این پایگاه دانش ممکن است حذف شده باشد یا ممکن است دسترسی نداشته باشید.",
|
||||
"newKnowledge.notFoundTitle": "پایگاه دانش یافت نشد",
|
||||
"newKnowledge.onlineDocuments": "اسناد آنلاین",
|
||||
"newKnowledge.onlineDrive": "درایو آنلاین",
|
||||
"newKnowledge.pagesAppearDescription": "سایت را پیمایش کنید تا صفحههایی را که افزوده میشوند بررسی کنید.",
|
||||
"newKnowledge.pagesAppearTitle": "صفحهها اینجا نمایش داده میشوند",
|
||||
"newKnowledge.pagesCrawled": "{{count}} صفحه در {{host}} پیمایش شد",
|
||||
"newKnowledge.permission": "اجازه",
|
||||
"newKnowledge.permissionAllMembers": "فضای کاری · همه اعضا می توانند مشاهده و ویرایش کنند",
|
||||
"newKnowledge.permissionOnlyMe": "فقط من",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} پیکربندی نشده است",
|
||||
"newKnowledge.providerNotConfiguredDescription": "برای خزیدن وبسایتها با {{provider}}، یک کلید API یا URL نقطه پایانی اضافه کنید.",
|
||||
"newKnowledge.providerUnavailable": "این ارائه دهنده در دسترس نیست.",
|
||||
"newKnowledge.reCrawl": "پیمایش دوباره",
|
||||
"newKnowledge.readOnlyEmpty": "از یک ویرایشگر فضای کاری بخواهید اولین پایگاه دانش را ایجاد کند.",
|
||||
"newKnowledge.refreshConnectionStatus": "وضعیت بازخوانی",
|
||||
"newKnowledge.refreshingConnection": "تازهسازی…",
|
||||
"newKnowledge.removeSource": "حذف منبع",
|
||||
"newKnowledge.retryCrawl": "تلاش دوباره برای پیمایش",
|
||||
"newKnowledge.retryProviderLoad": "دوباره امتحان کنید",
|
||||
"newKnowledge.rootUrl": "نشانی ریشه",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "این بخش در مرحله راه اندازی بعدی در دسترس خواهد بود.",
|
||||
"newKnowledge.searchSources": "منابع جستجو",
|
||||
"newKnowledge.sourceActions": "اقدامات برای {{name}}",
|
||||
"newKnowledge.sourceColumn": "منبع",
|
||||
"newKnowledge.sourceFilterLabel": "منابع را بر اساس وضعیت فیلتر کنید",
|
||||
"newKnowledge.sourceName": "نام منبع",
|
||||
"newKnowledge.sourceNamePlaceholder": "مثلاً پیمایش مستندات محصول",
|
||||
"newKnowledge.sourceNameRequired": "نام منبع را وارد کنید.",
|
||||
"newKnowledge.sourceStatus.active": "فعال",
|
||||
"newKnowledge.sourceStatus.disabled": "غیرفعال شد",
|
||||
"newKnowledge.sourceStatus.error": "خطا",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "شروع کنید با",
|
||||
"newKnowledge.startWithHelp": "میتوانید منابع یا اسناد بیشتری را در هر زمان اضافه کنید.",
|
||||
"newKnowledge.statusColumn": "وضعیت",
|
||||
"newKnowledge.stopCrawl": "توقف",
|
||||
"newKnowledge.stoppingCrawl": "در حال توقف…",
|
||||
"newKnowledge.syncNow": "اکنون همگام سازی کنید",
|
||||
"newKnowledge.syncPolicyColumn": "خط مشی همگام سازی",
|
||||
"newKnowledge.tags": "برچسبها",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "بهروزرسانی در {{date}}",
|
||||
"newKnowledge.uploadFiles": "بارگذاری فایلها",
|
||||
"newKnowledge.uploadFilesDescription": "فایلها را از رایانه اضافه کنید — بهمحض ایجاد نمایهسازی میشوند.",
|
||||
"newKnowledge.usingDefaults": "استفاده از تنظیمات پیشفرض",
|
||||
"newKnowledge.viewLabel": "نمای دانش",
|
||||
"newKnowledge.websiteCrawl": "خزیدن وب سایت",
|
||||
"noExternalKnowledge": "هنوز هیچ API دانش خارجی وجود ندارد، برای ایجاد اینجا را کلیک کنید",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Actions",
|
||||
"newKnowledge.addSource": "Ajouter une source",
|
||||
"newKnowledge.addSourceDescription": "Connectez une source à cette base de connaissances : elle se synchronise automatiquement et reste à jour.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Sélectionnez au moins une page explorée avant d’ajouter la source.",
|
||||
"newKnowledge.adjustAndRecrawl": "Ajuster et relancer l’exploration",
|
||||
"newKnowledge.allSources": "Toutes les sources",
|
||||
"newKnowledge.appsUnavailable": "— applications",
|
||||
"newKnowledge.authKind.api-key": "Clé API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Actualisez la connexion avant d'ajouter une source de site Web.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} se connecte",
|
||||
"newKnowledge.connectionRefreshFailed": "Nous n'avons pas pu actualiser cette connexion. Essayer à nouveau.",
|
||||
"newKnowledge.crawlAndPreview": "Exploration et aperçu",
|
||||
"newKnowledge.crawlFailed": "Impossible d’explorer {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Le site a renvoyé une erreur 403. Il bloque peut-être les robots d’exploration ou exige une authentification. Vérifiez l’URL, ajustez les options ou essayez un autre fournisseur.",
|
||||
"newKnowledge.crawlFailedDescription": "Le robot n’a pas pu terminer cet aperçu. Vérifiez l’URL, ajustez les options d’exploration ou réessayez.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} a signalé une erreur. Vérifiez la connexion au fournisseur et réessayez.",
|
||||
"newKnowledge.crawlFailedTimeout": "Le délai d’exploration a expiré. Essayez une URL plus précise ou réduisez le nombre maximal de pages.",
|
||||
"newKnowledge.crawlOptions": "Options d’exploration",
|
||||
"newKnowledge.crawlProgress": "Progression de l’exploration de {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "La configuration de l'analyse du site Web est désactivée jusqu'à ce que le flux de travail d'analyse soit disponible.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl est prêt",
|
||||
"newKnowledge.crawlStartFailed": "Impossible de démarrer l’aperçu de l’exploration. Réessayez.",
|
||||
"newKnowledge.crawlStopped": "Exploration arrêtée",
|
||||
"newKnowledge.crawling": "Exploration en cours…",
|
||||
"newKnowledge.crawlingPages": "Exploration de {{host}}… {{count}} pages trouvées",
|
||||
"newKnowledge.createFailed": "Nous n'avons pas pu créer cette base de connaissances. Vérifiez votre accès et réessayez.",
|
||||
"newKnowledge.createTitle": "Créer des connaissances",
|
||||
"newKnowledge.creators": "Créateurs",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Abandonner le brouillon",
|
||||
"newKnowledge.discardDraftDescription": "Les modifications apportées à ce brouillon de base de connaissances seront perdues.",
|
||||
"newKnowledge.discardDraftTitle": "Abandonner ce brouillon de base de connaissances ?",
|
||||
"newKnowledge.discardSourceDraftDescription": "La configuration de la source et l’aperçu de l’exploration seront supprimés.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Impossible d’abandonner le brouillon de la source. Réessayez.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Abandonner ce brouillon de source ?",
|
||||
"newKnowledge.documents": "Documents",
|
||||
"newKnowledge.documentsUnavailable": "— documents",
|
||||
"newKnowledge.emptyDescription": "Ajoutez vos documents et les agents pourront les lire directement, sans indexation à configurer.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Connectez une source et ses documents restent synchronisés, indexés automatiquement et prêts à l’emploi, sans configuration à gérer. Vos anciennes bases de connaissances continuent de fonctionner telles quelles.",
|
||||
"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.invalidRootUrl": "Saisissez une URL http(s) valide.",
|
||||
"newKnowledge.lastSyncColumn": "Dernière synchronisation",
|
||||
"newKnowledge.learnMore": "En savoir plus",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Quitter la configuration",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Quitter la configuration incomplète ?",
|
||||
"newKnowledge.legacy": "Ancien",
|
||||
"newKnowledge.loadMore": "Charger plus",
|
||||
"newKnowledge.maxPages": "Nombre maximal de pages",
|
||||
"newKnowledge.moreProviders": "Voir plus",
|
||||
"newKnowledge.name": "Nom de la connaissance",
|
||||
"newKnowledge.namePlaceholder": "par ex. Manuel de support client",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Nouveau",
|
||||
"newKnowledge.noDescription": "Aucune description",
|
||||
"newKnowledge.noMatchingSources": "Aucune source ne correspond à cette recherche.",
|
||||
"newKnowledge.noPagesFound": "Aucune page trouvée sur {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "Le robot a atteint le site, mais n’a trouvé aucune page indexable. Essayez une autre URL ou élargissez les options d’exploration.",
|
||||
"newKnowledge.notFoundDescription": "Cette base de connaissances a peut-être été supprimée ou vous n'y avez peut-être pas accès.",
|
||||
"newKnowledge.notFoundTitle": "Base de connaissances introuvable",
|
||||
"newKnowledge.onlineDocuments": "Documents en ligne",
|
||||
"newKnowledge.onlineDrive": "Drive en ligne",
|
||||
"newKnowledge.pagesAppearDescription": "Explorez le site pour vérifier les pages qui seront ajoutées.",
|
||||
"newKnowledge.pagesAppearTitle": "Les pages apparaîtront ici",
|
||||
"newKnowledge.pagesCrawled": "{{count}} pages explorées sur {{host}}",
|
||||
"newKnowledge.permission": "Autorisation",
|
||||
"newKnowledge.permissionAllMembers": "Espace de travail · tous les membres peuvent consulter et modifier",
|
||||
"newKnowledge.permissionOnlyMe": "Seulement moi",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} n'est pas configuré",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Ajoutez une clé API ou une URL de point de terminaison pour explorer les sites Web avec {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Ce fournisseur n'est pas disponible.",
|
||||
"newKnowledge.reCrawl": "Relancer l’exploration",
|
||||
"newKnowledge.readOnlyEmpty": "Demandez à un éditeur de l’espace de travail de créer la première base de connaissances.",
|
||||
"newKnowledge.refreshConnectionStatus": "Actualiser l'état",
|
||||
"newKnowledge.refreshingConnection": "Rafraîchissant…",
|
||||
"newKnowledge.removeSource": "Supprimer la source",
|
||||
"newKnowledge.retryCrawl": "Réessayer l’exploration",
|
||||
"newKnowledge.retryProviderLoad": "Réessayer",
|
||||
"newKnowledge.rootUrl": "URL racine",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Cette section deviendra disponible lors de la prochaine étape de configuration.",
|
||||
"newKnowledge.searchSources": "Sources de recherche",
|
||||
"newKnowledge.sourceActions": "Actions pour {{name}}",
|
||||
"newKnowledge.sourceColumn": "Origine",
|
||||
"newKnowledge.sourceFilterLabel": "Filtrer les sources par statut",
|
||||
"newKnowledge.sourceName": "Nom de la source",
|
||||
"newKnowledge.sourceNamePlaceholder": "p. ex. exploration de la documentation produit",
|
||||
"newKnowledge.sourceNameRequired": "Saisissez un nom de source.",
|
||||
"newKnowledge.sourceStatus.active": "Actif",
|
||||
"newKnowledge.sourceStatus.disabled": "Désactivé",
|
||||
"newKnowledge.sourceStatus.error": "Erreur",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Commencez par",
|
||||
"newKnowledge.startWithHelp": "Vous pouvez ajouter plus de sources ou de documents à tout moment.",
|
||||
"newKnowledge.statusColumn": "Statut",
|
||||
"newKnowledge.stopCrawl": "Arrêter",
|
||||
"newKnowledge.stoppingCrawl": "Arrêt en cours…",
|
||||
"newKnowledge.syncNow": "Synchroniser maintenant",
|
||||
"newKnowledge.syncPolicyColumn": "Politique de synchronisation",
|
||||
"newKnowledge.tags": "Étiquettes",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Mis à jour le {{date}}",
|
||||
"newKnowledge.uploadFiles": "Importer des fichiers",
|
||||
"newKnowledge.uploadFilesDescription": "Ajoutez des fichiers depuis votre ordinateur : ils sont indexés dès leur création.",
|
||||
"newKnowledge.usingDefaults": "Valeurs par défaut utilisées",
|
||||
"newKnowledge.viewLabel": "Vue des connaissances",
|
||||
"newKnowledge.websiteCrawl": "Exploration du site Web",
|
||||
"noExternalKnowledge": "Il n’y a pas encore d’API de connaissances externes, cliquez ici pour créer",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "क्रियाएँ",
|
||||
"newKnowledge.addSource": "स्रोत जोड़ें",
|
||||
"newKnowledge.addSourceDescription": "इस ज्ञानकोष से एक स्रोत कनेक्ट करें - यह स्वचालित रूप से समन्वयित होता है और ताज़ा रहता है।",
|
||||
"newKnowledge.addSourceRequiresSelection": "स्रोत जोड़ने से पहले कम से कम एक क्रॉल किया गया पेज चुनें।",
|
||||
"newKnowledge.adjustAndRecrawl": "समायोजित करें और फिर से क्रॉल करें",
|
||||
"newKnowledge.allSources": "सभी स्रोत",
|
||||
"newKnowledge.appsUnavailable": "— ऐप",
|
||||
"newKnowledge.authKind.api-key": "एपीआई कुंजी",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "वेबसाइट स्रोत जोड़ने से पहले कनेक्शन को ताज़ा करें।",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} कनेक्ट हो रहा है",
|
||||
"newKnowledge.connectionRefreshFailed": "हम इस कनेक्शन को ताज़ा नहीं कर सके। पुनः प्रयास करें।",
|
||||
"newKnowledge.crawlAndPreview": "क्रॉल और पूर्वावलोकन",
|
||||
"newKnowledge.crawlFailed": "{{host}} को क्रॉल नहीं किया जा सका",
|
||||
"newKnowledge.crawlFailed403": "साइट ने 403 लौटाया — हो सकता है कि वह क्रॉलर को रोकती हो या प्रमाणीकरण मांगती हो। URL जाँचें, क्रॉल विकल्प बदलें या किसी दूसरे प्रदाता को आज़माएँ।",
|
||||
"newKnowledge.crawlFailedDescription": "क्रॉलर यह पूर्वावलोकन पूरा नहीं कर सका। URL जाँचें, क्रॉल विकल्प बदलें या फिर से प्रयास करें।",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} ने त्रुटि की सूचना दी। प्रदाता कनेक्शन जाँचें और फिर से प्रयास करें।",
|
||||
"newKnowledge.crawlFailedTimeout": "क्रॉल का समय समाप्त हो गया। अधिक विशिष्ट URL आज़माएँ या पेज की अधिकतम संख्या घटाएँ।",
|
||||
"newKnowledge.crawlOptions": "क्रॉल विकल्प",
|
||||
"newKnowledge.crawlProgress": "{{host}} के लिए क्रॉल प्रगति",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "क्रॉल वर्कफ़्लो उपलब्ध होने तक वेबसाइट क्रॉल कॉन्फ़िगरेशन अक्षम है।",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "फायरक्रॉल तैयार है",
|
||||
"newKnowledge.crawlStartFailed": "क्रॉल पूर्वावलोकन शुरू नहीं हो सका। फिर से प्रयास करें।",
|
||||
"newKnowledge.crawlStopped": "क्रॉल रोक दिया गया",
|
||||
"newKnowledge.crawling": "क्रॉल किया जा रहा है…",
|
||||
"newKnowledge.crawlingPages": "{{host}} को क्रॉल किया जा रहा है… {{count}} पेज मिले",
|
||||
"newKnowledge.createFailed": "हम यह ज्ञानकोष नहीं बना सके। अपनी पहुंच जांचें और पुनः प्रयास करें।",
|
||||
"newKnowledge.createTitle": "ज्ञान पैदा करें",
|
||||
"newKnowledge.creators": "निर्माता",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "ड्राफ़्ट हटाएँ",
|
||||
"newKnowledge.discardDraftDescription": "इस नॉलेज बेस ड्राफ़्ट में किए गए आपके बदलाव खो जाएँगे।",
|
||||
"newKnowledge.discardDraftTitle": "क्या यह नॉलेज बेस ड्राफ़्ट हटाना है?",
|
||||
"newKnowledge.discardSourceDraftDescription": "स्रोत कॉन्फ़िगरेशन और क्रॉल पूर्वावलोकन हटा दिए जाएँगे।",
|
||||
"newKnowledge.discardSourceDraftFailed": "स्रोत ड्राफ़्ट हटाया नहीं जा सका। फिर से प्रयास करें।",
|
||||
"newKnowledge.discardSourceDraftTitle": "यह स्रोत ड्राफ़्ट हटाएँ?",
|
||||
"newKnowledge.documents": "दस्तावेज़",
|
||||
"newKnowledge.documentsUnavailable": "— दस्तावेज़",
|
||||
"newKnowledge.emptyDescription": "अपने दस्तावेज़ जोड़ें ताकि एजेंट उन्हें सीधे पढ़ सकें — इंडेक्सिंग कॉन्फ़िगर करने की ज़रूरत नहीं।",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "किसी स्रोत को कनेक्ट करें और उसके दस्तावेज़ सिंक, अपने-आप इंडेक्स और उपयोग के लिए तैयार रहेंगे—किसी सेटअप को संभालने की ज़रूरत नहीं। आपके पुराने नॉलेज बेस पहले की तरह काम करते रहेंगे।",
|
||||
"newKnowledge.guideTitle": "नए नॉलेज बेस से मिलें ✨",
|
||||
"newKnowledge.illustrationHeadline": "अपनी सामग्री एक बार कनेक्ट करें — हर ऐप नवीनतम ज्ञान के साथ जवाब देगा।",
|
||||
"newKnowledge.includeSubpages": "उप-पेज शामिल करें",
|
||||
"newKnowledge.invalidRootUrl": "मान्य http(s) URL दर्ज करें।",
|
||||
"newKnowledge.lastSyncColumn": "अंतिम सिंक",
|
||||
"newKnowledge.learnMore": "और जानें",
|
||||
"newKnowledge.leavePartialSetupConfirm": "सेटअप छोड़ें",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "क्या अधूरा सेटअप छोड़ना है?",
|
||||
"newKnowledge.legacy": "पुराना",
|
||||
"newKnowledge.loadMore": "और लोड करें",
|
||||
"newKnowledge.maxPages": "अधिकतम पेज",
|
||||
"newKnowledge.moreProviders": "और देखें",
|
||||
"newKnowledge.name": "ज्ञान नाम",
|
||||
"newKnowledge.namePlaceholder": "जैसे ग्राहक सहायता पुस्तिका",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "नया",
|
||||
"newKnowledge.noDescription": "कोई विवरण नहीं",
|
||||
"newKnowledge.noMatchingSources": "इस खोज से कोई स्रोत मेल नहीं खाता।",
|
||||
"newKnowledge.noPagesFound": "{{host}} पर कोई पेज नहीं मिला",
|
||||
"newKnowledge.noPagesFoundDescription": "क्रॉलर साइट तक पहुँचा, लेकिन कोई इंडेक्स करने योग्य पेज नहीं मिला। कोई दूसरा URL आज़माएँ या क्रॉल विकल्प बढ़ाएँ।",
|
||||
"newKnowledge.notFoundDescription": "हो सकता है कि यह ज्ञानकोष हटा दिया गया हो या आपके पास पहुंच न हो।",
|
||||
"newKnowledge.notFoundTitle": "ज्ञान का आधार नहीं मिला",
|
||||
"newKnowledge.onlineDocuments": "ऑनलाइन दस्तावेज़",
|
||||
"newKnowledge.onlineDrive": "ऑनलाइन ड्राइव",
|
||||
"newKnowledge.pagesAppearDescription": "जोड़े जाने वाले पेज देखने के लिए साइट को क्रॉल करें।",
|
||||
"newKnowledge.pagesAppearTitle": "पेज यहाँ दिखाई देंगे",
|
||||
"newKnowledge.pagesCrawled": "{{host}} पर {{count}} पेज क्रॉल किए गए",
|
||||
"newKnowledge.permission": "अनुमति",
|
||||
"newKnowledge.permissionAllMembers": "कार्यक्षेत्र · सभी सदस्य देख और संपादित कर सकते हैं",
|
||||
"newKnowledge.permissionOnlyMe": "केवल मैं",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} कॉन्फ़िगर नहीं है",
|
||||
"newKnowledge.providerNotConfiguredDescription": "{{provider}} के साथ वेबसाइटों को क्रॉल करने के लिए एक एपीआई कुंजी या एंडपॉइंट यूआरएल जोड़ें।",
|
||||
"newKnowledge.providerUnavailable": "यह प्रदाता अनुपलब्ध है।",
|
||||
"newKnowledge.reCrawl": "फिर से क्रॉल करें",
|
||||
"newKnowledge.readOnlyEmpty": "पहला नॉलेज बेस बनाने के लिए कार्यस्थान संपादक से कहें।",
|
||||
"newKnowledge.refreshConnectionStatus": "स्थिति ताज़ा करें",
|
||||
"newKnowledge.refreshingConnection": "ताज़ा…",
|
||||
"newKnowledge.removeSource": "स्रोत हटाएं",
|
||||
"newKnowledge.retryCrawl": "क्रॉल का फिर से प्रयास करें",
|
||||
"newKnowledge.retryProviderLoad": "पुनः प्रयास करें",
|
||||
"newKnowledge.rootUrl": "रूट URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "यह अनुभाग अगले सेटअप चरण में उपलब्ध हो जाएगा.",
|
||||
"newKnowledge.searchSources": "स्रोत खोजें",
|
||||
"newKnowledge.sourceActions": "{{name}} के लिए कार्रवाइयां",
|
||||
"newKnowledge.sourceColumn": "स्रोत",
|
||||
"newKnowledge.sourceFilterLabel": "स्थिति के अनुसार स्रोतों को फ़िल्टर करें",
|
||||
"newKnowledge.sourceName": "स्रोत का नाम",
|
||||
"newKnowledge.sourceNamePlaceholder": "जैसे, उत्पाद दस्तावेज़ क्रॉल",
|
||||
"newKnowledge.sourceNameRequired": "स्रोत का नाम दर्ज करें।",
|
||||
"newKnowledge.sourceStatus.active": "सक्रिय",
|
||||
"newKnowledge.sourceStatus.disabled": "विकलांग",
|
||||
"newKnowledge.sourceStatus.error": "त्रुटि",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "से शुरू करें",
|
||||
"newKnowledge.startWithHelp": "आप किसी भी समय अधिक स्रोत या दस्तावेज़ जोड़ सकते हैं।",
|
||||
"newKnowledge.statusColumn": "स्थिति",
|
||||
"newKnowledge.stopCrawl": "रोकें",
|
||||
"newKnowledge.stoppingCrawl": "रोका जा रहा है…",
|
||||
"newKnowledge.syncNow": "अभी सिंक करें",
|
||||
"newKnowledge.syncPolicyColumn": "सिंक नीति",
|
||||
"newKnowledge.tags": "टैग",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "{{date}} को अपडेट किया गया",
|
||||
"newKnowledge.uploadFiles": "फ़ाइलें अपलोड करें",
|
||||
"newKnowledge.uploadFilesDescription": "अपने कंप्यूटर से फ़ाइलें जोड़ें — बनाते ही वे इंडेक्स हो जाएँगी।",
|
||||
"newKnowledge.usingDefaults": "डिफ़ॉल्ट सेटिंग का उपयोग हो रहा है",
|
||||
"newKnowledge.viewLabel": "नॉलेज दृश्य",
|
||||
"newKnowledge.websiteCrawl": "वेबसाइट क्रॉल",
|
||||
"noExternalKnowledge": "अभी तक कोई बाहरी ज्ञान एपीआई नहीं है, बनाने के लिए यहां क्लिक करें",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Tindakan",
|
||||
"newKnowledge.addSource": "Tambahkan sumber",
|
||||
"newKnowledge.addSourceDescription": "Hubungkan sumber ke basis pengetahuan ini — sumber tersebut akan disinkronkan secara otomatis dan tetap segar.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Pilih setidaknya satu halaman yang dirayapi sebelum menambahkan sumber.",
|
||||
"newKnowledge.adjustAndRecrawl": "Sesuaikan dan rayapi ulang",
|
||||
"newKnowledge.allSources": "Semua sumber",
|
||||
"newKnowledge.appsUnavailable": "— aplikasi",
|
||||
"newKnowledge.authKind.api-key": "kunci API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Segarkan koneksi sebelum menambahkan sumber situs web.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} terhubung",
|
||||
"newKnowledge.connectionRefreshFailed": "Kami tidak dapat menyegarkan koneksi ini. Coba lagi.",
|
||||
"newKnowledge.crawlAndPreview": "Perayapan & pratinjau",
|
||||
"newKnowledge.crawlFailed": "Tidak dapat merayapi {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Situs mengembalikan 403 — situs mungkin memblokir perayap atau memerlukan autentikasi. Periksa URL, sesuaikan opsi perayapan, atau coba penyedia lain.",
|
||||
"newKnowledge.crawlFailedDescription": "Perayap tidak dapat menyelesaikan pratinjau ini. Periksa URL, sesuaikan opsi perayapan, atau coba lagi.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} melaporkan kesalahan. Periksa koneksi penyedia dan coba lagi.",
|
||||
"newKnowledge.crawlFailedTimeout": "Waktu perayapan habis. Coba URL yang lebih spesifik atau kurangi jumlah maksimum halaman.",
|
||||
"newKnowledge.crawlOptions": "Opsi perayapan",
|
||||
"newKnowledge.crawlProgress": "Progres perayapan untuk {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Konfigurasi perayapan situs web dinonaktifkan hingga alur kerja perayapan tersedia.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl sudah siap",
|
||||
"newKnowledge.crawlStartFailed": "Pratinjau perayapan tidak dapat dimulai. Coba lagi.",
|
||||
"newKnowledge.crawlStopped": "Perayapan dihentikan",
|
||||
"newKnowledge.crawling": "Merayapi…",
|
||||
"newKnowledge.crawlingPages": "Merayapi {{host}}… {{count}} halaman ditemukan",
|
||||
"newKnowledge.createFailed": "Kami tidak dapat membuat basis pengetahuan ini. Periksa akses Anda dan coba lagi.",
|
||||
"newKnowledge.createTitle": "Ciptakan Pengetahuan",
|
||||
"newKnowledge.creators": "Pembuat",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Buang draf",
|
||||
"newKnowledge.discardDraftDescription": "Perubahan pada draf basis pengetahuan ini akan hilang.",
|
||||
"newKnowledge.discardDraftTitle": "Buang draf basis pengetahuan ini?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Konfigurasi sumber dan pratinjau perayapan akan dihapus.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Draf sumber tidak dapat dibuang. Coba lagi.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Buang draf sumber ini?",
|
||||
"newKnowledge.documents": "Dokumen",
|
||||
"newKnowledge.documentsUnavailable": "— dokumen",
|
||||
"newKnowledge.emptyDescription": "Tambahkan dokumen agar agen dapat membacanya langsung — tanpa perlu mengatur pengindeksan.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Hubungkan sumber dan dokumennya akan tetap tersinkronisasi, diindeks otomatis, serta siap digunakan tanpa pengaturan yang perlu dikelola. Basis pengetahuan lama Anda tetap berfungsi seperti biasa.",
|
||||
"newKnowledge.guideTitle": "Kenali Basis Pengetahuan baru ✨",
|
||||
"newKnowledge.illustrationHeadline": "Hubungkan konten Anda sekali — setiap aplikasi menjawab dengan pengetahuan terbaru.",
|
||||
"newKnowledge.includeSubpages": "Sertakan subhalaman",
|
||||
"newKnowledge.invalidRootUrl": "Masukkan URL http(s) yang valid.",
|
||||
"newKnowledge.lastSyncColumn": "Sinkronisasi terakhir",
|
||||
"newKnowledge.learnMore": "Pelajari lebih lanjut",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Keluar dari penyiapan",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Keluar dari penyiapan yang belum selesai?",
|
||||
"newKnowledge.legacy": "Lama",
|
||||
"newKnowledge.loadMore": "Muat lebih banyak",
|
||||
"newKnowledge.maxPages": "Halaman maksimum",
|
||||
"newKnowledge.moreProviders": "Lihat lebih banyak",
|
||||
"newKnowledge.name": "Nama pengetahuan",
|
||||
"newKnowledge.namePlaceholder": "misalnya Buku Pegangan Dukungan Pelanggan",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Baru",
|
||||
"newKnowledge.noDescription": "Tidak ada deskripsi",
|
||||
"newKnowledge.noMatchingSources": "Tidak ada sumber yang cocok dengan pencarian ini.",
|
||||
"newKnowledge.noPagesFound": "Tidak ada halaman yang ditemukan di {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "Perayap mencapai situs tetapi tidak menemukan halaman yang dapat diindeks. Coba URL lain atau perluas opsi perayapan.",
|
||||
"newKnowledge.notFoundDescription": "Basis pengetahuan ini mungkin telah dihapus atau Anda mungkin tidak memiliki akses.",
|
||||
"newKnowledge.notFoundTitle": "Basis pengetahuan tidak ditemukan",
|
||||
"newKnowledge.onlineDocuments": "Dokumen daring",
|
||||
"newKnowledge.onlineDrive": "Perjalanan daring",
|
||||
"newKnowledge.pagesAppearDescription": "Rayapi situs untuk meninjau halaman yang akan ditambahkan.",
|
||||
"newKnowledge.pagesAppearTitle": "Halaman akan muncul di sini",
|
||||
"newKnowledge.pagesCrawled": "{{count}} halaman dirayapi di {{host}}",
|
||||
"newKnowledge.permission": "Izin",
|
||||
"newKnowledge.permissionAllMembers": "Ruang Kerja · semua anggota dapat melihat dan mengedit",
|
||||
"newKnowledge.permissionOnlyMe": "Hanya aku",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} tidak dikonfigurasi",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Tambahkan kunci API atau URL titik akhir untuk merayapi situs web dengan {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Penyedia ini tidak tersedia.",
|
||||
"newKnowledge.reCrawl": "Rayapi ulang",
|
||||
"newKnowledge.readOnlyEmpty": "Minta editor ruang kerja membuat basis pengetahuan pertama.",
|
||||
"newKnowledge.refreshConnectionStatus": "Segarkan status",
|
||||
"newKnowledge.refreshingConnection": "Menyegarkan…",
|
||||
"newKnowledge.removeSource": "Hapus sumber",
|
||||
"newKnowledge.retryCrawl": "Coba perayapan lagi",
|
||||
"newKnowledge.retryProviderLoad": "Coba lagi",
|
||||
"newKnowledge.rootUrl": "URL root",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Bagian ini akan tersedia pada langkah penyiapan berikutnya.",
|
||||
"newKnowledge.searchSources": "Cari sumber",
|
||||
"newKnowledge.sourceActions": "Tindakan untuk {{name}}",
|
||||
"newKnowledge.sourceColumn": "Sumber",
|
||||
"newKnowledge.sourceFilterLabel": "Filter sumber berdasarkan status",
|
||||
"newKnowledge.sourceName": "Nama sumber",
|
||||
"newKnowledge.sourceNamePlaceholder": "mis. perayapan dokumentasi produk",
|
||||
"newKnowledge.sourceNameRequired": "Masukkan nama sumber.",
|
||||
"newKnowledge.sourceStatus.active": "Aktif",
|
||||
"newKnowledge.sourceStatus.disabled": "Dinonaktifkan",
|
||||
"newKnowledge.sourceStatus.error": "Kesalahan",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Mulailah dengan",
|
||||
"newKnowledge.startWithHelp": "Anda dapat menambahkan lebih banyak Sumber atau Dokumen kapan saja.",
|
||||
"newKnowledge.statusColumn": "Status",
|
||||
"newKnowledge.stopCrawl": "Hentikan",
|
||||
"newKnowledge.stoppingCrawl": "Menghentikan…",
|
||||
"newKnowledge.syncNow": "Sinkronkan sekarang",
|
||||
"newKnowledge.syncPolicyColumn": "Kebijakan sinkronisasi",
|
||||
"newKnowledge.tags": "Tag",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Diperbarui {{date}}",
|
||||
"newKnowledge.uploadFiles": "Unggah file",
|
||||
"newKnowledge.uploadFilesDescription": "Tambahkan file dari komputer — file akan diindeks segera setelah dibuat.",
|
||||
"newKnowledge.usingDefaults": "Menggunakan pengaturan default",
|
||||
"newKnowledge.viewLabel": "Tampilan pengetahuan",
|
||||
"newKnowledge.websiteCrawl": "Perayapan situs web",
|
||||
"noExternalKnowledge": "Belum ada API Pengetahuan Eksternal, klik di sini untuk membuat",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Azioni",
|
||||
"newKnowledge.addSource": "Aggiungi fonte",
|
||||
"newKnowledge.addSourceDescription": "Collega una fonte a questa knowledge base: si sincronizza automaticamente e rimane aggiornata.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Seleziona almeno una pagina sottoposta a scansione prima di aggiungere la fonte.",
|
||||
"newKnowledge.adjustAndRecrawl": "Modifica e ripeti la scansione",
|
||||
"newKnowledge.allSources": "Tutte le fonti",
|
||||
"newKnowledge.appsUnavailable": "— app",
|
||||
"newKnowledge.authKind.api-key": "Chiave API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Aggiorna la connessione prima di aggiungere una fonte web.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} si sta connettendo",
|
||||
"newKnowledge.connectionRefreshFailed": "Impossibile aggiornare questa connessione. Riprova.",
|
||||
"newKnowledge.crawlAndPreview": "Scansione e anteprima",
|
||||
"newKnowledge.crawlFailed": "Impossibile eseguire la scansione di {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Il sito ha restituito un errore 403: potrebbe bloccare i crawler o richiedere l’autenticazione. Controlla l’URL, modifica le opzioni di scansione o prova un altro provider.",
|
||||
"newKnowledge.crawlFailedDescription": "Il crawler non ha potuto completare questa anteprima. Controlla l’URL, modifica le opzioni di scansione o riprova.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} ha segnalato un errore. Controlla la connessione al provider e riprova.",
|
||||
"newKnowledge.crawlFailedTimeout": "La scansione ha superato il tempo limite. Prova un URL più specifico o riduci il numero massimo di pagine.",
|
||||
"newKnowledge.crawlOptions": "Opzioni di scansione",
|
||||
"newKnowledge.crawlProgress": "Avanzamento della scansione di {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "La configurazione della scansione del sito web è disabilitata finché il flusso di lavoro di scansione non è disponibile.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl è pronto",
|
||||
"newKnowledge.crawlStartFailed": "Impossibile avviare l’anteprima della scansione. Riprova.",
|
||||
"newKnowledge.crawlStopped": "Scansione interrotta",
|
||||
"newKnowledge.crawling": "Scansione in corso…",
|
||||
"newKnowledge.crawlingPages": "Scansione di {{host}}… {{count}} pagine trovate",
|
||||
"newKnowledge.createFailed": "Non è stato possibile creare questa base di conoscenza. Controlla il tuo accesso e riprova.",
|
||||
"newKnowledge.createTitle": "Creare Conoscenza",
|
||||
"newKnowledge.creators": "Autori",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Scarta bozza",
|
||||
"newKnowledge.discardDraftDescription": "Le modifiche a questa bozza della knowledge base andranno perse.",
|
||||
"newKnowledge.discardDraftTitle": "Scartare questa bozza della knowledge base?",
|
||||
"newKnowledge.discardSourceDraftDescription": "La configurazione della fonte e l’anteprima della scansione verranno rimosse.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Impossibile eliminare la bozza della fonte. Riprova.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Eliminare questa bozza della fonte?",
|
||||
"newKnowledge.documents": "Documenti",
|
||||
"newKnowledge.documentsUnavailable": "— documenti",
|
||||
"newKnowledge.emptyDescription": "Aggiungi i tuoi documenti e gli agenti potranno leggerli direttamente, senza configurare l’indicizzazione.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Collega una fonte e i suoi documenti resteranno sincronizzati, indicizzati automaticamente e pronti all’uso, senza nulla da gestire. Le knowledge base precedenti continueranno a funzionare come prima.",
|
||||
"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.invalidRootUrl": "Inserisci un URL http(s) valido.",
|
||||
"newKnowledge.lastSyncColumn": "Ultima sincronizzazione",
|
||||
"newKnowledge.learnMore": "Scopri di più",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Esci dalla configurazione",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Uscire dalla configurazione incompleta?",
|
||||
"newKnowledge.legacy": "Legacy",
|
||||
"newKnowledge.loadMore": "Carica altro",
|
||||
"newKnowledge.maxPages": "Numero massimo di pagine",
|
||||
"newKnowledge.moreProviders": "Vedi di più",
|
||||
"newKnowledge.name": "Nome della conoscenza",
|
||||
"newKnowledge.namePlaceholder": "ad es. Manuale dell'assistenza clienti",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Nuovo",
|
||||
"newKnowledge.noDescription": "Nessuna descrizione",
|
||||
"newKnowledge.noMatchingSources": "Nessuna fonte corrisponde a questa ricerca.",
|
||||
"newKnowledge.noPagesFound": "Nessuna pagina trovata su {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "Il crawler ha raggiunto il sito ma non ha trovato pagine indicizzabili. Prova un URL diverso o amplia le opzioni di scansione.",
|
||||
"newKnowledge.notFoundDescription": "Questa knowledge base potrebbe essere stata eliminata o potresti non avere accesso.",
|
||||
"newKnowledge.notFoundTitle": "Base di conoscenza non trovata",
|
||||
"newKnowledge.onlineDocuments": "Documenti online",
|
||||
"newKnowledge.onlineDrive": "Unità in linea",
|
||||
"newKnowledge.pagesAppearDescription": "Esegui la scansione del sito per verificare quali pagine verranno aggiunte.",
|
||||
"newKnowledge.pagesAppearTitle": "Le pagine appariranno qui",
|
||||
"newKnowledge.pagesCrawled": "{{count}} pagine sottoposte a scansione su {{host}}",
|
||||
"newKnowledge.permission": "Autorizzazione",
|
||||
"newKnowledge.permissionAllMembers": "Area di lavoro · tutti i membri possono visualizzare e modificare",
|
||||
"newKnowledge.permissionOnlyMe": "Solo io",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} non è configurato",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Aggiungi una chiave API o un URL endpoint per eseguire la scansione dei siti web con {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Questo fornitore non è disponibile.",
|
||||
"newKnowledge.reCrawl": "Ripeti la scansione",
|
||||
"newKnowledge.readOnlyEmpty": "Chiedi a un editor dello spazio di lavoro di creare la prima knowledge base.",
|
||||
"newKnowledge.refreshConnectionStatus": "Aggiorna lo stato",
|
||||
"newKnowledge.refreshingConnection": "Aggiornamento…",
|
||||
"newKnowledge.removeSource": "Rimuovi la fonte",
|
||||
"newKnowledge.retryCrawl": "Riprova la scansione",
|
||||
"newKnowledge.retryProviderLoad": "Riprova",
|
||||
"newKnowledge.rootUrl": "URL principale",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Questa sezione diventerà disponibile nella fase di configurazione successiva.",
|
||||
"newKnowledge.searchSources": "Cerca fonti",
|
||||
"newKnowledge.sourceActions": "Azioni per {{name}}",
|
||||
"newKnowledge.sourceColumn": "Fonte",
|
||||
"newKnowledge.sourceFilterLabel": "Filtra le fonti per stato",
|
||||
"newKnowledge.sourceName": "Nome della fonte",
|
||||
"newKnowledge.sourceNamePlaceholder": "es. scansione della documentazione del prodotto",
|
||||
"newKnowledge.sourceNameRequired": "Inserisci un nome per la fonte.",
|
||||
"newKnowledge.sourceStatus.active": "Attivo",
|
||||
"newKnowledge.sourceStatus.disabled": "Disabilitato",
|
||||
"newKnowledge.sourceStatus.error": "Errore",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Inizia con",
|
||||
"newKnowledge.startWithHelp": "Puoi aggiungere più fonti o documenti in qualsiasi momento.",
|
||||
"newKnowledge.statusColumn": "Stato",
|
||||
"newKnowledge.stopCrawl": "Interrompi",
|
||||
"newKnowledge.stoppingCrawl": "Interruzione in corso…",
|
||||
"newKnowledge.syncNow": "Sincronizza ora",
|
||||
"newKnowledge.syncPolicyColumn": "Criterio di sincronizzazione",
|
||||
"newKnowledge.tags": "Tag",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Aggiornato il {{date}}",
|
||||
"newKnowledge.uploadFiles": "Carica file",
|
||||
"newKnowledge.uploadFilesDescription": "Aggiungi file dal computer: vengono indicizzati appena li crei.",
|
||||
"newKnowledge.usingDefaults": "Impostazioni predefinite in uso",
|
||||
"newKnowledge.viewLabel": "Vista conoscenza",
|
||||
"newKnowledge.websiteCrawl": "Scansione del sito web",
|
||||
"noExternalKnowledge": "Non esiste ancora un'API di conoscenza esterna, fai clic qui per creare",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "アクション",
|
||||
"newKnowledge.addSource": "ソースを追加",
|
||||
"newKnowledge.addSourceDescription": "ソースをこのナレッジ ベースに接続すると、自動的に同期され、最新の状態が保たれます。",
|
||||
"newKnowledge.addSourceRequiresSelection": "追加前にクロール済みページを1つ以上選択してください。",
|
||||
"newKnowledge.adjustAndRecrawl": "調整して再クロール",
|
||||
"newKnowledge.allSources": "すべてのソース",
|
||||
"newKnowledge.appsUnavailable": "— 個のアプリ",
|
||||
"newKnowledge.authKind.api-key": "APIキー",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Web サイトのソースを追加する前に接続を更新してください。",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} が接続中です",
|
||||
"newKnowledge.connectionRefreshFailed": "この接続を更新できませんでした。もう一度やり直してください。",
|
||||
"newKnowledge.crawlAndPreview": "クロールとプレビュー",
|
||||
"newKnowledge.crawlFailed": "{{host}} をクロールできませんでした",
|
||||
"newKnowledge.crawlFailed403": "サイトから403が返されました。クローラーがブロックされているか、認証が必要な可能性があります。URLを確認し、クロールオプションを調整するか、別のプロバイダーを試してください。",
|
||||
"newKnowledge.crawlFailedDescription": "クローラーはこのプレビューを完了できませんでした。URLを確認し、クロールオプションを調整するか、もう一度お試しください。",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}}でエラーが報告されました。プロバイダー接続を確認して、もう一度お試しください。",
|
||||
"newKnowledge.crawlFailedTimeout": "クロールがタイムアウトしました。対象を絞ったURLを指定するか、最大ページ数を減らしてください。",
|
||||
"newKnowledge.crawlOptions": "クロールオプション",
|
||||
"newKnowledge.crawlProgress": "{{host}} のクロール進行状況",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Web サイトのクロール設定は、クロール ワークフローが利用可能になるまで無効になります。",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl の準備ができました",
|
||||
"newKnowledge.crawlStartFailed": "クロールプレビューを開始できませんでした。もう一度お試しください。",
|
||||
"newKnowledge.crawlStopped": "クロールを停止しました",
|
||||
"newKnowledge.crawling": "クロール中…",
|
||||
"newKnowledge.crawlingPages": "{{host}} をクロール中… {{count}}ページが見つかりました",
|
||||
"newKnowledge.createFailed": "このナレッジ ベースを作成できませんでした。アクセスを確認して再試行してください。",
|
||||
"newKnowledge.createTitle": "知識の創造",
|
||||
"newKnowledge.creators": "作成者",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "下書きを破棄",
|
||||
"newKnowledge.discardDraftDescription": "このナレッジベースの下書きに加えた変更は失われます。",
|
||||
"newKnowledge.discardDraftTitle": "このナレッジベースの下書きを破棄しますか?",
|
||||
"newKnowledge.discardSourceDraftDescription": "ソース設定とクロールプレビューは削除されます。",
|
||||
"newKnowledge.discardSourceDraftFailed": "ソースの下書きを破棄できませんでした。もう一度お試しください。",
|
||||
"newKnowledge.discardSourceDraftTitle": "このソースの下書きを破棄しますか?",
|
||||
"newKnowledge.documents": "書類",
|
||||
"newKnowledge.documentsUnavailable": "— 件のドキュメント",
|
||||
"newKnowledge.emptyDescription": "ドキュメントを追加すると、エージェントが直接読み取れます。インデックス設定は不要です。",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "ソースを接続すると、そのドキュメントは同期され、自動的にインデックス化されてすぐに利用できます。管理する設定はありません。従来のナレッジベースもこれまでどおり動作します。",
|
||||
"newKnowledge.guideTitle": "新しいナレッジベースへようこそ ✨",
|
||||
"newKnowledge.illustrationHeadline": "コンテンツを一度接続すれば、すべてのアプリが最新のナレッジで回答します。",
|
||||
"newKnowledge.includeSubpages": "サブページを含める",
|
||||
"newKnowledge.invalidRootUrl": "有効なhttp(s) URLを入力してください。",
|
||||
"newKnowledge.lastSyncColumn": "最終同期",
|
||||
"newKnowledge.learnMore": "詳細を見る",
|
||||
"newKnowledge.leavePartialSetupConfirm": "セットアップを終了",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "未完了のセットアップを終了しますか?",
|
||||
"newKnowledge.legacy": "旧バージョン",
|
||||
"newKnowledge.loadMore": "さらに読み込む",
|
||||
"newKnowledge.maxPages": "最大ページ数",
|
||||
"newKnowledge.moreProviders": "もっと見る",
|
||||
"newKnowledge.name": "ナレッジ名",
|
||||
"newKnowledge.namePlaceholder": "例:カスタマーサポートハンドブック",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "新バージョン",
|
||||
"newKnowledge.noDescription": "説明なし",
|
||||
"newKnowledge.noMatchingSources": "この検索に一致するソースはありません。",
|
||||
"newKnowledge.noPagesFound": "{{host}} でページが見つかりませんでした",
|
||||
"newKnowledge.noPagesFoundDescription": "サイトには到達しましたが、インデックス可能なページが見つかりませんでした。別のURLを試すか、クロールオプションを広げてください。",
|
||||
"newKnowledge.notFoundDescription": "このナレッジ ベースは削除されているか、アクセスできない可能性があります。",
|
||||
"newKnowledge.notFoundTitle": "ナレッジベースが見つかりません",
|
||||
"newKnowledge.onlineDocuments": "オンライン文書",
|
||||
"newKnowledge.onlineDrive": "オンラインドライブ",
|
||||
"newKnowledge.pagesAppearDescription": "サイトをクロールして、追加されるページを確認します。",
|
||||
"newKnowledge.pagesAppearTitle": "ページはここに表示されます",
|
||||
"newKnowledge.pagesCrawled": "{{host}} で{{count}}ページをクロールしました",
|
||||
"newKnowledge.permission": "許可",
|
||||
"newKnowledge.permissionAllMembers": "ワークスペース · すべてのメンバーが表示および編集できます",
|
||||
"newKnowledge.permissionOnlyMe": "私だけ",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} が構成されていません",
|
||||
"newKnowledge.providerNotConfiguredDescription": "{{provider}} を使用して Web サイトをクロールするための API キーまたはエンドポイント URL を追加します。",
|
||||
"newKnowledge.providerUnavailable": "このプロバイダーは利用できません。",
|
||||
"newKnowledge.reCrawl": "再クロール",
|
||||
"newKnowledge.readOnlyEmpty": "最初のナレッジベースの作成をワークスペース編集者に依頼してください。",
|
||||
"newKnowledge.refreshConnectionStatus": "ステータスの更新",
|
||||
"newKnowledge.refreshingConnection": "爽やか…",
|
||||
"newKnowledge.removeSource": "ソースを削除",
|
||||
"newKnowledge.retryCrawl": "クロールを再試行",
|
||||
"newKnowledge.retryProviderLoad": "再試行",
|
||||
"newKnowledge.rootUrl": "ルートURL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "このセクションは、次のセットアップ手順で使用できるようになります。",
|
||||
"newKnowledge.searchSources": "ソースを検索",
|
||||
"newKnowledge.sourceActions": "{{name}} のアクション",
|
||||
"newKnowledge.sourceColumn": "ソース",
|
||||
"newKnowledge.sourceFilterLabel": "ソースをステータスでフィルタリングする",
|
||||
"newKnowledge.sourceName": "ソース名",
|
||||
"newKnowledge.sourceNamePlaceholder": "例:製品ドキュメントのクロール",
|
||||
"newKnowledge.sourceNameRequired": "ソース名を入力してください。",
|
||||
"newKnowledge.sourceStatus.active": "アクティブ",
|
||||
"newKnowledge.sourceStatus.disabled": "無効",
|
||||
"newKnowledge.sourceStatus.error": "エラー",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "から始める",
|
||||
"newKnowledge.startWithHelp": "いつでもソースやドキュメントを追加できます。",
|
||||
"newKnowledge.statusColumn": "ステータス",
|
||||
"newKnowledge.stopCrawl": "停止",
|
||||
"newKnowledge.stoppingCrawl": "停止中…",
|
||||
"newKnowledge.syncNow": "今すぐ同期",
|
||||
"newKnowledge.syncPolicyColumn": "同期ポリシー",
|
||||
"newKnowledge.tags": "タグ",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "{{date}} に更新",
|
||||
"newKnowledge.uploadFiles": "ファイルをアップロード",
|
||||
"newKnowledge.uploadFilesDescription": "コンピューターからファイルを追加すると、作成時にすぐインデックス化されます。",
|
||||
"newKnowledge.usingDefaults": "デフォルト設定を使用中",
|
||||
"newKnowledge.viewLabel": "ナレッジ表示",
|
||||
"newKnowledge.websiteCrawl": "ウェブサイトのクロール",
|
||||
"noExternalKnowledge": "外部ナレッジベース連携 API がありません。ここをクリックして作成してください",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "작업",
|
||||
"newKnowledge.addSource": "소스 추가",
|
||||
"newKnowledge.addSourceDescription": "이 지식 베이스에 소스를 연결하세요. 자동으로 동기화되고 최신 상태로 유지됩니다.",
|
||||
"newKnowledge.addSourceRequiresSelection": "소스를 추가하기 전에 크롤링된 페이지를 하나 이상 선택하세요.",
|
||||
"newKnowledge.adjustAndRecrawl": "조정 후 다시 크롤링",
|
||||
"newKnowledge.allSources": "모든 소스",
|
||||
"newKnowledge.appsUnavailable": "앱 —개",
|
||||
"newKnowledge.authKind.api-key": "API 키",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "웹사이트 소스를 추가하기 전에 연결을 새로 고치세요.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}}이 연결 중입니다.",
|
||||
"newKnowledge.connectionRefreshFailed": "이 연결을 새로 고칠 수 없습니다. 다시 시도해 보세요.",
|
||||
"newKnowledge.crawlAndPreview": "크롤링 및 미리보기",
|
||||
"newKnowledge.crawlFailed": "{{host}}을(를) 크롤링할 수 없습니다",
|
||||
"newKnowledge.crawlFailed403": "사이트에서 403을 반환했습니다. 크롤러를 차단하거나 인증이 필요할 수 있습니다. URL을 확인하고 크롤링 옵션을 조정하거나 다른 제공업체를 사용해 보세요.",
|
||||
"newKnowledge.crawlFailedDescription": "크롤러가 이 미리보기를 완료하지 못했습니다. URL을 확인하고 크롤링 옵션을 조정한 후 다시 시도하세요.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}}에서 오류를 보고했습니다. 제공업체 연결을 확인하고 다시 시도하세요.",
|
||||
"newKnowledge.crawlFailedTimeout": "크롤링 시간이 초과되었습니다. 범위가 더 좁은 URL을 사용하거나 최대 페이지 수를 줄이세요.",
|
||||
"newKnowledge.crawlOptions": "크롤링 옵션",
|
||||
"newKnowledge.crawlProgress": "{{host}} 크롤링 진행률",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "크롤링 워크플로를 사용할 수 있을 때까지 웹사이트 크롤링 구성이 비활성화됩니다.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl이 준비되었습니다.",
|
||||
"newKnowledge.crawlStartFailed": "크롤링 미리보기를 시작할 수 없습니다. 다시 시도하세요.",
|
||||
"newKnowledge.crawlStopped": "크롤링이 중지됨",
|
||||
"newKnowledge.crawling": "크롤링 중…",
|
||||
"newKnowledge.crawlingPages": "{{host}} 크롤링 중… {{count}}개 페이지 발견",
|
||||
"newKnowledge.createFailed": "이 기술 자료를 만들 수 없습니다. 액세스 권한을 확인하고 다시 시도하세요.",
|
||||
"newKnowledge.createTitle": "지식 창조",
|
||||
"newKnowledge.creators": "생성자",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "초안 삭제",
|
||||
"newKnowledge.discardDraftDescription": "이 지식 베이스 초안의 변경 사항이 삭제됩니다.",
|
||||
"newKnowledge.discardDraftTitle": "이 지식 베이스 초안을 삭제할까요?",
|
||||
"newKnowledge.discardSourceDraftDescription": "소스 구성과 크롤링 미리보기가 삭제됩니다.",
|
||||
"newKnowledge.discardSourceDraftFailed": "소스 초안을 삭제할 수 없습니다. 다시 시도하세요.",
|
||||
"newKnowledge.discardSourceDraftTitle": "이 소스 초안을 삭제할까요?",
|
||||
"newKnowledge.documents": "문서",
|
||||
"newKnowledge.documentsUnavailable": "문서 —개",
|
||||
"newKnowledge.emptyDescription": "문서를 추가하면 에이전트가 직접 읽을 수 있습니다. 인덱싱 설정은 필요하지 않습니다.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "소스를 연결하면 문서가 계속 동기화되고 자동으로 인덱싱되어 바로 사용할 수 있습니다. 관리할 설정은 없습니다. 기존 지식 베이스도 그대로 작동합니다.",
|
||||
"newKnowledge.guideTitle": "새로운 지식 베이스를 만나보세요 ✨",
|
||||
"newKnowledge.illustrationHeadline": "콘텐츠를 한 번 연결하면 모든 앱이 최신 지식으로 답변합니다.",
|
||||
"newKnowledge.includeSubpages": "하위 페이지 포함",
|
||||
"newKnowledge.invalidRootUrl": "유효한 http(s) URL을 입력하세요.",
|
||||
"newKnowledge.lastSyncColumn": "마지막 동기화",
|
||||
"newKnowledge.learnMore": "자세히 알아보기",
|
||||
"newKnowledge.leavePartialSetupConfirm": "설정 나가기",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "완료되지 않은 설정을 나갈까요?",
|
||||
"newKnowledge.legacy": "레거시",
|
||||
"newKnowledge.loadMore": "더 보기",
|
||||
"newKnowledge.maxPages": "최대 페이지 수",
|
||||
"newKnowledge.moreProviders": "더보기",
|
||||
"newKnowledge.name": "지식 이름",
|
||||
"newKnowledge.namePlaceholder": "예를 들어 고객 지원 핸드북",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "신규",
|
||||
"newKnowledge.noDescription": "설명 없음",
|
||||
"newKnowledge.noMatchingSources": "이 검색과 일치하는 소스가 없습니다.",
|
||||
"newKnowledge.noPagesFound": "{{host}}에서 페이지를 찾을 수 없습니다",
|
||||
"newKnowledge.noPagesFoundDescription": "사이트에 접속했지만 색인 가능한 페이지를 찾지 못했습니다. 다른 URL을 사용하거나 크롤링 옵션을 확장하세요.",
|
||||
"newKnowledge.notFoundDescription": "이 기술 자료가 삭제되었거나 액세스 권한이 없을 수 있습니다.",
|
||||
"newKnowledge.notFoundTitle": "기술 자료를 찾을 수 없습니다.",
|
||||
"newKnowledge.onlineDocuments": "온라인 문서",
|
||||
"newKnowledge.onlineDrive": "온라인 드라이브",
|
||||
"newKnowledge.pagesAppearDescription": "사이트를 크롤링하여 추가될 페이지를 확인하세요.",
|
||||
"newKnowledge.pagesAppearTitle": "페이지가 여기에 표시됩니다",
|
||||
"newKnowledge.pagesCrawled": "{{host}}에서 {{count}}개 페이지를 크롤링했습니다",
|
||||
"newKnowledge.permission": "허가",
|
||||
"newKnowledge.permissionAllMembers": "작업공간 · 모든 구성원이 보고 편집할 수 있습니다.",
|
||||
"newKnowledge.permissionOnlyMe": "나만",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}}이 구성되지 않았습니다.",
|
||||
"newKnowledge.providerNotConfiguredDescription": "{{provider}}을(를) 사용하여 웹사이트를 크롤링하려면 API 키 또는 엔드포인트 URL을 추가하세요.",
|
||||
"newKnowledge.providerUnavailable": "이 제공자를 사용할 수 없습니다.",
|
||||
"newKnowledge.reCrawl": "다시 크롤링",
|
||||
"newKnowledge.readOnlyEmpty": "워크스페이스 편집자에게 첫 번째 지식 베이스 생성을 요청하세요.",
|
||||
"newKnowledge.refreshConnectionStatus": "새로 고침 상태",
|
||||
"newKnowledge.refreshingConnection": "상쾌하다…",
|
||||
"newKnowledge.removeSource": "소스 제거",
|
||||
"newKnowledge.retryCrawl": "크롤링 다시 시도",
|
||||
"newKnowledge.retryProviderLoad": "재시도",
|
||||
"newKnowledge.rootUrl": "루트 URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "이 섹션은 다음 설정 단계에서 사용할 수 있습니다.",
|
||||
"newKnowledge.searchSources": "소스 검색",
|
||||
"newKnowledge.sourceActions": "{{name}}에 대한 작업",
|
||||
"newKnowledge.sourceColumn": "출처",
|
||||
"newKnowledge.sourceFilterLabel": "상태별로 소스 필터링",
|
||||
"newKnowledge.sourceName": "소스 이름",
|
||||
"newKnowledge.sourceNamePlaceholder": "예: 제품 문서 크롤링",
|
||||
"newKnowledge.sourceNameRequired": "소스 이름을 입력하세요.",
|
||||
"newKnowledge.sourceStatus.active": "활성",
|
||||
"newKnowledge.sourceStatus.disabled": "비활성화됨",
|
||||
"newKnowledge.sourceStatus.error": "오류",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "다음으로 시작",
|
||||
"newKnowledge.startWithHelp": "언제든지 더 많은 소스나 문서를 추가할 수 있습니다.",
|
||||
"newKnowledge.statusColumn": "상태",
|
||||
"newKnowledge.stopCrawl": "중지",
|
||||
"newKnowledge.stoppingCrawl": "중지 중…",
|
||||
"newKnowledge.syncNow": "지금 동기화",
|
||||
"newKnowledge.syncPolicyColumn": "동기화 정책",
|
||||
"newKnowledge.tags": "태그",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "{{date}} 업데이트",
|
||||
"newKnowledge.uploadFiles": "파일 업로드",
|
||||
"newKnowledge.uploadFilesDescription": "컴퓨터에서 파일을 추가하면 생성 즉시 인덱싱됩니다.",
|
||||
"newKnowledge.usingDefaults": "기본값 사용 중",
|
||||
"newKnowledge.viewLabel": "지식 보기",
|
||||
"newKnowledge.websiteCrawl": "웹사이트 크롤링",
|
||||
"noExternalKnowledge": "아직 외부 지식 API 가 없으므로 여기를 클릭하여 생성하십시오.",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Acties",
|
||||
"newKnowledge.addSource": "Bron toevoegen",
|
||||
"newKnowledge.addSourceDescription": "Verbind een bron met deze kennisbank: deze synchroniseert automatisch en blijft actueel.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Selecteer minstens één gecrawlde pagina voordat je de bron toevoegt.",
|
||||
"newKnowledge.adjustAndRecrawl": "Aanpassen en opnieuw crawlen",
|
||||
"newKnowledge.allSources": "Alle bronnen",
|
||||
"newKnowledge.appsUnavailable": "— apps",
|
||||
"newKnowledge.authKind.api-key": "API-sleutel",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Vernieuw de verbinding voordat u een websitebron toevoegt.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} maakt verbinding",
|
||||
"newKnowledge.connectionRefreshFailed": "We konden deze verbinding niet vernieuwen. Probeer het opnieuw.",
|
||||
"newKnowledge.crawlAndPreview": "Crawlen en bekijken",
|
||||
"newKnowledge.crawlFailed": "Kan {{host}} niet crawlen",
|
||||
"newKnowledge.crawlFailed403": "De site retourneerde 403. Mogelijk worden crawlers geblokkeerd of is authenticatie vereist. Controleer de URL, pas de crawlopties aan of probeer een andere provider.",
|
||||
"newKnowledge.crawlFailedDescription": "De crawler kon dit voorbeeld niet voltooien. Controleer de URL, pas de crawlopties aan of probeer het opnieuw.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} heeft een fout gemeld. Controleer de providerverbinding en probeer het opnieuw.",
|
||||
"newKnowledge.crawlFailedTimeout": "De crawl heeft de tijdslimiet overschreden. Probeer een specifiekere URL of verlaag het maximale aantal pagina’s.",
|
||||
"newKnowledge.crawlOptions": "Crawlopties",
|
||||
"newKnowledge.crawlProgress": "Crawlvoortgang voor {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "De configuratie van de websitecrawl is uitgeschakeld totdat de crawlworkflow beschikbaar is.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl is klaar",
|
||||
"newKnowledge.crawlStartFailed": "Het crawlvoorbeeld kon niet worden gestart. Probeer het opnieuw.",
|
||||
"newKnowledge.crawlStopped": "Crawl gestopt",
|
||||
"newKnowledge.crawling": "Bezig met crawlen…",
|
||||
"newKnowledge.crawlingPages": "{{host}} wordt gecrawld… {{count}} pagina’s gevonden",
|
||||
"newKnowledge.createFailed": "We konden deze kennisbank niet creëren. Controleer uw toegang en probeer het opnieuw.",
|
||||
"newKnowledge.createTitle": "Creëer kennis",
|
||||
"newKnowledge.creators": "Makers",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Concept verwijderen",
|
||||
"newKnowledge.discardDraftDescription": "Uw wijzigingen aan dit kennisbankconcept gaan verloren.",
|
||||
"newKnowledge.discardDraftTitle": "Dit kennisbankconcept verwijderen?",
|
||||
"newKnowledge.discardSourceDraftDescription": "De bronconfiguratie en het crawlvoorbeeld worden verwijderd.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Het bronconcept kon niet worden verwijderd. Probeer het opnieuw.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Dit bronconcept verwijderen?",
|
||||
"newKnowledge.documents": "Documenten",
|
||||
"newKnowledge.documentsUnavailable": "— documenten",
|
||||
"newKnowledge.emptyDescription": "Voeg je documenten toe zodat agents ze direct kunnen lezen, zonder indexering te configureren.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Verbind een bron en de documenten blijven gesynchroniseerd, automatisch geïndexeerd en direct klaar voor gebruik, zonder beheer. Je bestaande kennisbanken blijven ongewijzigd werken.",
|
||||
"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": "Subpagina’s opnemen",
|
||||
"newKnowledge.invalidRootUrl": "Voer een geldige http(s)-URL in.",
|
||||
"newKnowledge.lastSyncColumn": "Laatste synchronisatie",
|
||||
"newKnowledge.learnMore": "Meer informatie",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Configuratie verlaten",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Onvoltooide configuratie verlaten?",
|
||||
"newKnowledge.legacy": "Oud",
|
||||
"newKnowledge.loadMore": "Meer laden",
|
||||
"newKnowledge.maxPages": "Maximumaantal pagina’s",
|
||||
"newKnowledge.moreProviders": "View more",
|
||||
"newKnowledge.name": "Kennis naam",
|
||||
"newKnowledge.namePlaceholder": "bijv. Handboek voor klantenondersteuning",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Nieuw",
|
||||
"newKnowledge.noDescription": "Geen beschrijving",
|
||||
"newKnowledge.noMatchingSources": "Er zijn geen bronnen die overeenkomen met deze zoekopdracht.",
|
||||
"newKnowledge.noPagesFound": "Geen pagina’s gevonden op {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "De crawler bereikte de site, maar vond geen indexeerbare pagina’s. Probeer een andere URL of breid de crawlopties uit.",
|
||||
"newKnowledge.notFoundDescription": "Deze kennisbank is mogelijk verwijderd of u heeft mogelijk geen toegang.",
|
||||
"newKnowledge.notFoundTitle": "Kennisbank niet gevonden",
|
||||
"newKnowledge.onlineDocuments": "Onlinedocumenten",
|
||||
"newKnowledge.onlineDrive": "Online rijden",
|
||||
"newKnowledge.pagesAppearDescription": "Crawl de site om te bekijken welke pagina’s worden toegevoegd.",
|
||||
"newKnowledge.pagesAppearTitle": "Pagina’s verschijnen hier",
|
||||
"newKnowledge.pagesCrawled": "{{count}} pagina’s gecrawld op {{host}}",
|
||||
"newKnowledge.permission": "Toestemming",
|
||||
"newKnowledge.permissionAllMembers": "Werkruimte · alle leden kunnen bekijken en bewerken",
|
||||
"newKnowledge.permissionOnlyMe": "Alleen ik",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} is niet geconfigureerd",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Voeg een API-sleutel of eindpunt-URL toe om websites te crawlen met {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Deze aanbieder is niet beschikbaar.",
|
||||
"newKnowledge.reCrawl": "Opnieuw crawlen",
|
||||
"newKnowledge.readOnlyEmpty": "Vraag een werkruimte-editor om de eerste kennisbank te maken.",
|
||||
"newKnowledge.refreshConnectionStatus": "Vernieuwingsstatus",
|
||||
"newKnowledge.refreshingConnection": "Verfrissen…",
|
||||
"newKnowledge.removeSource": "Bron verwijderen",
|
||||
"newKnowledge.retryCrawl": "Crawl opnieuw proberen",
|
||||
"newKnowledge.retryProviderLoad": "Probeer het opnieuw",
|
||||
"newKnowledge.rootUrl": "Hoofd-URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Deze sectie komt beschikbaar in de volgende installatiestap.",
|
||||
"newKnowledge.searchSources": "Zoek bronnen",
|
||||
"newKnowledge.sourceActions": "Acties voor {{name}}",
|
||||
"newKnowledge.sourceColumn": "Bron",
|
||||
"newKnowledge.sourceFilterLabel": "Filter bronnen op status",
|
||||
"newKnowledge.sourceName": "Bronnaam",
|
||||
"newKnowledge.sourceNamePlaceholder": "bijv. crawl van productdocumentatie",
|
||||
"newKnowledge.sourceNameRequired": "Voer een bronnaam in.",
|
||||
"newKnowledge.sourceStatus.active": "Actief",
|
||||
"newKnowledge.sourceStatus.disabled": "Uitgeschakeld",
|
||||
"newKnowledge.sourceStatus.error": "Fout",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Begin met",
|
||||
"newKnowledge.startWithHelp": "U kunt op elk gewenst moment meer bronnen of documenten toevoegen.",
|
||||
"newKnowledge.statusColumn": "Status",
|
||||
"newKnowledge.stopCrawl": "Stoppen",
|
||||
"newKnowledge.stoppingCrawl": "Bezig met stoppen…",
|
||||
"newKnowledge.syncNow": "Synchroniseer nu",
|
||||
"newKnowledge.syncPolicyColumn": "Synchronisatiebeleid",
|
||||
"newKnowledge.tags": "Tags",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Bijgewerkt op {{date}}",
|
||||
"newKnowledge.uploadFiles": "Bestanden uploaden",
|
||||
"newKnowledge.uploadFilesDescription": "Voeg bestanden van je computer toe; ze worden geïndexeerd zodra je ze aanmaakt.",
|
||||
"newKnowledge.usingDefaults": "Standaardinstellingen gebruikt",
|
||||
"newKnowledge.viewLabel": "Kennisweergave",
|
||||
"newKnowledge.websiteCrawl": "Websitecrawl",
|
||||
"noExternalKnowledge": "There is no External Knowledge API yet, click here to create",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Działania",
|
||||
"newKnowledge.addSource": "Dodaj źródło",
|
||||
"newKnowledge.addSourceDescription": "Podłącz źródło do tej bazy wiedzy — synchronizuje się ona automatycznie i pozostaje aktualna.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Przed dodaniem źródła wybierz co najmniej jedną zindeksowaną stronę.",
|
||||
"newKnowledge.adjustAndRecrawl": "Dostosuj i przeskanuj ponownie",
|
||||
"newKnowledge.allSources": "Wszystkie źródła",
|
||||
"newKnowledge.appsUnavailable": "— aplikacji",
|
||||
"newKnowledge.authKind.api-key": "Klucz API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Odśwież połączenie przed dodaniem źródła strony internetowej.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} łączy się",
|
||||
"newKnowledge.connectionRefreshFailed": "Nie mogliśmy odświeżyć tego połączenia. Spróbuj ponownie.",
|
||||
"newKnowledge.crawlAndPreview": "Indeksowanie i podgląd",
|
||||
"newKnowledge.crawlFailed": "Nie udało się przeskanować {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Witryna zwróciła błąd 403 — może blokować roboty indeksujące lub wymagać uwierzytelnienia. Sprawdź adres URL, dostosuj opcje skanowania albo użyj innego dostawcy.",
|
||||
"newKnowledge.crawlFailedDescription": "Robot nie mógł ukończyć tego podglądu. Sprawdź adres URL, dostosuj opcje skanowania lub spróbuj ponownie.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} zgłosił błąd. Sprawdź połączenie z dostawcą i spróbuj ponownie.",
|
||||
"newKnowledge.crawlFailedTimeout": "Przekroczono limit czasu skanowania. Użyj bardziej szczegółowego adresu URL lub zmniejsz maksymalną liczbę stron.",
|
||||
"newKnowledge.crawlOptions": "Opcje skanowania",
|
||||
"newKnowledge.crawlProgress": "Postęp skanowania {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Konfiguracja indeksowania witryny jest wyłączona do czasu udostępnienia przepływu pracy indeksowania.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl jest gotowy",
|
||||
"newKnowledge.crawlStartFailed": "Nie udało się uruchomić podglądu skanowania. Spróbuj ponownie.",
|
||||
"newKnowledge.crawlStopped": "Skanowanie zatrzymane",
|
||||
"newKnowledge.crawling": "Skanowanie…",
|
||||
"newKnowledge.crawlingPages": "Skanowanie {{host}}… znaleziono {{count}} stron",
|
||||
"newKnowledge.createFailed": "Nie mogliśmy utworzyć tej bazy wiedzy. Sprawdź swój dostęp i spróbuj ponownie.",
|
||||
"newKnowledge.createTitle": "Twórz wiedzę",
|
||||
"newKnowledge.creators": "Twórcy",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Odrzuć wersję roboczą",
|
||||
"newKnowledge.discardDraftDescription": "Zmiany w tej wersji roboczej bazy wiedzy zostaną utracone.",
|
||||
"newKnowledge.discardDraftTitle": "Odrzucić tę wersję roboczą bazy wiedzy?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Konfiguracja źródła i podgląd skanowania zostaną usunięte.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Nie udało się odrzucić wersji roboczej źródła. Spróbuj ponownie.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Odrzucić tę wersję roboczą źródła?",
|
||||
"newKnowledge.documents": "Dokumenty",
|
||||
"newKnowledge.documentsUnavailable": "— dokumentów",
|
||||
"newKnowledge.emptyDescription": "Dodaj dokumenty, aby agenci mogli je czytać bezpośrednio — bez konfigurowania indeksowania.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Połącz źródło, a jego dokumenty pozostaną zsynchronizowane, automatycznie zindeksowane i gotowe do użycia, bez konieczności zarządzania konfiguracją. Dotychczasowe bazy wiedzy będą nadal działać bez zmian.",
|
||||
"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.invalidRootUrl": "Wprowadź prawidłowy adres URL http(s).",
|
||||
"newKnowledge.lastSyncColumn": "Ostatnia synchronizacja",
|
||||
"newKnowledge.learnMore": "Dowiedz się więcej",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Opuść konfigurację",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Opuścić nieukończoną konfigurację?",
|
||||
"newKnowledge.legacy": "Starsza wersja",
|
||||
"newKnowledge.loadMore": "Załaduj więcej",
|
||||
"newKnowledge.maxPages": "Maksymalna liczba stron",
|
||||
"newKnowledge.moreProviders": "Zobacz więcej",
|
||||
"newKnowledge.name": "Nazwa wiedzy",
|
||||
"newKnowledge.namePlaceholder": "np. Podręcznik obsługi klienta",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Nowa wersja",
|
||||
"newKnowledge.noDescription": "Brak opisu",
|
||||
"newKnowledge.noMatchingSources": "Żadne źródła nie pasują do tego wyszukiwania.",
|
||||
"newKnowledge.noPagesFound": "Nie znaleziono stron w {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "Robot dotarł do witryny, ale nie znalazł stron możliwych do zindeksowania. Użyj innego adresu URL lub rozszerz opcje skanowania.",
|
||||
"newKnowledge.notFoundDescription": "Ta baza wiedzy mogła zostać usunięta lub możesz nie mieć do niej dostępu.",
|
||||
"newKnowledge.notFoundTitle": "Nie znaleziono bazy wiedzy",
|
||||
"newKnowledge.onlineDocuments": "Dokumenty online",
|
||||
"newKnowledge.onlineDrive": "Dysk online",
|
||||
"newKnowledge.pagesAppearDescription": "Przeskanuj witrynę, aby sprawdzić, które strony zostaną dodane.",
|
||||
"newKnowledge.pagesAppearTitle": "Strony pojawią się tutaj",
|
||||
"newKnowledge.pagesCrawled": "Przeskanowano {{count}} stron w {{host}}",
|
||||
"newKnowledge.permission": "Pozwolenie",
|
||||
"newKnowledge.permissionAllMembers": "Obszar roboczy · wszyscy członkowie mogą przeglądać i edytować",
|
||||
"newKnowledge.permissionOnlyMe": "Tylko ja",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} nie jest skonfigurowany",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Dodaj klucz API lub adres URL punktu końcowego, aby indeksować strony internetowe za pomocą {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Ten dostawca jest niedostępny.",
|
||||
"newKnowledge.reCrawl": "Przeskanuj ponownie",
|
||||
"newKnowledge.readOnlyEmpty": "Poproś edytora obszaru roboczego o utworzenie pierwszej bazy wiedzy.",
|
||||
"newKnowledge.refreshConnectionStatus": "Odśwież status",
|
||||
"newKnowledge.refreshingConnection": "Odświeżanie…",
|
||||
"newKnowledge.removeSource": "Usuń źródło",
|
||||
"newKnowledge.retryCrawl": "Ponów skanowanie",
|
||||
"newKnowledge.retryProviderLoad": "Spróbuj ponownie",
|
||||
"newKnowledge.rootUrl": "Główny adres URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Ta sekcja będzie dostępna w następnym kroku konfiguracji.",
|
||||
"newKnowledge.searchSources": "Wyszukaj źródła",
|
||||
"newKnowledge.sourceActions": "Działania dla {{name}}",
|
||||
"newKnowledge.sourceColumn": "Źródło",
|
||||
"newKnowledge.sourceFilterLabel": "Filtruj źródła według stanu",
|
||||
"newKnowledge.sourceName": "Nazwa źródła",
|
||||
"newKnowledge.sourceNamePlaceholder": "np. skanowanie dokumentacji produktu",
|
||||
"newKnowledge.sourceNameRequired": "Wprowadź nazwę źródła.",
|
||||
"newKnowledge.sourceStatus.active": "Aktywny",
|
||||
"newKnowledge.sourceStatus.disabled": "Wyłączone",
|
||||
"newKnowledge.sourceStatus.error": "Błąd",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Zacznij od",
|
||||
"newKnowledge.startWithHelp": "W dowolnym momencie możesz dodać więcej źródeł lub dokumentów.",
|
||||
"newKnowledge.statusColumn": "Stan",
|
||||
"newKnowledge.stopCrawl": "Zatrzymaj",
|
||||
"newKnowledge.stoppingCrawl": "Zatrzymywanie…",
|
||||
"newKnowledge.syncNow": "Synchronizuj teraz",
|
||||
"newKnowledge.syncPolicyColumn": "Polityka synchronizacji",
|
||||
"newKnowledge.tags": "Tagi",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Zaktualizowano {{date}}",
|
||||
"newKnowledge.uploadFiles": "Prześlij pliki",
|
||||
"newKnowledge.uploadFilesDescription": "Dodaj pliki z komputera — zostaną zindeksowane od razu po utworzeniu.",
|
||||
"newKnowledge.usingDefaults": "Używane są ustawienia domyślne",
|
||||
"newKnowledge.viewLabel": "Widok wiedzy",
|
||||
"newKnowledge.websiteCrawl": "Indeksowanie witryny",
|
||||
"noExternalKnowledge": "Nie ma jeszcze interfejsu API wiedzy zewnętrznej, kliknij tutaj, aby utworzyć",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Ações",
|
||||
"newKnowledge.addSource": "Adicionar fonte",
|
||||
"newKnowledge.addSourceDescription": "Conecte uma fonte a esta base de conhecimento — ela sincroniza automaticamente e permanece atualizada.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Selecione pelo menos uma página rastreada antes de adicionar a fonte.",
|
||||
"newKnowledge.adjustAndRecrawl": "Ajustar e rastrear novamente",
|
||||
"newKnowledge.allSources": "Todas as fontes",
|
||||
"newKnowledge.appsUnavailable": "— apps",
|
||||
"newKnowledge.authKind.api-key": "Chave de API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Atualize a conexão antes de adicionar uma fonte de site.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} está se conectando",
|
||||
"newKnowledge.connectionRefreshFailed": "Não foi possível atualizar esta conexão. Tente novamente.",
|
||||
"newKnowledge.crawlAndPreview": "Rastreamento e visualização",
|
||||
"newKnowledge.crawlFailed": "Não foi possível rastrear {{host}}",
|
||||
"newKnowledge.crawlFailed403": "O site retornou 403 — ele pode bloquear rastreadores ou exigir autenticação. Verifique a URL, ajuste as opções de rastreamento ou tente outro provedor.",
|
||||
"newKnowledge.crawlFailedDescription": "O rastreador não conseguiu concluir esta visualização. Verifique a URL, ajuste as opções de rastreamento ou tente novamente.",
|
||||
"newKnowledge.crawlFailedProvider": "O {{provider}} informou um erro. Verifique a conexão do provedor e tente novamente.",
|
||||
"newKnowledge.crawlFailedTimeout": "O tempo limite do rastreamento expirou. Tente uma URL mais específica ou reduza o número máximo de páginas.",
|
||||
"newKnowledge.crawlOptions": "Opções de rastreamento",
|
||||
"newKnowledge.crawlProgress": "Progresso do rastreamento de {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "A configuração de rastreamento de sites será desativada até que o fluxo de trabalho de rastreamento esteja disponível.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "O Firecrawl está pronto",
|
||||
"newKnowledge.crawlStartFailed": "Não foi possível iniciar a visualização do rastreamento. Tente novamente.",
|
||||
"newKnowledge.crawlStopped": "Rastreamento interrompido",
|
||||
"newKnowledge.crawling": "Rastreando…",
|
||||
"newKnowledge.crawlingPages": "Rastreando {{host}}… {{count}} páginas encontradas",
|
||||
"newKnowledge.createFailed": "Não foi possível criar esta base de conhecimento. Verifique seu acesso e tente novamente.",
|
||||
"newKnowledge.createTitle": "Crie Conhecimento",
|
||||
"newKnowledge.creators": "Criadores",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Descartar rascunho",
|
||||
"newKnowledge.discardDraftDescription": "Suas alterações neste rascunho da base de conhecimento serão perdidas.",
|
||||
"newKnowledge.discardDraftTitle": "Descartar este rascunho da base de conhecimento?",
|
||||
"newKnowledge.discardSourceDraftDescription": "A configuração da fonte e a visualização do rastreamento serão removidas.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Não foi possível descartar o rascunho da fonte. Tente novamente.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Descartar este rascunho de fonte?",
|
||||
"newKnowledge.documents": "Documentos",
|
||||
"newKnowledge.documentsUnavailable": "— documentos",
|
||||
"newKnowledge.emptyDescription": "Adicione seus documentos para que os agentes possam lê-los diretamente, sem configurar a indexação.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Conecte uma fonte e os documentos permanecerão sincronizados, indexados automaticamente e prontos para uso, sem nada para gerenciar. Suas bases de conhecimento anteriores continuarão funcionando normalmente.",
|
||||
"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.invalidRootUrl": "Insira uma URL http(s) válida.",
|
||||
"newKnowledge.lastSyncColumn": "Última sincronização",
|
||||
"newKnowledge.learnMore": "Saiba mais",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Sair da configuração",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Sair da configuração incompleta?",
|
||||
"newKnowledge.legacy": "Legado",
|
||||
"newKnowledge.loadMore": "Carregar mais",
|
||||
"newKnowledge.maxPages": "Máximo de páginas",
|
||||
"newKnowledge.moreProviders": "Ver mais",
|
||||
"newKnowledge.name": "Nome do conhecimento",
|
||||
"newKnowledge.namePlaceholder": "por exemplo Manual de Suporte ao Cliente",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Novo",
|
||||
"newKnowledge.noDescription": "Sem descrição",
|
||||
"newKnowledge.noMatchingSources": "Nenhuma fonte corresponde a esta pesquisa.",
|
||||
"newKnowledge.noPagesFound": "Nenhuma página encontrada em {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "O rastreador acessou o site, mas não encontrou páginas indexáveis. Tente outra URL ou amplie as opções de rastreamento.",
|
||||
"newKnowledge.notFoundDescription": "Esta base de conhecimento pode ter sido excluída ou você pode não ter acesso.",
|
||||
"newKnowledge.notFoundTitle": "Base de conhecimento não encontrada",
|
||||
"newKnowledge.onlineDocuments": "Documentos on-line",
|
||||
"newKnowledge.onlineDrive": "Unidade on-line",
|
||||
"newKnowledge.pagesAppearDescription": "Rastreie o site para revisar quais páginas serão adicionadas.",
|
||||
"newKnowledge.pagesAppearTitle": "As páginas aparecerão aqui",
|
||||
"newKnowledge.pagesCrawled": "{{count}} páginas rastreadas em {{host}}",
|
||||
"newKnowledge.permission": "Permissão",
|
||||
"newKnowledge.permissionAllMembers": "Espaço de trabalho · todos os membros podem visualizar e editar",
|
||||
"newKnowledge.permissionOnlyMe": "Só eu",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} não está configurado",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Adicione uma chave de API ou URL de endpoint para rastrear sites com {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Este provedor não está disponível.",
|
||||
"newKnowledge.reCrawl": "Rastrear novamente",
|
||||
"newKnowledge.readOnlyEmpty": "Peça a um editor do espaço de trabalho para criar a primeira base de conhecimento.",
|
||||
"newKnowledge.refreshConnectionStatus": "Atualizar status",
|
||||
"newKnowledge.refreshingConnection": "Refrescante…",
|
||||
"newKnowledge.removeSource": "Remover fonte",
|
||||
"newKnowledge.retryCrawl": "Tentar rastreamento novamente",
|
||||
"newKnowledge.retryProviderLoad": "Tentar novamente",
|
||||
"newKnowledge.rootUrl": "URL raiz",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Esta seção estará disponível na próxima etapa de configuração.",
|
||||
"newKnowledge.searchSources": "Fontes de pesquisa",
|
||||
"newKnowledge.sourceActions": "Ações para {{name}}",
|
||||
"newKnowledge.sourceColumn": "Fonte",
|
||||
"newKnowledge.sourceFilterLabel": "Filtrar fontes por status",
|
||||
"newKnowledge.sourceName": "Nome da fonte",
|
||||
"newKnowledge.sourceNamePlaceholder": "ex.: rastreamento da documentação do produto",
|
||||
"newKnowledge.sourceNameRequired": "Insira um nome para a fonte.",
|
||||
"newKnowledge.sourceStatus.active": "Ativo",
|
||||
"newKnowledge.sourceStatus.disabled": "Desativado",
|
||||
"newKnowledge.sourceStatus.error": "Erro",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Comece com",
|
||||
"newKnowledge.startWithHelp": "Você pode adicionar mais fontes ou documentos a qualquer momento.",
|
||||
"newKnowledge.statusColumn": "Estado",
|
||||
"newKnowledge.stopCrawl": "Parar",
|
||||
"newKnowledge.stoppingCrawl": "Parando…",
|
||||
"newKnowledge.syncNow": "Sincronize agora",
|
||||
"newKnowledge.syncPolicyColumn": "Política de sincronização",
|
||||
"newKnowledge.tags": "Tags",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Atualizado em {{date}}",
|
||||
"newKnowledge.uploadFiles": "Enviar arquivos",
|
||||
"newKnowledge.uploadFilesDescription": "Adicione arquivos do seu computador; eles são indexados assim que você os cria.",
|
||||
"newKnowledge.usingDefaults": "Usando valores padrão",
|
||||
"newKnowledge.viewLabel": "Visualização de conhecimento",
|
||||
"newKnowledge.websiteCrawl": "Rastreamento de site",
|
||||
"noExternalKnowledge": "Ainda não existe uma API de conhecimento externo, clique aqui para criar",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Acțiuni",
|
||||
"newKnowledge.addSource": "Adăugați sursa",
|
||||
"newKnowledge.addSourceDescription": "Conectați o sursă la această bază de cunoștințe — se sincronizează automat și rămâne actuală.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Selectează cel puțin o pagină explorată înainte de a adăuga sursa.",
|
||||
"newKnowledge.adjustAndRecrawl": "Ajustează și explorează din nou",
|
||||
"newKnowledge.allSources": "Toate sursele",
|
||||
"newKnowledge.appsUnavailable": "— aplicații",
|
||||
"newKnowledge.authKind.api-key": "cheie API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Reîmprospătați conexiunea înainte de a adăuga o sursă de site.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} se conectează",
|
||||
"newKnowledge.connectionRefreshFailed": "Nu am putut reîmprospăta această conexiune. Încearcă din nou.",
|
||||
"newKnowledge.crawlAndPreview": "Accesați cu crawlere și previzualizați",
|
||||
"newKnowledge.crawlFailed": "Nu s-a putut explora {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Site-ul a returnat 403 — este posibil să blocheze crawlerele sau să necesite autentificare. Verifică adresa URL, ajustează opțiunile de explorare sau încearcă alt furnizor.",
|
||||
"newKnowledge.crawlFailedDescription": "Crawlerul nu a putut finaliza această previzualizare. Verifică adresa URL, ajustează opțiunile de explorare sau încearcă din nou.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} a raportat o eroare. Verifică conexiunea furnizorului și încearcă din nou.",
|
||||
"newKnowledge.crawlFailedTimeout": "Explorarea a depășit timpul limită. Încearcă o adresă URL mai specifică sau redu numărul maxim de pagini.",
|
||||
"newKnowledge.crawlOptions": "Opțiuni de explorare",
|
||||
"newKnowledge.crawlProgress": "Progresul explorării pentru {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Configurarea accesării cu crawlere a site-ului este dezactivată până când fluxul de lucru cu crawlere este disponibil.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl este gata",
|
||||
"newKnowledge.crawlStartFailed": "Previzualizarea explorării nu a putut porni. Încearcă din nou.",
|
||||
"newKnowledge.crawlStopped": "Explorare oprită",
|
||||
"newKnowledge.crawling": "Se explorează…",
|
||||
"newKnowledge.crawlingPages": "Se explorează {{host}}… {{count}} pagini găsite",
|
||||
"newKnowledge.createFailed": "Nu am putut crea această bază de cunoștințe. Verificați accesul și încercați din nou.",
|
||||
"newKnowledge.createTitle": "Creați cunoștințe",
|
||||
"newKnowledge.creators": "Creatori",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Renunță la schiță",
|
||||
"newKnowledge.discardDraftDescription": "Modificările aduse acestei schițe a bazei de cunoștințe se vor pierde.",
|
||||
"newKnowledge.discardDraftTitle": "Renunțați la această schiță a bazei de cunoștințe?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Configurația sursei și previzualizarea explorării vor fi eliminate.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Schița sursei nu a putut fi eliminată. Încearcă din nou.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Elimini această schiță de sursă?",
|
||||
"newKnowledge.documents": "Documente",
|
||||
"newKnowledge.documentsUnavailable": "— documente",
|
||||
"newKnowledge.emptyDescription": "Adaugă documentele, iar agenții le pot citi direct — fără indexare de configurat.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Conectează o sursă, iar documentele ei rămân sincronizate, indexate automat și gata de utilizare, fără nimic de administrat. Bazele de cunoștințe existente continuă să funcționeze ca înainte.",
|
||||
"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.invalidRootUrl": "Introdu o adresă URL http(s) validă.",
|
||||
"newKnowledge.lastSyncColumn": "Ultima sincronizare",
|
||||
"newKnowledge.learnMore": "Află mai multe",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Ieși din configurare",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Ieșiți din configurarea incompletă?",
|
||||
"newKnowledge.legacy": "Versiune veche",
|
||||
"newKnowledge.loadMore": "Încarcă mai multe",
|
||||
"newKnowledge.maxPages": "Număr maxim de pagini",
|
||||
"newKnowledge.moreProviders": "Vezi mai mult",
|
||||
"newKnowledge.name": "Nume de cunoștințe",
|
||||
"newKnowledge.namePlaceholder": "de ex. Manual de asistență pentru clienți",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Versiune nouă",
|
||||
"newKnowledge.noDescription": "Fără descriere",
|
||||
"newKnowledge.noMatchingSources": "Nicio sursă nu corespunde acestei căutări.",
|
||||
"newKnowledge.noPagesFound": "Nu s-au găsit pagini la {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "Crawlerul a ajuns la site, dar nu a găsit pagini care pot fi indexate. Încearcă altă adresă URL sau extinde opțiunile de explorare.",
|
||||
"newKnowledge.notFoundDescription": "Este posibil ca această bază de cunoștințe să fi fost ștearsă sau este posibil să nu aveți acces.",
|
||||
"newKnowledge.notFoundTitle": "Baza de cunoștințe nu a fost găsită",
|
||||
"newKnowledge.onlineDocuments": "Documente online",
|
||||
"newKnowledge.onlineDrive": "Conducere online",
|
||||
"newKnowledge.pagesAppearDescription": "Explorează site-ul pentru a verifica paginile care vor fi adăugate.",
|
||||
"newKnowledge.pagesAppearTitle": "Paginile vor apărea aici",
|
||||
"newKnowledge.pagesCrawled": "{{count}} pagini explorate la {{host}}",
|
||||
"newKnowledge.permission": "Permisiune",
|
||||
"newKnowledge.permissionAllMembers": "Spațiu de lucru · toți membrii pot vizualiza și edita",
|
||||
"newKnowledge.permissionOnlyMe": "Doar eu",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} nu este configurat",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Adăugați o cheie API sau o adresă URL a punctului final pentru a accesa cu crawlere site-urile web cu {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Acest furnizor nu este disponibil.",
|
||||
"newKnowledge.reCrawl": "Explorează din nou",
|
||||
"newKnowledge.readOnlyEmpty": "Cere unui editor al spațiului de lucru să creeze prima bază de cunoștințe.",
|
||||
"newKnowledge.refreshConnectionStatus": "Starea de reîmprospătare",
|
||||
"newKnowledge.refreshingConnection": "Înviorare…",
|
||||
"newKnowledge.removeSource": "Eliminați sursa",
|
||||
"newKnowledge.retryCrawl": "Reîncearcă explorarea",
|
||||
"newKnowledge.retryProviderLoad": "Reîncercați",
|
||||
"newKnowledge.rootUrl": "URL rădăcină",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Această secțiune va deveni disponibilă în următorul pas de configurare.",
|
||||
"newKnowledge.searchSources": "Căutați surse",
|
||||
"newKnowledge.sourceActions": "Acțiuni pentru {{name}}",
|
||||
"newKnowledge.sourceColumn": "Sursă",
|
||||
"newKnowledge.sourceFilterLabel": "Filtrați sursele după stare",
|
||||
"newKnowledge.sourceName": "Numele sursei",
|
||||
"newKnowledge.sourceNamePlaceholder": "de ex., explorarea documentației produsului",
|
||||
"newKnowledge.sourceNameRequired": "Introdu un nume pentru sursă.",
|
||||
"newKnowledge.sourceStatus.active": "Activ",
|
||||
"newKnowledge.sourceStatus.disabled": "Dezactivat",
|
||||
"newKnowledge.sourceStatus.error": "Eroare",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Începe cu",
|
||||
"newKnowledge.startWithHelp": "Puteți adăuga oricând mai multe surse sau documente.",
|
||||
"newKnowledge.statusColumn": "Stare",
|
||||
"newKnowledge.stopCrawl": "Oprește",
|
||||
"newKnowledge.stoppingCrawl": "Se oprește…",
|
||||
"newKnowledge.syncNow": "Sincronizează acum",
|
||||
"newKnowledge.syncPolicyColumn": "Politica de sincronizare",
|
||||
"newKnowledge.tags": "Etichete",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Actualizat la {{date}}",
|
||||
"newKnowledge.uploadFiles": "Încarcă fișiere",
|
||||
"newKnowledge.uploadFilesDescription": "Adaugă fișiere de pe computer — sunt indexate imediat ce le creezi.",
|
||||
"newKnowledge.usingDefaults": "Se folosesc valorile implicite",
|
||||
"newKnowledge.viewLabel": "Vizualizare cunoștințe",
|
||||
"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",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Действия",
|
||||
"newKnowledge.addSource": "Добавить источник",
|
||||
"newKnowledge.addSourceDescription": "Подключите источник к этой базе знаний — она синхронизируется автоматически и остается актуальной.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Перед добавлением источника выберите хотя бы одну просканированную страницу.",
|
||||
"newKnowledge.adjustAndRecrawl": "Настроить и просканировать снова",
|
||||
"newKnowledge.allSources": "Все источники",
|
||||
"newKnowledge.appsUnavailable": "— приложений",
|
||||
"newKnowledge.authKind.api-key": "API-ключ",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Обновите соединение перед добавлением источника веб-сайта.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} подключается",
|
||||
"newKnowledge.connectionRefreshFailed": "Не удалось обновить это соединение. Попробуйте еще раз.",
|
||||
"newKnowledge.crawlAndPreview": "Сканирование и предварительный просмотр",
|
||||
"newKnowledge.crawlFailed": "Не удалось просканировать {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Сайт вернул ошибку 403 — возможно, он блокирует поисковых роботов или требует авторизации. Проверьте URL, измените параметры сканирования или попробуйте другого провайдера.",
|
||||
"newKnowledge.crawlFailedDescription": "Не удалось завершить предварительное сканирование. Проверьте URL, измените параметры сканирования или повторите попытку.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} сообщил об ошибке. Проверьте подключение к провайдеру и повторите попытку.",
|
||||
"newKnowledge.crawlFailedTimeout": "Истекло время ожидания сканирования. Укажите более точный URL или уменьшите максимальное число страниц.",
|
||||
"newKnowledge.crawlOptions": "Параметры сканирования",
|
||||
"newKnowledge.crawlProgress": "Ход сканирования {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Конфигурация сканирования веб-сайта отключена до тех пор, пока не будет доступен рабочий процесс сканирования.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl готов",
|
||||
"newKnowledge.crawlStartFailed": "Не удалось запустить предварительное сканирование. Повторите попытку.",
|
||||
"newKnowledge.crawlStopped": "Сканирование остановлено",
|
||||
"newKnowledge.crawling": "Сканирование…",
|
||||
"newKnowledge.crawlingPages": "Сканирование {{host}}… найдено страниц: {{count}}",
|
||||
"newKnowledge.createFailed": "Мы не смогли создать эту базу знаний. Проверьте доступ и повторите попытку.",
|
||||
"newKnowledge.createTitle": "Создавайте знания",
|
||||
"newKnowledge.creators": "Создатели",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Удалить черновик",
|
||||
"newKnowledge.discardDraftDescription": "Изменения в этом черновике базы знаний будут потеряны.",
|
||||
"newKnowledge.discardDraftTitle": "Удалить этот черновик базы знаний?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Конфигурация источника и предварительное сканирование будут удалены.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Не удалось удалить черновик источника. Повторите попытку.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Удалить этот черновик источника?",
|
||||
"newKnowledge.documents": "Документы",
|
||||
"newKnowledge.documentsUnavailable": "— документов",
|
||||
"newKnowledge.emptyDescription": "Добавьте документы, и агенты смогут читать их напрямую — без настройки индексации.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Подключите источник, и его документы будут синхронизироваться, автоматически индексироваться и сразу станут готовы к работе — без дополнительной настройки. Ваши прежние базы знаний продолжат работать как раньше.",
|
||||
"newKnowledge.guideTitle": "Познакомьтесь с новой базой знаний ✨",
|
||||
"newKnowledge.illustrationHeadline": "Подключите контент один раз — и каждое приложение будет отвечать на основе самых свежих знаний.",
|
||||
"newKnowledge.includeSubpages": "Включать вложенные страницы",
|
||||
"newKnowledge.invalidRootUrl": "Введите корректный URL с http(s).",
|
||||
"newKnowledge.lastSyncColumn": "Последняя синхронизация",
|
||||
"newKnowledge.learnMore": "Подробнее",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Выйти из настройки",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Выйти из незавершённой настройки?",
|
||||
"newKnowledge.legacy": "Предыдущая версия",
|
||||
"newKnowledge.loadMore": "Загрузить ещё",
|
||||
"newKnowledge.maxPages": "Максимум страниц",
|
||||
"newKnowledge.moreProviders": "Подробнее",
|
||||
"newKnowledge.name": "Название знания",
|
||||
"newKnowledge.namePlaceholder": "например Руководство по поддержке клиентов",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Новая версия",
|
||||
"newKnowledge.noDescription": "Нет описания",
|
||||
"newKnowledge.noMatchingSources": "Ни один источник не соответствует этому запросу.",
|
||||
"newKnowledge.noPagesFound": "На {{host}} не найдено страниц",
|
||||
"newKnowledge.noPagesFoundDescription": "Робот получил доступ к сайту, но не нашёл страниц для индексирования. Попробуйте другой URL или расширьте параметры сканирования.",
|
||||
"newKnowledge.notFoundDescription": "Возможно, эта база знаний была удалена, или у вас нет доступа.",
|
||||
"newKnowledge.notFoundTitle": "База знаний не найдена",
|
||||
"newKnowledge.onlineDocuments": "Онлайн-документы",
|
||||
"newKnowledge.onlineDrive": "Онлайн-диск",
|
||||
"newKnowledge.pagesAppearDescription": "Просканируйте сайт, чтобы проверить, какие страницы будут добавлены.",
|
||||
"newKnowledge.pagesAppearTitle": "Здесь появятся страницы",
|
||||
"newKnowledge.pagesCrawled": "Просканировано страниц на {{host}}: {{count}}",
|
||||
"newKnowledge.permission": "Разрешение",
|
||||
"newKnowledge.permissionAllMembers": "Рабочая область · все участники могут просматривать и редактировать",
|
||||
"newKnowledge.permissionOnlyMe": "Только я",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} не настроено",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Добавьте ключ API или URL-адрес конечной точки для сканирования веб-сайтов с помощью {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Этот провайдер недоступен.",
|
||||
"newKnowledge.reCrawl": "Просканировать снова",
|
||||
"newKnowledge.readOnlyEmpty": "Попросите редактора рабочего пространства создать первую базу знаний.",
|
||||
"newKnowledge.refreshConnectionStatus": "Обновить статус",
|
||||
"newKnowledge.refreshingConnection": "Обновление…",
|
||||
"newKnowledge.removeSource": "Удалить источник",
|
||||
"newKnowledge.retryCrawl": "Повторить сканирование",
|
||||
"newKnowledge.retryProviderLoad": "Повторить попытку",
|
||||
"newKnowledge.rootUrl": "Корневой URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Этот раздел станет доступен на следующем этапе настройки.",
|
||||
"newKnowledge.searchSources": "Поиск источников",
|
||||
"newKnowledge.sourceActions": "Действия для {{name}}",
|
||||
"newKnowledge.sourceColumn": "Источник",
|
||||
"newKnowledge.sourceFilterLabel": "Фильтровать источники по статусу",
|
||||
"newKnowledge.sourceName": "Название источника",
|
||||
"newKnowledge.sourceNamePlaceholder": "например, сканирование документации продукта",
|
||||
"newKnowledge.sourceNameRequired": "Введите название источника.",
|
||||
"newKnowledge.sourceStatus.active": "Активен",
|
||||
"newKnowledge.sourceStatus.disabled": "Отключено",
|
||||
"newKnowledge.sourceStatus.error": "Ошибка",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Начните с",
|
||||
"newKnowledge.startWithHelp": "Вы можете добавить больше источников или документов в любое время.",
|
||||
"newKnowledge.statusColumn": "Статус",
|
||||
"newKnowledge.stopCrawl": "Остановить",
|
||||
"newKnowledge.stoppingCrawl": "Остановка…",
|
||||
"newKnowledge.syncNow": "Синхронизировать сейчас",
|
||||
"newKnowledge.syncPolicyColumn": "Политика синхронизации",
|
||||
"newKnowledge.tags": "Теги",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Обновлено {{date}}",
|
||||
"newKnowledge.uploadFiles": "Загрузить файлы",
|
||||
"newKnowledge.uploadFilesDescription": "Добавьте файлы с компьютера — они будут проиндексированы сразу после создания.",
|
||||
"newKnowledge.usingDefaults": "Используются настройки по умолчанию",
|
||||
"newKnowledge.viewLabel": "Вид базы знаний",
|
||||
"newKnowledge.websiteCrawl": "Сканирование веб-сайта",
|
||||
"noExternalKnowledge": "У нас еще нет External Knowledge API, нажмите здесь, чтобы создать",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Dejanja",
|
||||
"newKnowledge.addSource": "Dodaj vir",
|
||||
"newKnowledge.addSourceDescription": "Povežite vir s to bazo znanja — samodejno se sinhronizira in ostane sveža.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Pred dodajanjem vira izberite vsaj eno preiskano stran.",
|
||||
"newKnowledge.adjustAndRecrawl": "Prilagodi in ponovno preišči",
|
||||
"newKnowledge.allSources": "Vsi viri",
|
||||
"newKnowledge.appsUnavailable": "— aplikacij",
|
||||
"newKnowledge.authKind.api-key": "API ključ",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Osvežite povezavo, preden dodate vir spletnega mesta.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} vzpostavlja povezavo",
|
||||
"newKnowledge.connectionRefreshFailed": "Te povezave nismo mogli osvežiti. Poskusite znova.",
|
||||
"newKnowledge.crawlAndPreview": "Iskanje in predogled",
|
||||
"newKnowledge.crawlFailed": "Spletnega mesta {{host}} ni bilo mogoče preiskati",
|
||||
"newKnowledge.crawlFailed403": "Spletno mesto je vrnilo napako 403 — morda blokira pajke ali zahteva prijavo. Preverite URL, prilagodite možnosti preiskovanja ali poskusite drugega ponudnika.",
|
||||
"newKnowledge.crawlFailedDescription": "Pajek ni mogel dokončati tega predogleda. Preverite URL, prilagodite možnosti preiskovanja ali poskusite znova.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} je sporočil napako. Preverite povezavo s ponudnikom in poskusite znova.",
|
||||
"newKnowledge.crawlFailedTimeout": "Čas za preiskovanje je potekel. Poskusite z natančnejšim URL-jem ali zmanjšajte največje število strani.",
|
||||
"newKnowledge.crawlOptions": "Možnosti preiskovanja",
|
||||
"newKnowledge.crawlProgress": "Napredek preiskovanja za {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Konfiguracija iskanja po vsebini spletnega mesta je onemogočena, dokler potek dela po vsebini ni na voljo.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl je pripravljen",
|
||||
"newKnowledge.crawlStartFailed": "Predogleda preiskovanja ni bilo mogoče zagnati. Poskusite znova.",
|
||||
"newKnowledge.crawlStopped": "Preiskovanje ustavljeno",
|
||||
"newKnowledge.crawling": "Preiskovanje…",
|
||||
"newKnowledge.crawlingPages": "Preiskovanje {{host}}… najdenih strani: {{count}}",
|
||||
"newKnowledge.createFailed": "Te baze znanja nismo mogli ustvariti. Preverite dostop in poskusite znova.",
|
||||
"newKnowledge.createTitle": "Ustvarite znanje",
|
||||
"newKnowledge.creators": "Ustvarjalci",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Zavrzi osnutek",
|
||||
"newKnowledge.discardDraftDescription": "Spremembe tega osnutka zbirke znanja bodo izgubljene.",
|
||||
"newKnowledge.discardDraftTitle": "Želite zavreči ta osnutek zbirke znanja?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Nastavitev vira in predogled preiskovanja bosta odstranjena.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Osnutka vira ni bilo mogoče zavreči. Poskusite znova.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Želite zavreči ta osnutek vira?",
|
||||
"newKnowledge.documents": "Dokumenti",
|
||||
"newKnowledge.documentsUnavailable": "— dokumentov",
|
||||
"newKnowledge.emptyDescription": "Dodajte dokumente in agenti jih lahko berejo neposredno — brez nastavljanja indeksiranja.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Povežite vir in njegovi dokumenti bodo ostali sinhronizirani, samodejno indeksirani in pripravljeni za uporabo brez dodatnega upravljanja. Vaše obstoječe baze znanja bodo še naprej delovale kot doslej.",
|
||||
"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.invalidRootUrl": "Vnesite veljaven URL http(s).",
|
||||
"newKnowledge.lastSyncColumn": "Zadnja sinhronizacija",
|
||||
"newKnowledge.learnMore": "Več informacij",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Zapusti nastavitev",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Želite zapustiti nedokončano nastavitev?",
|
||||
"newKnowledge.legacy": "Staro",
|
||||
"newKnowledge.loadMore": "Naloži več",
|
||||
"newKnowledge.maxPages": "Največje število strani",
|
||||
"newKnowledge.moreProviders": "Oglejte si več",
|
||||
"newKnowledge.name": "Ime znanja",
|
||||
"newKnowledge.namePlaceholder": "npr. Priročnik za podporo strankam",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Novo",
|
||||
"newKnowledge.noDescription": "Brez opisa",
|
||||
"newKnowledge.noMatchingSources": "Noben vir ne ustreza temu iskanju.",
|
||||
"newKnowledge.noPagesFound": "Na {{host}} ni bilo najdenih strani",
|
||||
"newKnowledge.noPagesFoundDescription": "Pajek je dosegel spletno mesto, vendar ni našel strani za indeksiranje. Poskusite drug URL ali razširite možnosti preiskovanja.",
|
||||
"newKnowledge.notFoundDescription": "Ta baza znanja je bila morda izbrisana ali pa nimate dostopa.",
|
||||
"newKnowledge.notFoundTitle": "Baza znanja ni bila najdena",
|
||||
"newKnowledge.onlineDocuments": "Spletni dokumenti",
|
||||
"newKnowledge.onlineDrive": "Spletna vožnja",
|
||||
"newKnowledge.pagesAppearDescription": "Preiščite spletno mesto in preverite, katere strani bodo dodane.",
|
||||
"newKnowledge.pagesAppearTitle": "Strani bodo prikazane tukaj",
|
||||
"newKnowledge.pagesCrawled": "Preiskanih strani na {{host}}: {{count}}",
|
||||
"newKnowledge.permission": "Dovoljenje",
|
||||
"newKnowledge.permissionAllMembers": "Delovni prostor · vsi člani si lahko ogledujejo in urejajo",
|
||||
"newKnowledge.permissionOnlyMe": "Samo jaz",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} ni konfiguriran",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Dodajte ključ API ali URL končne točke za iskanje po spletnih mestih z {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Ta ponudnik ni dosegljiv.",
|
||||
"newKnowledge.reCrawl": "Ponovno preišči",
|
||||
"newKnowledge.readOnlyEmpty": "Prosite urednika delovnega prostora, naj ustvari prvo bazo znanja.",
|
||||
"newKnowledge.refreshConnectionStatus": "Osveži stanje",
|
||||
"newKnowledge.refreshingConnection": "Osvežitev …",
|
||||
"newKnowledge.removeSource": "Odstrani vir",
|
||||
"newKnowledge.retryCrawl": "Ponovi preiskovanje",
|
||||
"newKnowledge.retryProviderLoad": "Poskusi znova",
|
||||
"newKnowledge.rootUrl": "Korenski URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Ta razdelek bo na voljo v naslednjem koraku nastavitve.",
|
||||
"newKnowledge.searchSources": "Iskanje virov",
|
||||
"newKnowledge.sourceActions": "Dejanja za {{name}}",
|
||||
"newKnowledge.sourceColumn": "Vir",
|
||||
"newKnowledge.sourceFilterLabel": "Filtrirajte vire po statusu",
|
||||
"newKnowledge.sourceName": "Ime vira",
|
||||
"newKnowledge.sourceNamePlaceholder": "npr. preiskovanje dokumentacije izdelka",
|
||||
"newKnowledge.sourceNameRequired": "Vnesite ime vira.",
|
||||
"newKnowledge.sourceStatus.active": "Aktivno",
|
||||
"newKnowledge.sourceStatus.disabled": "Onemogočeno",
|
||||
"newKnowledge.sourceStatus.error": "Napaka",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Začni z",
|
||||
"newKnowledge.startWithHelp": "Kadar koli lahko dodate več virov ali dokumentov.",
|
||||
"newKnowledge.statusColumn": "Stanje",
|
||||
"newKnowledge.stopCrawl": "Ustavi",
|
||||
"newKnowledge.stoppingCrawl": "Ustavljanje…",
|
||||
"newKnowledge.syncNow": "Sinhroniziraj zdaj",
|
||||
"newKnowledge.syncPolicyColumn": "Pravilnik o sinhronizaciji",
|
||||
"newKnowledge.tags": "Oznake",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Posodobljeno {{date}}",
|
||||
"newKnowledge.uploadFiles": "Naloži datoteke",
|
||||
"newKnowledge.uploadFilesDescription": "Dodajte datoteke iz računalnika — indeksirajo se takoj ob ustvarjanju.",
|
||||
"newKnowledge.usingDefaults": "Uporabljene so privzete nastavitve",
|
||||
"newKnowledge.viewLabel": "Prikaz znanja",
|
||||
"newKnowledge.websiteCrawl": "Iskanje po vsebini spletne strani",
|
||||
"noExternalKnowledge": "Zunanjega API-ja za znanje še ni, kliknite tukaj za ustvarjanje",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "การดำเนินการ",
|
||||
"newKnowledge.addSource": "เพิ่มแหล่งที่มา",
|
||||
"newKnowledge.addSourceDescription": "เชื่อมต่อแหล่งข้อมูลกับฐานความรู้นี้ โดยจะซิงค์โดยอัตโนมัติและมีความสดใหม่อยู่เสมอ",
|
||||
"newKnowledge.addSourceRequiresSelection": "เลือกหน้าที่รวบรวมข้อมูลแล้วอย่างน้อยหนึ่งหน้าก่อนเพิ่มแหล่งข้อมูล",
|
||||
"newKnowledge.adjustAndRecrawl": "ปรับและรวบรวมข้อมูลอีกครั้ง",
|
||||
"newKnowledge.allSources": "แหล่งที่มาทั้งหมด",
|
||||
"newKnowledge.appsUnavailable": "— แอป",
|
||||
"newKnowledge.authKind.api-key": "คีย์ API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "รีเฟรชการเชื่อมต่อก่อนที่จะเพิ่มแหล่งที่มาของเว็บไซต์",
|
||||
"newKnowledge.connectionProvisioning": "กำลังเชื่อมต่อ {{provider}}",
|
||||
"newKnowledge.connectionRefreshFailed": "เราไม่สามารถรีเฟรชการเชื่อมต่อนี้ได้ ลองอีกครั้ง",
|
||||
"newKnowledge.crawlAndPreview": "รวบรวมข้อมูลและดูตัวอย่าง",
|
||||
"newKnowledge.crawlFailed": "ไม่สามารถรวบรวมข้อมูล {{host}} ได้",
|
||||
"newKnowledge.crawlFailed403": "เว็บไซต์ส่งคืนข้อผิดพลาด 403 ซึ่งอาจบล็อกโปรแกรมรวบรวมข้อมูลหรือต้องมีการยืนยันตัวตน ตรวจสอบ URL ปรับตัวเลือกการรวบรวมข้อมูล หรือลองใช้ผู้ให้บริการรายอื่น",
|
||||
"newKnowledge.crawlFailedDescription": "โปรแกรมรวบรวมข้อมูลไม่สามารถทำตัวอย่างนี้ให้เสร็จได้ ตรวจสอบ URL ปรับตัวเลือกการรวบรวมข้อมูล หรือลองอีกครั้ง",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} รายงานข้อผิดพลาด ตรวจสอบการเชื่อมต่อผู้ให้บริการแล้วลองอีกครั้ง",
|
||||
"newKnowledge.crawlFailedTimeout": "หมดเวลาการรวบรวมข้อมูล ลองใช้ URL ที่เจาะจงขึ้นหรือลดจำนวนหน้าสูงสุด",
|
||||
"newKnowledge.crawlOptions": "ตัวเลือกการรวบรวมข้อมูล",
|
||||
"newKnowledge.crawlProgress": "ความคืบหน้าการรวบรวมข้อมูลของ {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "การกำหนดค่าการรวบรวมข้อมูลเว็บไซต์ถูกปิดใช้งานจนกว่าเวิร์กโฟลว์การรวบรวมข้อมูลจะพร้อมใช้งาน",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl พร้อมแล้ว",
|
||||
"newKnowledge.crawlStartFailed": "ไม่สามารถเริ่มตัวอย่างการรวบรวมข้อมูลได้ ลองอีกครั้ง",
|
||||
"newKnowledge.crawlStopped": "หยุดการรวบรวมข้อมูลแล้ว",
|
||||
"newKnowledge.crawling": "กำลังรวบรวมข้อมูล…",
|
||||
"newKnowledge.crawlingPages": "กำลังรวบรวมข้อมูล {{host}}… พบ {{count}} หน้า",
|
||||
"newKnowledge.createFailed": "เราไม่สามารถสร้างฐานความรู้นี้ได้ ตรวจสอบการเข้าถึงของคุณแล้วลองอีกครั้ง",
|
||||
"newKnowledge.createTitle": "สร้างองค์ความรู้",
|
||||
"newKnowledge.creators": "ผู้สร้าง",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "ละทิ้งฉบับร่าง",
|
||||
"newKnowledge.discardDraftDescription": "การเปลี่ยนแปลงในฉบับร่างฐานความรู้นี้จะสูญหาย",
|
||||
"newKnowledge.discardDraftTitle": "ละทิ้งฉบับร่างฐานความรู้นี้หรือไม่?",
|
||||
"newKnowledge.discardSourceDraftDescription": "การกำหนดค่าแหล่งข้อมูลและตัวอย่างการรวบรวมข้อมูลจะถูกลบ",
|
||||
"newKnowledge.discardSourceDraftFailed": "ไม่สามารถละทิ้งฉบับร่างแหล่งข้อมูลได้ ลองอีกครั้ง",
|
||||
"newKnowledge.discardSourceDraftTitle": "ละทิ้งฉบับร่างแหล่งข้อมูลนี้หรือไม่",
|
||||
"newKnowledge.documents": "เอกสาร",
|
||||
"newKnowledge.documentsUnavailable": "— เอกสาร",
|
||||
"newKnowledge.emptyDescription": "เพิ่มเอกสารของคุณ แล้วเอเจนต์จะอ่านได้โดยตรง โดยไม่ต้องตั้งค่าการทำดัชนี",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "เชื่อมต่อแหล่งข้อมูล แล้วเอกสารจะซิงค์ ทำดัชนีอัตโนมัติ และพร้อมใช้งานโดยไม่ต้องจัดการการตั้งค่า ฐานความรู้เดิมของคุณยังคงทำงานได้ตามปกติ",
|
||||
"newKnowledge.guideTitle": "พบกับฐานความรู้แบบใหม่ ✨",
|
||||
"newKnowledge.illustrationHeadline": "เชื่อมต่อเนื้อหาครั้งเดียว ทุกแอปจะตอบด้วยความรู้ล่าสุด",
|
||||
"newKnowledge.includeSubpages": "รวมหน้าย่อย",
|
||||
"newKnowledge.invalidRootUrl": "ป้อน URL http(s) ที่ถูกต้อง",
|
||||
"newKnowledge.lastSyncColumn": "ซิงค์ครั้งล่าสุด",
|
||||
"newKnowledge.learnMore": "เรียนรู้เพิ่มเติม",
|
||||
"newKnowledge.leavePartialSetupConfirm": "ออกจากการตั้งค่า",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "ออกจากการตั้งค่าที่ยังไม่เสร็จหรือไม่?",
|
||||
"newKnowledge.legacy": "แบบเดิม",
|
||||
"newKnowledge.loadMore": "โหลดเพิ่มเติม",
|
||||
"newKnowledge.maxPages": "จำนวนหน้าสูงสุด",
|
||||
"newKnowledge.moreProviders": "ดูเพิ่มเติม",
|
||||
"newKnowledge.name": "ชื่อความรู้",
|
||||
"newKnowledge.namePlaceholder": "เช่น คู่มือการสนับสนุนลูกค้า",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "แบบใหม่",
|
||||
"newKnowledge.noDescription": "ไม่มีคำอธิบาย",
|
||||
"newKnowledge.noMatchingSources": "ไม่มีแหล่งที่มาที่ตรงกับการค้นหานี้",
|
||||
"newKnowledge.noPagesFound": "ไม่พบหน้าที่ {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "โปรแกรมรวบรวมข้อมูลเข้าถึงเว็บไซต์แล้วแต่ไม่พบหน้าที่สร้างดัชนีได้ ลองใช้ URL อื่นหรือขยายตัวเลือกการรวบรวมข้อมูล",
|
||||
"newKnowledge.notFoundDescription": "ฐานความรู้นี้อาจถูกลบไปแล้วหรือคุณอาจไม่สามารถเข้าถึงได้",
|
||||
"newKnowledge.notFoundTitle": "ไม่พบฐานความรู้",
|
||||
"newKnowledge.onlineDocuments": "เอกสารออนไลน์",
|
||||
"newKnowledge.onlineDrive": "ไดรฟ์ออนไลน์",
|
||||
"newKnowledge.pagesAppearDescription": "รวบรวมข้อมูลเว็บไซต์เพื่อตรวจสอบหน้าที่จะเพิ่ม",
|
||||
"newKnowledge.pagesAppearTitle": "หน้าจะแสดงที่นี่",
|
||||
"newKnowledge.pagesCrawled": "รวบรวมข้อมูล {{count}} หน้าที่ {{host}}",
|
||||
"newKnowledge.permission": "การอนุญาต",
|
||||
"newKnowledge.permissionAllMembers": "พื้นที่ทำงาน · สมาชิกทุกคนสามารถดูและแก้ไขได้",
|
||||
"newKnowledge.permissionOnlyMe": "มีเพียงฉันเท่านั้น",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} ไม่ได้กำหนดค่า",
|
||||
"newKnowledge.providerNotConfiguredDescription": "เพิ่มคีย์ API หรือ URL ปลายทางเพื่อรวบรวมข้อมูลเว็บไซต์ด้วย {{provider}}",
|
||||
"newKnowledge.providerUnavailable": "ผู้ให้บริการนี้ไม่พร้อมใช้งาน",
|
||||
"newKnowledge.reCrawl": "รวบรวมข้อมูลอีกครั้ง",
|
||||
"newKnowledge.readOnlyEmpty": "ขอให้ผู้แก้ไขพื้นที่ทำงานสร้างฐานความรู้แรก",
|
||||
"newKnowledge.refreshConnectionStatus": "รีเฟรชสถานะ",
|
||||
"newKnowledge.refreshingConnection": "สดชื่น...",
|
||||
"newKnowledge.removeSource": "ลบแหล่งสัญญาณ",
|
||||
"newKnowledge.retryCrawl": "ลองรวบรวมข้อมูลอีกครั้ง",
|
||||
"newKnowledge.retryProviderLoad": "ลองอีกครั้ง",
|
||||
"newKnowledge.rootUrl": "URL หลัก",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "ส่วนนี้จะพร้อมใช้งานในขั้นตอนการตั้งค่าถัดไป",
|
||||
"newKnowledge.searchSources": "แหล่งค้นหา",
|
||||
"newKnowledge.sourceActions": "การดำเนินการสำหรับ {{name}}",
|
||||
"newKnowledge.sourceColumn": "ที่มา",
|
||||
"newKnowledge.sourceFilterLabel": "กรองแหล่งที่มาตามสถานะ",
|
||||
"newKnowledge.sourceName": "ชื่อแหล่งข้อมูล",
|
||||
"newKnowledge.sourceNamePlaceholder": "เช่น การรวบรวมข้อมูลเอกสารผลิตภัณฑ์",
|
||||
"newKnowledge.sourceNameRequired": "ป้อนชื่อแหล่งข้อมูล",
|
||||
"newKnowledge.sourceStatus.active": "แอคทีฟ",
|
||||
"newKnowledge.sourceStatus.disabled": "ปิดใช้งาน",
|
||||
"newKnowledge.sourceStatus.error": "เกิดข้อผิดพลาด",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "เริ่มต้นด้วย",
|
||||
"newKnowledge.startWithHelp": "คุณสามารถเพิ่มแหล่งที่มาหรือเอกสารเพิ่มเติมได้ตลอดเวลา",
|
||||
"newKnowledge.statusColumn": "สถานะ",
|
||||
"newKnowledge.stopCrawl": "หยุด",
|
||||
"newKnowledge.stoppingCrawl": "กำลังหยุด…",
|
||||
"newKnowledge.syncNow": "ซิงค์เลย",
|
||||
"newKnowledge.syncPolicyColumn": "นโยบายการซิงค์",
|
||||
"newKnowledge.tags": "แท็ก",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "อัปเดตเมื่อ {{date}}",
|
||||
"newKnowledge.uploadFiles": "อัปโหลดไฟล์",
|
||||
"newKnowledge.uploadFilesDescription": "เพิ่มไฟล์จากคอมพิวเตอร์ ไฟล์จะถูกทำดัชนีทันทีที่สร้าง",
|
||||
"newKnowledge.usingDefaults": "ใช้ค่าเริ่มต้น",
|
||||
"newKnowledge.viewLabel": "มุมมองความรู้",
|
||||
"newKnowledge.websiteCrawl": "การรวบรวมข้อมูลเว็บไซต์",
|
||||
"noExternalKnowledge": "ยังไม่มี External Knowledge API คลิกที่นี่เพื่อสร้าง",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Eylemler",
|
||||
"newKnowledge.addSource": "Kaynak ekle",
|
||||
"newKnowledge.addSourceDescription": "Bir kaynağı bu bilgi tabanına bağlayın; otomatik olarak senkronize edilir ve güncel kalır.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Kaynağı eklemeden önce taranmış en az bir sayfa seçin.",
|
||||
"newKnowledge.adjustAndRecrawl": "Ayarla ve yeniden tara",
|
||||
"newKnowledge.allSources": "Tüm kaynaklar",
|
||||
"newKnowledge.appsUnavailable": "— uygulama",
|
||||
"newKnowledge.authKind.api-key": "API anahtarı",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Bir web sitesi kaynağı eklemeden önce bağlantıyı yenileyin.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} bağlanıyor",
|
||||
"newKnowledge.connectionRefreshFailed": "Bu bağlantıyı yenileyemedik. Tekrar deneyin.",
|
||||
"newKnowledge.crawlAndPreview": "Tara ve önizle",
|
||||
"newKnowledge.crawlFailed": "{{host}} taranamadı",
|
||||
"newKnowledge.crawlFailed403": "Site 403 yanıtı verdi — tarayıcıları engelliyor veya kimlik doğrulaması gerektiriyor olabilir. URL’yi kontrol edin, tarama seçeneklerini ayarlayın ya da başka bir sağlayıcı deneyin.",
|
||||
"newKnowledge.crawlFailedDescription": "Tarayıcı bu önizlemeyi tamamlayamadı. URL’yi kontrol edin, tarama seçeneklerini ayarlayın veya yeniden deneyin.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} bir hata bildirdi. Sağlayıcı bağlantısını kontrol edip yeniden deneyin.",
|
||||
"newKnowledge.crawlFailedTimeout": "Tarama zaman aşımına uğradı. Daha dar kapsamlı bir URL deneyin veya en fazla sayfa sayısını azaltın.",
|
||||
"newKnowledge.crawlOptions": "Tarama seçenekleri",
|
||||
"newKnowledge.crawlProgress": "{{host}} için tarama ilerlemesi",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Web sitesi tarama yapılandırması, tarama iş akışı kullanılabilir olana kadar devre dışı bırakılır.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl hazır",
|
||||
"newKnowledge.crawlStartFailed": "Tarama önizlemesi başlatılamadı. Yeniden deneyin.",
|
||||
"newKnowledge.crawlStopped": "Tarama durduruldu",
|
||||
"newKnowledge.crawling": "Taranıyor…",
|
||||
"newKnowledge.crawlingPages": "{{host}} taranıyor… {{count}} sayfa bulundu",
|
||||
"newKnowledge.createFailed": "Bu bilgi tabanını oluşturamadık. Erişiminizi kontrol edip tekrar deneyin.",
|
||||
"newKnowledge.createTitle": "Bilgi Yaratın",
|
||||
"newKnowledge.creators": "Oluşturanlar",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Taslağı sil",
|
||||
"newKnowledge.discardDraftDescription": "Bu bilgi tabanı taslağındaki değişiklikleriniz kaybolacak.",
|
||||
"newKnowledge.discardDraftTitle": "Bu bilgi tabanı taslağı silinsin mi?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Kaynak yapılandırması ve tarama önizlemesi kaldırılacak.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Kaynak taslağı silinemedi. Yeniden deneyin.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Bu kaynak taslağı silinsin mi?",
|
||||
"newKnowledge.documents": "Belgeler",
|
||||
"newKnowledge.documentsUnavailable": "— belge",
|
||||
"newKnowledge.emptyDescription": "Belgelerinizi ekleyin; ajanlar indeksleme yapılandırmadan belgeleri doğrudan okuyabilsin.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Bir kaynak bağladığınızda belgeleri senkronize kalır, otomatik olarak indekslenir ve yönetilecek bir kurulum olmadan kullanıma hazır olur. Mevcut bilgi tabanlarınız olduğu gibi çalışmaya devam eder.",
|
||||
"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.invalidRootUrl": "Geçerli bir http(s) URL’si girin.",
|
||||
"newKnowledge.lastSyncColumn": "Son senkronizasyon",
|
||||
"newKnowledge.learnMore": "Daha fazla bilgi",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Kurulumdan çık",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Tamamlanmamış kurulumdan çıkılsın mı?",
|
||||
"newKnowledge.legacy": "Eski",
|
||||
"newKnowledge.loadMore": "Daha fazla yükle",
|
||||
"newKnowledge.maxPages": "En fazla sayfa",
|
||||
"newKnowledge.moreProviders": "Daha fazla göster",
|
||||
"newKnowledge.name": "Bilgi adı",
|
||||
"newKnowledge.namePlaceholder": "örneğin Müşteri Desteği El Kitabı",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Yeni",
|
||||
"newKnowledge.noDescription": "Açıklama yok",
|
||||
"newKnowledge.noMatchingSources": "Bu aramayla eşleşen kaynak yok.",
|
||||
"newKnowledge.noPagesFound": "{{host}} adresinde sayfa bulunamadı",
|
||||
"newKnowledge.noPagesFoundDescription": "Tarayıcı siteye ulaştı ancak dizine eklenebilir sayfa bulamadı. Farklı bir URL deneyin veya tarama seçeneklerini genişletin.",
|
||||
"newKnowledge.notFoundDescription": "Bu bilgi tabanı silinmiş olabilir veya erişiminiz olmayabilir.",
|
||||
"newKnowledge.notFoundTitle": "Bilgi tabanı bulunamadı",
|
||||
"newKnowledge.onlineDocuments": "Çevrimiçi belgeler",
|
||||
"newKnowledge.onlineDrive": "Çevrimiçi sürücü",
|
||||
"newKnowledge.pagesAppearDescription": "Hangi sayfaların ekleneceğini görmek için siteyi tarayın.",
|
||||
"newKnowledge.pagesAppearTitle": "Sayfalar burada görünecek",
|
||||
"newKnowledge.pagesCrawled": "{{host}} üzerinde {{count}} sayfa tarandı",
|
||||
"newKnowledge.permission": "İzin",
|
||||
"newKnowledge.permissionAllMembers": "Çalışma alanı · tüm üyeler görüntüleyebilir ve düzenleyebilir",
|
||||
"newKnowledge.permissionOnlyMe": "Sadece ben",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} yapılandırılmadı",
|
||||
"newKnowledge.providerNotConfiguredDescription": "{{provider}} ile web sitelerini taramak için bir API anahtarı veya uç nokta URL'si ekleyin.",
|
||||
"newKnowledge.providerUnavailable": "Bu sağlayıcı kullanılamıyor.",
|
||||
"newKnowledge.reCrawl": "Yeniden tara",
|
||||
"newKnowledge.readOnlyEmpty": "İlk bilgi tabanını oluşturması için bir çalışma alanı editörüne başvurun.",
|
||||
"newKnowledge.refreshConnectionStatus": "Durumu yenile",
|
||||
"newKnowledge.refreshingConnection": "Yenileniyor…",
|
||||
"newKnowledge.removeSource": "Kaynağı kaldır",
|
||||
"newKnowledge.retryCrawl": "Taramayı yeniden dene",
|
||||
"newKnowledge.retryProviderLoad": "Tekrar dene",
|
||||
"newKnowledge.rootUrl": "Kök URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Bu bölüm bir sonraki kurulum adımında kullanılabilir hale gelecektir.",
|
||||
"newKnowledge.searchSources": "Kaynakları ara",
|
||||
"newKnowledge.sourceActions": "{{name}} için eylemler",
|
||||
"newKnowledge.sourceColumn": "Kaynak",
|
||||
"newKnowledge.sourceFilterLabel": "Kaynakları duruma göre filtrele",
|
||||
"newKnowledge.sourceName": "Kaynak adı",
|
||||
"newKnowledge.sourceNamePlaceholder": "ör. ürün belgeleri taraması",
|
||||
"newKnowledge.sourceNameRequired": "Bir kaynak adı girin.",
|
||||
"newKnowledge.sourceStatus.active": "Aktif",
|
||||
"newKnowledge.sourceStatus.disabled": "Devre Dışı",
|
||||
"newKnowledge.sourceStatus.error": "Hata",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Şununla başla:",
|
||||
"newKnowledge.startWithHelp": "İstediğiniz zaman daha fazla Kaynak veya Belge ekleyebilirsiniz.",
|
||||
"newKnowledge.statusColumn": "Durum",
|
||||
"newKnowledge.stopCrawl": "Durdur",
|
||||
"newKnowledge.stoppingCrawl": "Durduruluyor…",
|
||||
"newKnowledge.syncNow": "Şimdi senkronize et",
|
||||
"newKnowledge.syncPolicyColumn": "Senkronizasyon politikası",
|
||||
"newKnowledge.tags": "Etiketler",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "{{date}} tarihinde güncellendi",
|
||||
"newKnowledge.uploadFiles": "Dosya yükle",
|
||||
"newKnowledge.uploadFilesDescription": "Bilgisayarınızdan dosya ekleyin; oluşturduğunuz anda indekslenirler.",
|
||||
"newKnowledge.usingDefaults": "Varsayılanlar kullanılıyor",
|
||||
"newKnowledge.viewLabel": "Bilgi görünümü",
|
||||
"newKnowledge.websiteCrawl": "Web sitesi taraması",
|
||||
"noExternalKnowledge": "Henüz Harici Bilgi API'si yok, oluşturmak için buraya tıklayın",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Дії",
|
||||
"newKnowledge.addSource": "Додати джерело",
|
||||
"newKnowledge.addSourceDescription": "Підключіть джерело до цієї бази знань — вона автоматично синхронізується та залишається актуальною.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Перед додаванням джерела виберіть принаймні одну проскановану сторінку.",
|
||||
"newKnowledge.adjustAndRecrawl": "Налаштувати й просканувати знову",
|
||||
"newKnowledge.allSources": "Усі джерела",
|
||||
"newKnowledge.appsUnavailable": "— застосунків",
|
||||
"newKnowledge.authKind.api-key": "API ключ",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Оновіть з’єднання, перш ніж додавати джерело веб-сайту.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} підключається",
|
||||
"newKnowledge.connectionRefreshFailed": "Нам не вдалося оновити це з’єднання. Спробуйте знову.",
|
||||
"newKnowledge.crawlAndPreview": "Сканування та попередній перегляд",
|
||||
"newKnowledge.crawlFailed": "Не вдалося просканувати {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Сайт повернув помилку 403 — можливо, він блокує пошукових роботів або вимагає автентифікації. Перевірте URL-адресу, змініть параметри сканування або спробуйте іншого постачальника.",
|
||||
"newKnowledge.crawlFailedDescription": "Робот не зміг завершити попередній перегляд. Перевірте URL-адресу, змініть параметри сканування або повторіть спробу.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} повідомив про помилку. Перевірте підключення до постачальника й повторіть спробу.",
|
||||
"newKnowledge.crawlFailedTimeout": "Час очікування сканування минув. Спробуйте точнішу URL-адресу або зменште максимальну кількість сторінок.",
|
||||
"newKnowledge.crawlOptions": "Параметри сканування",
|
||||
"newKnowledge.crawlProgress": "Хід сканування {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Конфігурацію сканування веб-сайту вимкнено, доки робочий процес сканування не стане доступним.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl готовий",
|
||||
"newKnowledge.crawlStartFailed": "Не вдалося запустити попередній перегляд сканування. Повторіть спробу.",
|
||||
"newKnowledge.crawlStopped": "Сканування зупинено",
|
||||
"newKnowledge.crawling": "Сканування…",
|
||||
"newKnowledge.crawlingPages": "Сканування {{host}}… знайдено сторінок: {{count}}",
|
||||
"newKnowledge.createFailed": "Ми не змогли створити цю базу знань. Перевірте свій доступ і повторіть спробу.",
|
||||
"newKnowledge.createTitle": "Створюйте знання",
|
||||
"newKnowledge.creators": "Автори",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Відхилити чернетку",
|
||||
"newKnowledge.discardDraftDescription": "Зміни в цій чернетці бази знань буде втрачено.",
|
||||
"newKnowledge.discardDraftTitle": "Відхилити цю чернетку бази знань?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Конфігурацію джерела й попередній перегляд сканування буде видалено.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Не вдалося відхилити чернетку джерела. Повторіть спробу.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Відхилити цю чернетку джерела?",
|
||||
"newKnowledge.documents": "Документи",
|
||||
"newKnowledge.documentsUnavailable": "— документів",
|
||||
"newKnowledge.emptyDescription": "Додайте документи, і агенти зможуть читати їх безпосередньо — без налаштування індексації.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Підключіть джерело, і його документи залишатимуться синхронізованими, автоматично індексуватимуться та будуть готові до використання без додаткового налаштування. Ваші попередні бази знань працюватимуть як і раніше.",
|
||||
"newKnowledge.guideTitle": "Познайомтеся з новою базою знань ✨",
|
||||
"newKnowledge.illustrationHeadline": "Підключіть вміст один раз — і кожна програма відповідатиме на основі найсвіжіших знань.",
|
||||
"newKnowledge.includeSubpages": "Включати підсторінки",
|
||||
"newKnowledge.invalidRootUrl": "Введіть дійсну URL-адресу http(s).",
|
||||
"newKnowledge.lastSyncColumn": "Остання синхронізація",
|
||||
"newKnowledge.learnMore": "Докладніше",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Вийти з налаштування",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Вийти з незавершеного налаштування?",
|
||||
"newKnowledge.legacy": "Попередня версія",
|
||||
"newKnowledge.loadMore": "Завантажити ще",
|
||||
"newKnowledge.maxPages": "Максимум сторінок",
|
||||
"newKnowledge.moreProviders": "Дивитись більше",
|
||||
"newKnowledge.name": "Назва знання",
|
||||
"newKnowledge.namePlaceholder": "напр. Посібник із підтримки клієнтів",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Нова версія",
|
||||
"newKnowledge.noDescription": "Немає опису",
|
||||
"newKnowledge.noMatchingSources": "Жодне джерело не відповідає цьому запиту.",
|
||||
"newKnowledge.noPagesFound": "На {{host}} не знайдено сторінок",
|
||||
"newKnowledge.noPagesFoundDescription": "Робот отримав доступ до сайту, але не знайшов сторінок для індексування. Спробуйте іншу URL-адресу або розширте параметри сканування.",
|
||||
"newKnowledge.notFoundDescription": "Можливо, цю базу знань було видалено або ви не маєте доступу.",
|
||||
"newKnowledge.notFoundTitle": "База знань не знайдена",
|
||||
"newKnowledge.onlineDocuments": "Документи онлайн",
|
||||
"newKnowledge.onlineDrive": "Онлайн драйв",
|
||||
"newKnowledge.pagesAppearDescription": "Проскануйте сайт, щоб переглянути сторінки, які буде додано.",
|
||||
"newKnowledge.pagesAppearTitle": "Тут з’являться сторінки",
|
||||
"newKnowledge.pagesCrawled": "Проскановано сторінок на {{host}}: {{count}}",
|
||||
"newKnowledge.permission": "Дозвіл",
|
||||
"newKnowledge.permissionAllMembers": "Робоча область · усі учасники можуть переглядати та редагувати",
|
||||
"newKnowledge.permissionOnlyMe": "Тільки я",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} не налаштовано",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Додайте ключ API або URL-адресу кінцевої точки, щоб сканувати веб-сайти за допомогою {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Цей провайдер недоступний.",
|
||||
"newKnowledge.reCrawl": "Просканувати знову",
|
||||
"newKnowledge.readOnlyEmpty": "Попросіть редактора робочого простору створити першу базу знань.",
|
||||
"newKnowledge.refreshConnectionStatus": "Оновити статус",
|
||||
"newKnowledge.refreshingConnection": "Оновлення…",
|
||||
"newKnowledge.removeSource": "Видалити джерело",
|
||||
"newKnowledge.retryCrawl": "Повторити сканування",
|
||||
"newKnowledge.retryProviderLoad": "Спробуйте ще раз",
|
||||
"newKnowledge.rootUrl": "Коренева URL-адреса",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Цей розділ стане доступним на наступному кроці налаштування.",
|
||||
"newKnowledge.searchSources": "Пошук джерел",
|
||||
"newKnowledge.sourceActions": "Дії для {{name}}",
|
||||
"newKnowledge.sourceColumn": "Джерело",
|
||||
"newKnowledge.sourceFilterLabel": "Фільтрувати джерела за статусом",
|
||||
"newKnowledge.sourceName": "Назва джерела",
|
||||
"newKnowledge.sourceNamePlaceholder": "наприклад, сканування документації продукту",
|
||||
"newKnowledge.sourceNameRequired": "Введіть назву джерела.",
|
||||
"newKnowledge.sourceStatus.active": "Активний",
|
||||
"newKnowledge.sourceStatus.disabled": "Вимкнено",
|
||||
"newKnowledge.sourceStatus.error": "Помилка",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Почніть з",
|
||||
"newKnowledge.startWithHelp": "Ви можете будь-коли додати більше джерел або документів.",
|
||||
"newKnowledge.statusColumn": "Статус",
|
||||
"newKnowledge.stopCrawl": "Зупинити",
|
||||
"newKnowledge.stoppingCrawl": "Зупинення…",
|
||||
"newKnowledge.syncNow": "Синхронізувати зараз",
|
||||
"newKnowledge.syncPolicyColumn": "Політика синхронізації",
|
||||
"newKnowledge.tags": "Теги",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Оновлено {{date}}",
|
||||
"newKnowledge.uploadFiles": "Завантажити файли",
|
||||
"newKnowledge.uploadFilesDescription": "Додайте файли з комп’ютера — вони індексуються одразу після створення.",
|
||||
"newKnowledge.usingDefaults": "Використовуються стандартні налаштування",
|
||||
"newKnowledge.viewLabel": "Вигляд бази знань",
|
||||
"newKnowledge.websiteCrawl": "Сканування веб-сайту",
|
||||
"noExternalKnowledge": "API зовнішніх знань поки що не існує, натисніть тут, щоб створити",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "Hành động",
|
||||
"newKnowledge.addSource": "Thêm nguồn",
|
||||
"newKnowledge.addSourceDescription": "Kết nối nguồn với cơ sở kiến thức này — nguồn này tự động đồng bộ hóa và luôn cập nhật.",
|
||||
"newKnowledge.addSourceRequiresSelection": "Chọn ít nhất một trang đã thu thập trước khi thêm nguồn.",
|
||||
"newKnowledge.adjustAndRecrawl": "Điều chỉnh và thu thập lại",
|
||||
"newKnowledge.allSources": "Tất cả các nguồn",
|
||||
"newKnowledge.appsUnavailable": "— ứng dụng",
|
||||
"newKnowledge.authKind.api-key": "Khóa API",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "Làm mới kết nối trước khi thêm nguồn trang web.",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} đang kết nối",
|
||||
"newKnowledge.connectionRefreshFailed": "Chúng tôi không thể làm mới kết nối này. Hãy thử lại.",
|
||||
"newKnowledge.crawlAndPreview": "Thu thập thông tin và xem trước",
|
||||
"newKnowledge.crawlFailed": "Không thể thu thập dữ liệu từ {{host}}",
|
||||
"newKnowledge.crawlFailed403": "Trang web trả về lỗi 403 — có thể trang đang chặn trình thu thập hoặc yêu cầu xác thực. Kiểm tra URL, điều chỉnh tùy chọn thu thập hoặc thử nhà cung cấp khác.",
|
||||
"newKnowledge.crawlFailedDescription": "Trình thu thập không thể hoàn tất bản xem trước này. Kiểm tra URL, điều chỉnh tùy chọn thu thập hoặc thử lại.",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} đã báo lỗi. Kiểm tra kết nối nhà cung cấp rồi thử lại.",
|
||||
"newKnowledge.crawlFailedTimeout": "Quá thời gian thu thập. Hãy thử URL cụ thể hơn hoặc giảm số trang tối đa.",
|
||||
"newKnowledge.crawlOptions": "Tùy chọn thu thập",
|
||||
"newKnowledge.crawlProgress": "Tiến trình thu thập của {{host}}",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "Cấu hình thu thập thông tin trang web bị tắt cho đến khi có quy trình thu thập thông tin.",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl đã sẵn sàng",
|
||||
"newKnowledge.crawlStartFailed": "Không thể bắt đầu bản xem trước thu thập. Hãy thử lại.",
|
||||
"newKnowledge.crawlStopped": "Đã dừng thu thập",
|
||||
"newKnowledge.crawling": "Đang thu thập…",
|
||||
"newKnowledge.crawlingPages": "Đang thu thập {{host}}… đã tìm thấy {{count}} trang",
|
||||
"newKnowledge.createFailed": "Chúng tôi không thể tạo ra nền tảng kiến thức này. Hãy kiểm tra quyền truy cập của bạn và thử lại.",
|
||||
"newKnowledge.createTitle": "Tạo kiến thức",
|
||||
"newKnowledge.creators": "Người tạo",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "Hủy bản nháp",
|
||||
"newKnowledge.discardDraftDescription": "Các thay đổi đối với bản nháp cơ sở kiến thức này sẽ bị mất.",
|
||||
"newKnowledge.discardDraftTitle": "Hủy bản nháp cơ sở kiến thức này?",
|
||||
"newKnowledge.discardSourceDraftDescription": "Cấu hình nguồn và bản xem trước thu thập sẽ bị xóa.",
|
||||
"newKnowledge.discardSourceDraftFailed": "Không thể hủy bản nháp nguồn. Hãy thử lại.",
|
||||
"newKnowledge.discardSourceDraftTitle": "Hủy bản nháp nguồn này?",
|
||||
"newKnowledge.documents": "Tài liệu",
|
||||
"newKnowledge.documentsUnavailable": "— tài liệu",
|
||||
"newKnowledge.emptyDescription": "Thêm tài liệu để tác nhân có thể đọc trực tiếp — không cần cấu hình lập chỉ mục.",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "Kết nối một nguồn và tài liệu của nguồn đó sẽ luôn được đồng bộ, tự động lập chỉ mục và sẵn sàng sử dụng mà không cần quản lý thiết lập. Các cơ sở kiến thức cũ vẫn hoạt động như trước.",
|
||||
"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.invalidRootUrl": "Nhập URL http(s) hợp lệ.",
|
||||
"newKnowledge.lastSyncColumn": "Đồng bộ hóa lần cuối",
|
||||
"newKnowledge.learnMore": "Tìm hiểu thêm",
|
||||
"newKnowledge.leavePartialSetupConfirm": "Thoát thiết lập",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "Thoát khỏi thiết lập chưa hoàn tất?",
|
||||
"newKnowledge.legacy": "Cũ",
|
||||
"newKnowledge.loadMore": "Tải thêm",
|
||||
"newKnowledge.maxPages": "Số trang tối đa",
|
||||
"newKnowledge.moreProviders": "Xem thêm",
|
||||
"newKnowledge.name": "Tên kiến thức",
|
||||
"newKnowledge.namePlaceholder": "ví dụ: Sổ tay hỗ trợ khách hàng",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "Mới",
|
||||
"newKnowledge.noDescription": "Không có mô tả",
|
||||
"newKnowledge.noMatchingSources": "Không có nguồn nào phù hợp với tìm kiếm này.",
|
||||
"newKnowledge.noPagesFound": "Không tìm thấy trang nào tại {{host}}",
|
||||
"newKnowledge.noPagesFoundDescription": "Trình thu thập đã truy cập trang web nhưng không tìm thấy trang nào có thể lập chỉ mục. Hãy thử URL khác hoặc mở rộng tùy chọn thu thập.",
|
||||
"newKnowledge.notFoundDescription": "Cơ sở kiến thức này có thể đã bị xóa hoặc bạn không có quyền truy cập.",
|
||||
"newKnowledge.notFoundTitle": "Không tìm thấy cơ sở kiến thức",
|
||||
"newKnowledge.onlineDocuments": "Tài liệu trực tuyến",
|
||||
"newKnowledge.onlineDrive": "Ổ đĩa trực tuyến",
|
||||
"newKnowledge.pagesAppearDescription": "Thu thập trang web để xem những trang nào sẽ được thêm.",
|
||||
"newKnowledge.pagesAppearTitle": "Các trang sẽ xuất hiện ở đây",
|
||||
"newKnowledge.pagesCrawled": "Đã thu thập {{count}} trang tại {{host}}",
|
||||
"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",
|
||||
"newKnowledge.permissionOnlyMe": "Chỉ có tôi",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} chưa được định cấu hình",
|
||||
"newKnowledge.providerNotConfiguredDescription": "Thêm khóa API hoặc URL điểm cuối để thu thập dữ liệu trang web bằng {{provider}}.",
|
||||
"newKnowledge.providerUnavailable": "Nhà cung cấp này không có sẵn.",
|
||||
"newKnowledge.reCrawl": "Thu thập lại",
|
||||
"newKnowledge.readOnlyEmpty": "Yêu cầu biên tập viên không gian làm việc tạo cơ sở kiến thức đầu tiên.",
|
||||
"newKnowledge.refreshConnectionStatus": "Trạng thái làm mới",
|
||||
"newKnowledge.refreshingConnection": "Đang làm mới…",
|
||||
"newKnowledge.removeSource": "Xóa nguồn",
|
||||
"newKnowledge.retryCrawl": "Thử thu thập lại",
|
||||
"newKnowledge.retryProviderLoad": "Thử lại",
|
||||
"newKnowledge.rootUrl": "URL gốc",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "Phần này sẽ có sẵn trong bước thiết lập tiếp theo.",
|
||||
"newKnowledge.searchSources": "Nguồn tìm kiếm",
|
||||
"newKnowledge.sourceActions": "Hành động dành cho {{name}}",
|
||||
"newKnowledge.sourceColumn": "Nguồn",
|
||||
"newKnowledge.sourceFilterLabel": "Lọc nguồn theo trạng thái",
|
||||
"newKnowledge.sourceName": "Tên nguồn",
|
||||
"newKnowledge.sourceNamePlaceholder": "ví dụ: thu thập tài liệu sản phẩm",
|
||||
"newKnowledge.sourceNameRequired": "Nhập tên nguồn.",
|
||||
"newKnowledge.sourceStatus.active": "Đang hoạt động",
|
||||
"newKnowledge.sourceStatus.disabled": "Đã tắt",
|
||||
"newKnowledge.sourceStatus.error": "Lỗi",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "Bắt đầu với",
|
||||
"newKnowledge.startWithHelp": "Bạn có thể thêm nhiều Nguồn hoặc Tài liệu hơn bất cứ lúc nào.",
|
||||
"newKnowledge.statusColumn": "Trạng thái",
|
||||
"newKnowledge.stopCrawl": "Dừng",
|
||||
"newKnowledge.stoppingCrawl": "Đang dừng…",
|
||||
"newKnowledge.syncNow": "Đồng bộ hóa ngay",
|
||||
"newKnowledge.syncPolicyColumn": "Chính sách đồng bộ hóa",
|
||||
"newKnowledge.tags": "Thẻ",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "Cập nhật {{date}}",
|
||||
"newKnowledge.uploadFiles": "Tải tệp lên",
|
||||
"newKnowledge.uploadFilesDescription": "Thêm tệp từ máy tính — tệp sẽ được lập chỉ mục ngay khi tạo.",
|
||||
"newKnowledge.usingDefaults": "Đang dùng giá trị mặc định",
|
||||
"newKnowledge.viewLabel": "Chế độ xem kiến thức",
|
||||
"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",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "行动",
|
||||
"newKnowledge.addSource": "添加来源",
|
||||
"newKnowledge.addSourceDescription": "将来源连接到该知识库 - 它会自动同步并保持最新。",
|
||||
"newKnowledge.addSourceRequiresSelection": "添加来源前,请至少选择一个已抓取的页面。",
|
||||
"newKnowledge.adjustAndRecrawl": "调整并重新抓取",
|
||||
"newKnowledge.allSources": "所有来源",
|
||||
"newKnowledge.appsUnavailable": "— 个应用",
|
||||
"newKnowledge.authKind.api-key": "API 密钥",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "添加网站源之前刷新连接。",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} 正在连接",
|
||||
"newKnowledge.connectionRefreshFailed": "我们无法刷新此连接。再试一次。",
|
||||
"newKnowledge.crawlAndPreview": "抓取和预览",
|
||||
"newKnowledge.crawlFailed": "无法抓取 {{host}}",
|
||||
"newKnowledge.crawlFailed403": "网站返回了 403,可能阻止抓取工具访问或需要身份验证。请检查 URL、调整抓取选项,或尝试其他提供商。",
|
||||
"newKnowledge.crawlFailedDescription": "抓取工具无法完成此预览。请检查 URL、调整抓取选项,或重试。",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} 报告了错误。请检查提供商连接并重试。",
|
||||
"newKnowledge.crawlFailedTimeout": "抓取超时。请尝试范围更小的 URL,或减少最大页面数。",
|
||||
"newKnowledge.crawlOptions": "抓取选项",
|
||||
"newKnowledge.crawlProgress": "{{host}} 的抓取进度",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "在爬网工作流程可用之前,网站爬网配置将被禁用。",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl 已准备就绪",
|
||||
"newKnowledge.crawlStartFailed": "无法启动抓取预览。请重试。",
|
||||
"newKnowledge.crawlStopped": "抓取已停止",
|
||||
"newKnowledge.crawling": "正在抓取…",
|
||||
"newKnowledge.crawlingPages": "正在抓取 {{host}}… 已找到 {{count}} 个页面",
|
||||
"newKnowledge.createFailed": "无法创建此知识库,请检查权限后重试。",
|
||||
"newKnowledge.createTitle": "创建知识库",
|
||||
"newKnowledge.creators": "创建者",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "放弃草稿",
|
||||
"newKnowledge.discardDraftDescription": "对此知识库草稿的更改将会丢失。",
|
||||
"newKnowledge.discardDraftTitle": "放弃此知识库草稿?",
|
||||
"newKnowledge.discardSourceDraftDescription": "来源配置和抓取预览将被移除。",
|
||||
"newKnowledge.discardSourceDraftFailed": "无法放弃来源草稿。请重试。",
|
||||
"newKnowledge.discardSourceDraftTitle": "放弃此来源草稿?",
|
||||
"newKnowledge.documents": "文档",
|
||||
"newKnowledge.documentsUnavailable": "— 篇文档",
|
||||
"newKnowledge.emptyDescription": "添加文档后,智能体即可直接读取,无需配置索引。",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "连接数据源后,其文档会保持同步、自动建立索引并可立即使用,无需管理任何配置。旧版知识库仍会照常运行。",
|
||||
"newKnowledge.guideTitle": "认识全新的知识库 ✨",
|
||||
"newKnowledge.illustrationHeadline": "只需连接一次内容,每个应用都能基于最新知识回答。",
|
||||
"newKnowledge.includeSubpages": "包含子页面",
|
||||
"newKnowledge.invalidRootUrl": "请输入有效的 http(s) URL。",
|
||||
"newKnowledge.lastSyncColumn": "上次同步",
|
||||
"newKnowledge.learnMore": "了解更多",
|
||||
"newKnowledge.leavePartialSetupConfirm": "离开设置",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "离开未完成的设置?",
|
||||
"newKnowledge.legacy": "旧版",
|
||||
"newKnowledge.loadMore": "加载更多",
|
||||
"newKnowledge.maxPages": "最大页面数",
|
||||
"newKnowledge.moreProviders": "更多提供商",
|
||||
"newKnowledge.name": "知识库名称",
|
||||
"newKnowledge.namePlaceholder": "例如:客户支持手册",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "新版",
|
||||
"newKnowledge.noDescription": "暂无描述",
|
||||
"newKnowledge.noMatchingSources": "没有与此搜索匹配的来源。",
|
||||
"newKnowledge.noPagesFound": "在 {{host}} 未找到页面",
|
||||
"newKnowledge.noPagesFoundDescription": "抓取工具已访问网站,但未找到可建立索引的页面。请尝试其他 URL,或扩大抓取范围。",
|
||||
"newKnowledge.notFoundDescription": "此知识库可能已被删除,或你没有访问权限。",
|
||||
"newKnowledge.notFoundTitle": "未找到知识库",
|
||||
"newKnowledge.onlineDocuments": "在线文档",
|
||||
"newKnowledge.onlineDrive": "在线驱动器",
|
||||
"newKnowledge.pagesAppearDescription": "抓取网站以查看将添加哪些页面。",
|
||||
"newKnowledge.pagesAppearTitle": "页面将显示在此处",
|
||||
"newKnowledge.pagesCrawled": "已抓取 {{host}} 的 {{count}} 个页面",
|
||||
"newKnowledge.permission": "权限",
|
||||
"newKnowledge.permissionAllMembers": "工作区 · 所有成员均可查看和编辑",
|
||||
"newKnowledge.permissionOnlyMe": "仅自己",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} 未配置",
|
||||
"newKnowledge.providerNotConfiguredDescription": "添加 API 密钥或端点 URL 以使用 {{provider}} 抓取网站。",
|
||||
"newKnowledge.providerUnavailable": "该提供商不可用。",
|
||||
"newKnowledge.reCrawl": "重新抓取",
|
||||
"newKnowledge.readOnlyEmpty": "请联系工作区编辑者创建第一个知识库。",
|
||||
"newKnowledge.refreshConnectionStatus": "刷新状态",
|
||||
"newKnowledge.refreshingConnection": "正在刷新……",
|
||||
"newKnowledge.removeSource": "删除来源",
|
||||
"newKnowledge.retryCrawl": "重试抓取",
|
||||
"newKnowledge.retryProviderLoad": "重试",
|
||||
"newKnowledge.rootUrl": "根 URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "此部分将在下一设置步骤中开放。",
|
||||
"newKnowledge.searchSources": "搜索来源",
|
||||
"newKnowledge.sourceActions": "{{name}} 的操作",
|
||||
"newKnowledge.sourceColumn": "来源",
|
||||
"newKnowledge.sourceFilterLabel": "按状态过滤源",
|
||||
"newKnowledge.sourceName": "来源名称",
|
||||
"newKnowledge.sourceNamePlaceholder": "例如:产品文档抓取",
|
||||
"newKnowledge.sourceNameRequired": "请输入来源名称。",
|
||||
"newKnowledge.sourceStatus.active": "活跃",
|
||||
"newKnowledge.sourceStatus.disabled": "已禁用",
|
||||
"newKnowledge.sourceStatus.error": "错误",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "创建方式",
|
||||
"newKnowledge.startWithHelp": "你可以随时添加更多数据源或文档。",
|
||||
"newKnowledge.statusColumn": "状态",
|
||||
"newKnowledge.stopCrawl": "停止",
|
||||
"newKnowledge.stoppingCrawl": "正在停止…",
|
||||
"newKnowledge.syncNow": "立即同步",
|
||||
"newKnowledge.syncPolicyColumn": "同步策略",
|
||||
"newKnowledge.tags": "标签",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "更新于 {{date}}",
|
||||
"newKnowledge.uploadFiles": "上传文件",
|
||||
"newKnowledge.uploadFilesDescription": "从电脑添加文件,创建后会立即建立索引。",
|
||||
"newKnowledge.usingDefaults": "使用默认设置",
|
||||
"newKnowledge.viewLabel": "知识库视图",
|
||||
"newKnowledge.websiteCrawl": "网站抓取",
|
||||
"noExternalKnowledge": "还没有外部知识库 API,点击此处创建",
|
||||
|
||||
@ -134,6 +134,8 @@
|
||||
"newKnowledge.actionsColumn": "行動",
|
||||
"newKnowledge.addSource": "新增來源",
|
||||
"newKnowledge.addSourceDescription": "將來源連接到該知識庫 - 它會自動同步並保持最新。",
|
||||
"newKnowledge.addSourceRequiresSelection": "新增來源前,請至少選取一個已抓取的頁面。",
|
||||
"newKnowledge.adjustAndRecrawl": "調整並重新抓取",
|
||||
"newKnowledge.allSources": "所有來源",
|
||||
"newKnowledge.appsUnavailable": "— 個應用程式",
|
||||
"newKnowledge.authKind.api-key": "API 金鑰",
|
||||
@ -154,7 +156,20 @@
|
||||
"newKnowledge.connectionNeedsAttentionDescription": "新增網站來源之前刷新連線。",
|
||||
"newKnowledge.connectionProvisioning": "{{provider}} 正在連接",
|
||||
"newKnowledge.connectionRefreshFailed": "我們無法刷新此連線。再試一次。",
|
||||
"newKnowledge.crawlAndPreview": "抓取與預覽",
|
||||
"newKnowledge.crawlFailed": "無法抓取 {{host}}",
|
||||
"newKnowledge.crawlFailed403": "網站傳回了 403,可能阻擋抓取工具或需要驗證。請檢查 URL、調整抓取選項,或嘗試其他供應商。",
|
||||
"newKnowledge.crawlFailedDescription": "抓取工具無法完成此預覽。請檢查 URL、調整抓取選項,或重試。",
|
||||
"newKnowledge.crawlFailedProvider": "{{provider}} 回報錯誤。請檢查供應商連線並重試。",
|
||||
"newKnowledge.crawlFailedTimeout": "抓取逾時。請嘗試範圍較小的 URL,或減少頁面數上限。",
|
||||
"newKnowledge.crawlOptions": "抓取選項",
|
||||
"newKnowledge.crawlProgress": "{{host}} 的抓取進度",
|
||||
"newKnowledge.crawlSetupUnavailableDescription": "在爬網工作流程可用之前,網站爬網設定將會被停用。",
|
||||
"newKnowledge.crawlSetupUnavailableTitle": "Firecrawl 已準備就緒",
|
||||
"newKnowledge.crawlStartFailed": "無法啟動抓取預覽。請重試。",
|
||||
"newKnowledge.crawlStopped": "抓取已停止",
|
||||
"newKnowledge.crawling": "正在抓取…",
|
||||
"newKnowledge.crawlingPages": "正在抓取 {{host}}… 已找到 {{count}} 個頁面",
|
||||
"newKnowledge.createFailed": "無法建立此知識庫,請檢查權限後再試一次。",
|
||||
"newKnowledge.createTitle": "建立知識庫",
|
||||
"newKnowledge.creators": "建立者",
|
||||
@ -167,6 +182,9 @@
|
||||
"newKnowledge.discardDraftConfirm": "放棄草稿",
|
||||
"newKnowledge.discardDraftDescription": "對此知識庫草稿的變更將會遺失。",
|
||||
"newKnowledge.discardDraftTitle": "放棄此知識庫草稿?",
|
||||
"newKnowledge.discardSourceDraftDescription": "來源設定和抓取預覽將被移除。",
|
||||
"newKnowledge.discardSourceDraftFailed": "無法捨棄來源草稿。請重試。",
|
||||
"newKnowledge.discardSourceDraftTitle": "捨棄此來源草稿?",
|
||||
"newKnowledge.documents": "文件",
|
||||
"newKnowledge.documentsUnavailable": "— 份文件",
|
||||
"newKnowledge.emptyDescription": "加入文件後,智慧代理即可直接讀取,無需設定索引。",
|
||||
@ -178,6 +196,8 @@
|
||||
"newKnowledge.guideDescription": "連接資料來源後,其文件會保持同步、自動建立索引並可立即使用,無需管理任何設定。舊版知識庫仍會照常運作。",
|
||||
"newKnowledge.guideTitle": "認識全新的知識庫 ✨",
|
||||
"newKnowledge.illustrationHeadline": "只需連接一次內容,每個應用程式都能以最新知識回答。",
|
||||
"newKnowledge.includeSubpages": "包含子頁面",
|
||||
"newKnowledge.invalidRootUrl": "請輸入有效的 http(s) URL。",
|
||||
"newKnowledge.lastSyncColumn": "上次同步",
|
||||
"newKnowledge.learnMore": "瞭解更多",
|
||||
"newKnowledge.leavePartialSetupConfirm": "離開設定",
|
||||
@ -185,6 +205,7 @@
|
||||
"newKnowledge.leavePartialSetupTitle": "離開未完成的設定?",
|
||||
"newKnowledge.legacy": "舊版",
|
||||
"newKnowledge.loadMore": "載入更多",
|
||||
"newKnowledge.maxPages": "頁面數上限",
|
||||
"newKnowledge.moreProviders": "更多供應商",
|
||||
"newKnowledge.name": "知識庫名稱",
|
||||
"newKnowledge.namePlaceholder": "例如:客戶支援手冊",
|
||||
@ -192,10 +213,15 @@
|
||||
"newKnowledge.new": "新版",
|
||||
"newKnowledge.noDescription": "暫無描述",
|
||||
"newKnowledge.noMatchingSources": "沒有與此搜尋相符的來源。",
|
||||
"newKnowledge.noPagesFound": "在 {{host}} 找不到頁面",
|
||||
"newKnowledge.noPagesFoundDescription": "抓取工具已連線至網站,但找不到可建立索引的頁面。請嘗試其他 URL,或擴大抓取範圍。",
|
||||
"newKnowledge.notFoundDescription": "此知識庫可能已被刪除,或你沒有存取權限。",
|
||||
"newKnowledge.notFoundTitle": "找不到知識庫",
|
||||
"newKnowledge.onlineDocuments": "線上文檔",
|
||||
"newKnowledge.onlineDrive": "線上驅動器",
|
||||
"newKnowledge.pagesAppearDescription": "抓取網站以查看將新增哪些頁面。",
|
||||
"newKnowledge.pagesAppearTitle": "頁面將顯示在此處",
|
||||
"newKnowledge.pagesCrawled": "已抓取 {{host}} 的 {{count}} 個頁面",
|
||||
"newKnowledge.permission": "權限",
|
||||
"newKnowledge.permissionAllMembers": "工作區 · 所有成員皆可檢視和編輯",
|
||||
"newKnowledge.permissionOnlyMe": "僅自己",
|
||||
@ -207,16 +233,23 @@
|
||||
"newKnowledge.providerNotConfigured": "{{provider}} 未配置",
|
||||
"newKnowledge.providerNotConfiguredDescription": "新增 API 金鑰或端點 URL 以使用 {{provider}} 抓取網站。",
|
||||
"newKnowledge.providerUnavailable": "該提供者不可用。",
|
||||
"newKnowledge.reCrawl": "重新抓取",
|
||||
"newKnowledge.readOnlyEmpty": "請聯絡工作區編輯者建立第一個知識庫。",
|
||||
"newKnowledge.refreshConnectionStatus": "刷新狀態",
|
||||
"newKnowledge.refreshingConnection": "正在重新整理…",
|
||||
"newKnowledge.removeSource": "刪除來源",
|
||||
"newKnowledge.retryCrawl": "重試抓取",
|
||||
"newKnowledge.retryProviderLoad": "重試",
|
||||
"newKnowledge.rootUrl": "根 URL",
|
||||
"newKnowledge.rootUrlPlaceholder": "https://docs.example.com",
|
||||
"newKnowledge.routeUnavailable": "此區段將在下一個設定步驟中開放。",
|
||||
"newKnowledge.searchSources": "搜尋來源",
|
||||
"newKnowledge.sourceActions": "{{name}} 的操作",
|
||||
"newKnowledge.sourceColumn": "來源",
|
||||
"newKnowledge.sourceFilterLabel": "按狀態過濾來源",
|
||||
"newKnowledge.sourceName": "來源名稱",
|
||||
"newKnowledge.sourceNamePlaceholder": "例如:產品文件抓取",
|
||||
"newKnowledge.sourceNameRequired": "請輸入來源名稱。",
|
||||
"newKnowledge.sourceStatus.active": "活躍",
|
||||
"newKnowledge.sourceStatus.disabled": "已停用",
|
||||
"newKnowledge.sourceStatus.error": "錯誤",
|
||||
@ -238,6 +271,8 @@
|
||||
"newKnowledge.startWith": "建立方式",
|
||||
"newKnowledge.startWithHelp": "你可以隨時新增更多資料來源或文件。",
|
||||
"newKnowledge.statusColumn": "狀態",
|
||||
"newKnowledge.stopCrawl": "停止",
|
||||
"newKnowledge.stoppingCrawl": "正在停止…",
|
||||
"newKnowledge.syncNow": "立即同步",
|
||||
"newKnowledge.syncPolicyColumn": "同步策略",
|
||||
"newKnowledge.tags": "標籤",
|
||||
@ -246,6 +281,7 @@
|
||||
"newKnowledge.updated": "更新於 {{date}}",
|
||||
"newKnowledge.uploadFiles": "上傳檔案",
|
||||
"newKnowledge.uploadFilesDescription": "從電腦加入檔案,建立後會立即建立索引。",
|
||||
"newKnowledge.usingDefaults": "使用預設設定",
|
||||
"newKnowledge.viewLabel": "知識庫檢視",
|
||||
"newKnowledge.websiteCrawl": "網站抓取",
|
||||
"noExternalKnowledge": "目前還沒有外部知識 API,按兩下此處創建",
|
||||
|
||||
@ -318,6 +318,42 @@ describe('consoleQuery transport context', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should forward keepalive context to the base request transport', async () => {
|
||||
const request = vi.fn().mockResolvedValue(
|
||||
new Response(JSON.stringify({}), {
|
||||
status: 200,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
}),
|
||||
)
|
||||
const consoleQuery = await loadConsoleQueryWithRequest(request)
|
||||
const queryOptions = consoleQuery.agent.byAgentId.buildDraft.get.queryOptions({
|
||||
input: {
|
||||
params: {
|
||||
agent_id: 'agent-1',
|
||||
},
|
||||
},
|
||||
context: {
|
||||
keepalive: true,
|
||||
},
|
||||
})
|
||||
|
||||
await Promise.resolve(
|
||||
queryOptions.queryFn({ signal: new AbortController().signal } as QueryFunctionContext),
|
||||
).catch(() => undefined)
|
||||
|
||||
expect(request).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/agent/agent-1/build-draft'),
|
||||
expect.objectContaining({
|
||||
keepalive: true,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
fetchCompat: true,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('should serialize trial app dataset ids as repeated query params', async () => {
|
||||
const request = vi.fn().mockResolvedValue(
|
||||
new Response(
|
||||
|
||||
@ -63,6 +63,7 @@ export function getBaseURL(path: string) {
|
||||
}
|
||||
|
||||
export type ConsoleClientContext = TanstackQueryOperationContext & {
|
||||
keepalive?: boolean
|
||||
silent?: boolean
|
||||
}
|
||||
|
||||
@ -72,7 +73,9 @@ function createConsoleOpenAPILink(contract: AnyContractRouter): ConsoleClientLin
|
||||
return new OpenAPILink<ConsoleClientContext>(contract, {
|
||||
url: getBaseURL(API_PREFIX),
|
||||
fetch: (input, init, options) => {
|
||||
return request(normalizeConsoleOpenAPIURL(input.url), init, {
|
||||
const requestInit = options.context.keepalive ? { ...init, keepalive: true } : init
|
||||
|
||||
return request(normalizeConsoleOpenAPIURL(input.url), requestInit, {
|
||||
fetchCompat: true,
|
||||
request: input,
|
||||
silent: options.context.silent,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user