diff --git a/web/features/new-rag/README.md b/web/features/new-rag/README.md index ae58e16505e..c373c59a770 100644 --- a/web/features/new-rag/README.md +++ b/web/features/new-rag/README.md @@ -11,6 +11,6 @@ This feature owns the KnowledgeFS-backed knowledge list, creation flows, sources - Shared KnowledgeFS read contracts used by other features live under `service/knowledge-fs/`; feature-specific editing policy remains here. - Document query modules own server-state configuration. View components consume those options and coordinate only workflows that require one consistent page snapshot. - Document processing events live with `documents/tasks/`; retrieval event streams live with `retrieval/services/`. -- Exit confirmation, creation, and processing overlays are feature compositions of Dify UI Dialog, AlertDialog, Drawer, and Popover primitives. +- Creation and processing overlays are feature compositions of Dify UI Dialog, AlertDialog, Drawer, and Popover primitives. Files in this directory remain feature-owned; direct consumers do not become their owners. Keep shared dataset APIs and permission policy in their existing owners rather than copying them into this feature. diff --git a/web/features/new-rag/create/__tests__/page.spec.tsx b/web/features/new-rag/create/__tests__/page.spec.tsx index 99270cb210d..040d27afab5 100644 --- a/web/features/new-rag/create/__tests__/page.spec.tsx +++ b/web/features/new-rag/create/__tests__/page.spec.tsx @@ -2423,9 +2423,8 @@ describe('CreateKnowledgePage', () => { expect(routerMock.replace).toHaveBeenCalledWith('/datasets?view=new') }) - it('asks before discarding an unsaved draft', async () => { + it('closes an unsaved draft without confirmation', async () => { const user = userEvent.setup() - const historyBack = vi.spyOn(window.history, 'back').mockImplementation(() => undefined) renderPage() await user.type( screen.getByRole('textbox', { name: 'dataset.newKnowledge.name' }), @@ -2434,24 +2433,11 @@ describe('CreateKnowledgePage', () => { await user.click(screen.getByRole('button', { name: 'common.operation.close' })) - expect(routerMock.back).not.toHaveBeenCalled() - const confirmation = await screen.findByRole('alertdialog', { - name: 'dataset.newKnowledge.discardDraftTitle', - }) - expect(confirmation).toHaveTextContent('dataset.newKnowledge.discardDraftDescription') - await user.click( - within(confirmation).getByRole('button', { - name: 'dataset.newKnowledge.discardDraftConfirm', - }), - ) - expect(historyBack).toHaveBeenCalledOnce() - - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) - expect(routerMock.replace).toHaveBeenCalledWith('/datasets?view=new') + expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() }) - it('protects an unsaved draft from browser unload', async () => { + it('does not protect an unsaved draft from browser unload', async () => { const user = userEvent.setup() renderPage() await user.type( @@ -2462,49 +2448,10 @@ describe('CreateKnowledgePage', () => { act(() => window.dispatchEvent(event)) - expect(event.defaultPrevented).toBe(true) + expect(event.defaultPrevented).toBe(false) }) - it('asks before leaving an unsaved draft with browser Back', async () => { - const user = userEvent.setup() - renderPage() - await user.type( - screen.getByRole('textbox', { name: 'dataset.newKnowledge.name' }), - 'Draft knowledge', - ) - - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) - - const confirmation = await screen.findByRole('alertdialog', { - name: 'dataset.newKnowledge.discardDraftTitle', - }) - await user.click( - within(confirmation).getByRole('button', { - name: 'dataset.newKnowledge.discardDraftConfirm', - }), - ) - - expect(routerMock.replace).toHaveBeenCalledWith('/datasets?view=new') - }) - - it('does not warn after a draft is cleared before browser Back', async () => { - const user = userEvent.setup() - renderPage() - const nameInput = screen.getByRole('textbox', { name: 'dataset.newKnowledge.name' }) - await user.type(nameInput, 'Draft knowledge') - await user.clear(nameInput) - - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) - - expect( - screen.queryByRole('alertdialog', { - name: 'dataset.newKnowledge.discardDraftTitle', - }), - ).not.toBeInTheDocument() - expect(routerMock.replace).toHaveBeenCalledWith('/datasets?view=new') - }) - - it('warns before leaving a partially created knowledge space', async () => { + it('leaves a partially created knowledge space without confirmation', async () => { const user = userEvent.setup() navigationMock.startMode = 'upload' serviceMock.upload.mockRejectedValueOnce(new Error('upload unavailable')) @@ -2522,18 +2469,9 @@ describe('CreateKnowledgePage', () => { await user.click(screen.getByRole('button', { name: 'common.operation.cancel' })) - expect(routerMock.back).not.toHaveBeenCalled() - const confirmation = await screen.findByRole('alertdialog', { - name: 'dataset.newKnowledge.leavePartialSetupTitle', - }) - expect(confirmation).toHaveTextContent('dataset.newKnowledge.leavePartialSetupDescription') - await user.click( - within(confirmation).getByRole('button', { - name: 'dataset.newKnowledge.leavePartialSetupConfirm', - }), - ) expect(routerMock.replace).toHaveBeenCalledWith( '/datasets/new/e735c1dc-d2b8-4dc4-86dc-abaf2fb7d084/sources', ) + expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() }) }) diff --git a/web/features/new-rag/create/components/exit-dialog.tsx b/web/features/new-rag/create/components/exit-dialog.tsx deleted file mode 100644 index 4c346425fe2..00000000000 --- a/web/features/new-rag/create/components/exit-dialog.tsx +++ /dev/null @@ -1,71 +0,0 @@ -'use client' - -import { - AlertDialog, - AlertDialogActions, - AlertDialogCancelButton, - AlertDialogConfirmButton, - AlertDialogContent, - AlertDialogDescription, - AlertDialogTitle, -} from '@langgenius/dify-ui/alert-dialog' -import { useTranslation } from 'react-i18next' - -export type CreateKnowledgeExitReason = 'discard' | 'partial' - -export function CreateKnowledgeExitDialog({ - onCancel, - onConfirm, - reason, -}: { - onCancel: () => void - onConfirm: () => void - reason: CreateKnowledgeExitReason | null -}) { - const { t } = useTranslation('dataset') - const { t: tCommon } = useTranslation('common') - const isPartial = reason === 'partial' - - return ( - { - if (!open) onCancel() - }} - > - - - - {t(($) => - isPartial - ? $['newKnowledge.leavePartialSetupTitle'] - : $['newKnowledge.discardDraftTitle'], - )} - - } - className="system-md-regular text-text-secondary" - > - {t(($) => - isPartial - ? $['newKnowledge.leavePartialSetupDescription'] - : $['newKnowledge.discardDraftDescription'], - )} - - - - - {tCommon(($) => $['operation.cancel'])} - - - {t(($) => - isPartial - ? $['newKnowledge.leavePartialSetupConfirm'] - : $['newKnowledge.discardDraftConfirm'], - )} - - - - - ) -} diff --git a/web/features/new-rag/create/page.tsx b/web/features/new-rag/create/page.tsx index f26c8514e44..f42298268b1 100644 --- a/web/features/new-rag/create/page.tsx +++ b/web/features/new-rag/create/page.tsx @@ -10,7 +10,6 @@ import type { KnowledgeFsUploadPhase, KnowledgeFsUploadProgress, } from '../upload/knowledge-fs-upload' -import type { CreateKnowledgeExitReason } from './components/exit-dialog' import type { QueuedUpload } from './upload-queue' import type { KnowledgeVisibility } from './workflow' import { Button } from '@langgenius/dify-ui/button' @@ -38,7 +37,7 @@ import { import { Textarea } from '@langgenius/dify-ui/textarea' import { useMutation, useQueryClient } from '@tanstack/react-query' import { useAtomValue } from 'jotai' -import { useCallback, useEffect, useId, useRef, useState } from 'react' +import { useCallback, useId, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { datasetDefaultPermissionKeysAtom } from '@/context/permission-state' import { knowledgeFsUploadEnabledAtom, rbacEnabledAtom } from '@/features/system-features/state' @@ -62,7 +61,6 @@ import { } from '../upload/knowledge-fs-upload' import { useKnowledgeFileSizeLimit } from '../upload/use-file-size-limit' import { KnowledgeIllustration, StartMode } from './components/dialog-parts' -import { CreateKnowledgeExitDialog } from './components/exit-dialog' import { CreateSourceSetup } from './source-setup' import { CreateUploadQueue } from './upload-queue' import { @@ -122,14 +120,9 @@ export function CreateKnowledgePage() { () => new Map(), ) const [uploadError, setUploadError] = useState(false) - const [exitReason, setExitReason] = useState(null) const idempotencyKeyRef = useRef(undefined) const uploadsRef = useRef([]) const uploadProgressRef = useRef(new Map()) - const historyGuardArmedRef = useRef(false) - const browserBackExitRef = useRef(false) - const pendingNavigationRef = useRef(undefined) - const navigationFallbackRef = useRef | undefined>(undefined) const createMutation = useMutation({ mutationFn: createKnowledge }) const submissionPending = createMutation.isPending || uploading || stagingCount > 0 const validUploads = uploads.filter(({ issue }) => !issue) @@ -144,106 +137,11 @@ export function CreateKnowledgePage() { !validUploads.length || validUploads.some((upload) => upload.stagingFailed || !upload.stagedUploadId)) const sourceSubmissionBlocked = startMode === 'source' && !initialSource - const sourceDraftChanged = - JSON.stringify(sourceDraft) !== - JSON.stringify(createNewKnowledgeSourceDraft(sourceDraft.sourceType)) - const hasUnsavedChanges = Boolean( - name || - description || - visibility !== defaultVisibility || - startMode !== initialStartMode || - sourceDraftChanged || - uploads.length || - createdKnowledge, - ) - const updateInitialSource = useCallback((source?: InitialSource) => { initialSourceRef.current = source setInitialSource(source) }, []) - 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() - globalThis.clearTimeout(navigationFallbackRef.current) - navigationFallbackRef.current = globalThis.setTimeout(() => { - if (pendingNavigationRef.current !== path) return - pendingNavigationRef.current = undefined - historyGuardArmedRef.current = false - router.replace(path) - }, 1000) - }, - [router], - ) - - 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) { - globalThis.clearTimeout(navigationFallbackRef.current) - navigationFallbackRef.current = undefined - pendingNavigationRef.current = undefined - router.replace(pendingNavigation) - return - } - if (!hasUnsavedChanges) { - router.replace(newKnowledgeListPath) - return - } - - browserBackExitRef.current = true - setExitReason(createdKnowledge ? 'partial' : 'discard') - } - - globalThis.addEventListener('popstate', handlePopState) - return () => globalThis.removeEventListener('popstate', handlePopState) - }, [createdKnowledge, hasUnsavedChanges, router]) - - useEffect( - () => () => { - globalThis.clearTimeout(navigationFallbackRef.current) - }, - [], - ) - - useEffect(() => { - if (!hasUnsavedChanges) return - - const handleBeforeUnload = (event: BeforeUnloadEvent) => { - event.preventDefault() - event.returnValue = '' - } - - globalThis.addEventListener('beforeunload', handleBeforeUnload) - return () => globalThis.removeEventListener('beforeunload', handleBeforeUnload) - }, [hasUnsavedChanges]) - const resetUnsubmittedError = () => { if (!submissionLocked) createMutation.reset() setUploadError(false) @@ -307,39 +205,15 @@ export function CreateKnowledgePage() { const requestClose = () => { if (submissionPending) return - if (createdKnowledge) { - setExitReason('partial') - return - } - if (hasUnsavedChanges) { - setExitReason('discard') - return - } - replaceAfterHistoryGuard(newKnowledgeListPath) - } - - const confirmExit = () => { - const confirmedReason = exitReason - setExitReason(null) for (const upload of uploadsRef.current) { if (upload.stagedUploadId) void discardKnowledgeFsStagedUpload(upload.stagedUploadId).catch(() => undefined) } - if (confirmedReason === 'partial' && createdKnowledge) { - browserBackExitRef.current = false - replaceAfterHistoryGuard(newKnowledgeDetailPath(createdKnowledge.control_space_id)) - return - } - browserBackExitRef.current = false - replaceAfterHistoryGuard(newKnowledgeListPath) - } - - const cancelExit = () => { - setExitReason(null) - if (!browserBackExitRef.current) return - - browserBackExitRef.current = false - armHistoryGuard() + router.replace( + createdKnowledge + ? newKnowledgeDetailPath(createdKnowledge.control_space_id) + : newKnowledgeListPath, + ) } const handleSubmit = async () => { @@ -401,7 +275,7 @@ export function CreateKnowledgePage() { } } - replaceAfterHistoryGuard( + router.replace( startMode === 'upload' ? newKnowledgeDocumentsPath(created.control_space_id) : `${newKnowledgeDetailPath(created.control_space_id)}${ @@ -693,18 +567,13 @@ export function CreateKnowledgePage() { - { setModelSetupDialogOpen(false) if (createdKnowledge) - replaceAfterHistoryGuard(newKnowledgeSettingsPath(createdKnowledge.control_space_id)) + router.replace(newKnowledgeSettingsPath(createdKnowledge.control_space_id)) }} /> diff --git a/web/features/new-rag/settings/__tests__/form.spec.tsx b/web/features/new-rag/settings/__tests__/form.spec.tsx index 0ff17540160..6232e46b671 100644 --- a/web/features/new-rag/settings/__tests__/form.spec.tsx +++ b/web/features/new-rag/settings/__tests__/form.spec.tsx @@ -1705,76 +1705,7 @@ describe('KnowledgeSettingsPage workflows', () => { expect(screen.getByRole('alert')).toHaveTextContent('datasetSettings.form.embeddingModel') }) - it('asks before following a link while the form has unsaved changes', async () => { - const user = userEvent.setup() - renderForm() - const destination = document.createElement('a') - destination.href = '/datasets/new/space-1/sources' - destination.textContent = 'Go to sources' - document.body.append(destination) - - const nameInput = screen.getByRole('textbox', { name: 'datasetSettings.form.name' }) - await user.clear(nameInput) - await user.type(nameInput, 'Unsaved camera specs') - await user.click(destination) - - const dialog = await screen.findByRole('alertdialog') - expect(routerMock.push).not.toHaveBeenCalled() - await user.click( - within(dialog).getByRole('button', { - name: 'dataset.newKnowledge.discardDraftConfirm', - }), - ) - - expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/sources') - destination.remove() - }) - - it('protects a delayed retrieval save from immediate navigation', async () => { - renderForm() - const destination = document.createElement('a') - destination.href = '/datasets/new/space-1/sources' - destination.textContent = 'Go to sources' - document.body.append(destination) - - fireEvent.change( - screen.getByRole('textbox', { - name: 'dataset.newKnowledge.settings.topKLabel', - }), - { target: { value: '8' } }, - ) - fireEvent.click(destination) - - expect(await screen.findByRole('alertdialog')).toBeInTheDocument() - expect(routerMock.push).not.toHaveBeenCalled() - destination.remove() - }) - - it('asks before browser back navigation while the form has unsaved changes', async () => { - const user = userEvent.setup() - const historyBack = vi.spyOn(globalThis.history, 'back').mockImplementation(() => {}) - try { - renderForm() - const nameInput = screen.getByRole('textbox', { name: 'datasetSettings.form.name' }) - await user.clear(nameInput) - await user.type(nameInput, 'Unsaved camera specs') - - act(() => globalThis.dispatchEvent(new PopStateEvent('popstate'))) - - const dialog = await screen.findByRole('alertdialog') - expect(historyBack).not.toHaveBeenCalled() - await user.click( - within(dialog).getByRole('button', { - name: 'dataset.newKnowledge.discardDraftConfirm', - }), - ) - expect(historyBack).toHaveBeenCalledOnce() - } finally { - historyBack.mockRestore() - } - }) - - it('protects unsaved changes from browser unload', async () => { + it('does not protect unsaved changes from browser unload', async () => { const user = userEvent.setup() renderForm() @@ -1784,7 +1715,8 @@ describe('KnowledgeSettingsPage workflows', () => { const event = new Event('beforeunload', { cancelable: true }) globalThis.dispatchEvent(event) - expect(event.defaultPrevented).toBe(true) + expect(event.defaultPrevented).toBe(false) + expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() }) it('normalizes split Knowledge FS provider identities for the model selector', () => { diff --git a/web/features/new-rag/settings/__tests__/state-boundary.spec.tsx b/web/features/new-rag/settings/__tests__/state-boundary.spec.tsx index d6d5559a409..649604526a5 100644 --- a/web/features/new-rag/settings/__tests__/state-boundary.spec.tsx +++ b/web/features/new-rag/settings/__tests__/state-boundary.spec.tsx @@ -5,25 +5,25 @@ import { render } from '@/test/console/render' import { KnowledgeSettingsStateBoundary } from '../state/boundary' import { knowledgeSettingsSpaceIdAtom } from '../state/inputs' import { - knowledgeSettingsHasUnsavedWorkAtom, - startKnowledgeSettingsBasicDraftAtom, + knowledgeSettingsHasPendingSaveAtom, + setKnowledgeSettingsSavePendingAtom, } from '../state/workflow' const globalProbeAtom = atom('global-before') function WorkflowProbe({ name }: { name: string }) { const globalValue = useAtomValue(globalProbeAtom) - const hasUnsavedWork = useAtomValue(knowledgeSettingsHasUnsavedWorkAtom) + const hasPendingSave = useAtomValue(knowledgeSettingsHasPendingSaveAtom) const knowledgeSpaceId = useAtomValue(knowledgeSettingsSpaceIdAtom) - const startDraft = useSetAtom(startKnowledgeSettingsBasicDraftAtom) + const setSavePending = useSetAtom(setKnowledgeSettingsSavePendingAtom) return ( {globalValue} - {hasUnsavedWork ? 'dirty' : 'clean'} + {hasPendingSave ? 'saving' : 'idle'} {knowledgeSpaceId} - - start draft + setSavePending({ owner: 'probe', pending: true })} type="button"> + start saving ) @@ -59,9 +59,9 @@ describe('KnowledgeSettingsStateBoundary', () => { const first = within(screen.getByRole('region', { name: 'first settings instance' })) const second = within(screen.getByRole('region', { name: 'second settings instance' })) - await user.click(first.getByRole('button', { name: 'start draft' })) - expect(first.getByText('dirty')).toBeInTheDocument() - expect(second.getByText('clean')).toBeInTheDocument() + await user.click(first.getByRole('button', { name: 'start saving' })) + expect(first.getByText('saving')).toBeInTheDocument() + expect(second.getByText('idle')).toBeInTheDocument() await user.click(screen.getByRole('button', { name: 'update global' })) expect(first.getByText('global-after')).toBeInTheDocument() @@ -81,13 +81,13 @@ describe('KnowledgeSettingsStateBoundary', () => { const rendered = render(tree('space-1')) const instance = within(screen.getByRole('region', { name: 'settings instance' })) - await user.click(instance.getByRole('button', { name: 'start draft' })) - expect(instance.getByText('dirty')).toBeInTheDocument() + await user.click(instance.getByRole('button', { name: 'start saving' })) + expect(instance.getByText('saving')).toBeInTheDocument() rendered.rerender(tree('space-2')) const resetInstance = within(screen.getByRole('region', { name: 'settings instance' })) - expect(resetInstance.getByText('clean')).toBeInTheDocument() + expect(resetInstance.getByText('idle')).toBeInTheDocument() expect(resetInstance.getByText('space-2')).toBeInTheDocument() }) }) diff --git a/web/features/new-rag/settings/basic-information.tsx b/web/features/new-rag/settings/basic-information.tsx index 3828e2e4cfb..a25ce99ed62 100644 --- a/web/features/new-rag/settings/basic-information.tsx +++ b/web/features/new-rag/settings/basic-information.tsx @@ -31,11 +31,7 @@ import { knowledgeSettingsPermissionsAtom, knowledgeSettingsSpaceAtom, } from './state/queries' -import { - finishKnowledgeSettingsBasicDraftAtom, - setKnowledgeSettingsSavePendingAtom, - startKnowledgeSettingsBasicDraftAtom, -} from './state/workflow' +import { setKnowledgeSettingsSavePendingAtom } from './state/workflow' const NAME_ERROR_ID = 'knowledge-name-error' const DESCRIPTION_ERROR_ID = 'knowledge-description-error' @@ -114,8 +110,6 @@ export function BasicInformationSection() { const { t: tWorkflow } = useTranslation('workflow') const space = useAtomValue(knowledgeSettingsSpaceAtom) const permissions = useAtomValue(knowledgeSettingsPermissionsAtom) - const startDraft = useSetAtom(startKnowledgeSettingsBasicDraftAtom) - const finishDraft = useSetAtom(finishKnowledgeSettingsBasicDraftAtom) const setSavePending = useSetAtom(setKnowledgeSettingsSavePendingAtom) const invalidateSettings = useSetAtom(invalidateKnowledgeSettingsAtom) const membersQuery = useMembers() @@ -195,12 +189,10 @@ export function BasicInformationSection() { draftRef.current = undefined draftBaseVersionRef.current = undefined setDraft(undefined) - finishDraft() return } draftRef.current = next draftBaseVersionRef.current ??= serverVersion - startDraft() setDraft(next) } @@ -209,7 +201,6 @@ export function BasicInformationSection() { draftBaseVersionRef.current = undefined setDraft(undefined) setNameTouched(false) - finishDraft() } const showSaveError = (error?: unknown) => @@ -276,7 +267,6 @@ export function BasicInformationSection() { toast.success(tCommon(($) => $['api.actionSuccess'])) setIsRefreshing(true) draftBaseVersionRef.current = undefined - finishDraft() void invalidateSettings().then( () => { draftRef.current = undefined diff --git a/web/features/new-rag/settings/form.tsx b/web/features/new-rag/settings/form.tsx index 69f5b02f108..445dc45a442 100644 --- a/web/features/new-rag/settings/form.tsx +++ b/web/features/new-rag/settings/form.tsx @@ -5,7 +5,6 @@ import { useTranslation } from 'react-i18next' import { BasicInformationSection } from './basic-information' import { DeleteKnowledgeAction } from './delete-knowledge' import { ExternalAccessSection } from './external-access' -import { KnowledgeSettingsNavigationGuard } from './navigation-guard' import { RetrievalSettingsSection } from './retrieval-settings' import { knowledgeSettingsSpaceAtom } from './state/queries' @@ -34,7 +33,6 @@ export function KnowledgeSettingsForm() { - > ) } diff --git a/web/features/new-rag/settings/navigation-guard.tsx b/web/features/new-rag/settings/navigation-guard.tsx deleted file mode 100644 index e8f835e6751..00000000000 --- a/web/features/new-rag/settings/navigation-guard.tsx +++ /dev/null @@ -1,177 +0,0 @@ -'use client' - -import { - AlertDialog, - AlertDialogActions, - AlertDialogCancelButton, - AlertDialogConfirmButton, - AlertDialogContent, - AlertDialogDescription, - AlertDialogTitle, -} from '@langgenius/dify-ui/alert-dialog' -import { useAtomValue } from 'jotai' -import { useCallback, useEffect, useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { useRouter } from '@/next/navigation' -import { knowledgeSettingsHasUnsavedWorkAtom } from './state/workflow' - -export function KnowledgeSettingsNavigationGuard() { - const { t } = useTranslation('dataset') - const { t: tCommon } = useTranslation('common') - const router = useRouter() - const hasUnsavedWork = useAtomValue(knowledgeSettingsHasUnsavedWorkAtom) - const [discardDialogOpen, setDiscardDialogOpen] = useState(false) - const pendingNavigationRef = useRef(undefined) - const historyGuardArmedRef = useRef(false) - const historyGuardReleaseRef = useRef(false) - const browserBackPendingRef = useRef(false) - const allowNavigationRef = useRef(false) - - const armHistoryGuard = useCallback(() => { - globalThis.history.pushState(globalThis.history.state, '', globalThis.location.href) - historyGuardArmedRef.current = true - }, []) - - useEffect(() => { - if (hasUnsavedWork) { - if ( - !historyGuardArmedRef.current && - !browserBackPendingRef.current && - !allowNavigationRef.current - ) - armHistoryGuard() - return - } - if (!historyGuardArmedRef.current) return - historyGuardReleaseRef.current = true - historyGuardArmedRef.current = false - globalThis.history.back() - }, [armHistoryGuard, hasUnsavedWork]) - - useEffect(() => { - const handlePopState = () => { - if (historyGuardReleaseRef.current) { - historyGuardReleaseRef.current = false - return - } - if (allowNavigationRef.current) { - const destination = pendingNavigationRef.current - pendingNavigationRef.current = undefined - if (destination) router.push(destination) - return - } - if (!historyGuardArmedRef.current) return - - historyGuardArmedRef.current = false - browserBackPendingRef.current = true - setDiscardDialogOpen(true) - } - - globalThis.addEventListener('popstate', handlePopState) - return () => globalThis.removeEventListener('popstate', handlePopState) - }, [router]) - - useEffect(() => { - if (!hasUnsavedWork) return - - const handleBeforeUnload = (event: BeforeUnloadEvent) => { - event.preventDefault() - event.returnValue = '' - } - 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) - const current = new URL(globalThis.location.href) - if ( - destination.origin !== current.origin || - (destination.pathname === current.pathname && - destination.search === current.search && - destination.hash === current.hash) - ) - return - - event.preventDefault() - pendingNavigationRef.current = `${destination.pathname}${destination.search}${destination.hash}` - setDiscardDialogOpen(true) - } - - globalThis.addEventListener('beforeunload', handleBeforeUnload) - document.addEventListener('click', handleDocumentClick, true) - return () => { - globalThis.removeEventListener('beforeunload', handleBeforeUnload) - document.removeEventListener('click', handleDocumentClick, true) - } - }, [hasUnsavedWork]) - - const confirmDiscardAndNavigate = () => { - const destination = pendingNavigationRef.current - setDiscardDialogOpen(false) - allowNavigationRef.current = true - if (browserBackPendingRef.current) { - browserBackPendingRef.current = false - pendingNavigationRef.current = undefined - globalThis.history.back() - return - } - if (destination && historyGuardArmedRef.current) { - historyGuardArmedRef.current = false - globalThis.history.back() - return - } - pendingNavigationRef.current = undefined - if (destination) router.push(destination) - } - - const closeDiscardDialog = () => { - setDiscardDialogOpen(false) - pendingNavigationRef.current = undefined - if (!browserBackPendingRef.current) return - browserBackPendingRef.current = false - if (hasUnsavedWork) armHistoryGuard() - } - - return ( - { - if (open) setDiscardDialogOpen(true) - else closeDiscardDialog() - }} - > - - - - {tCommon(($) => $['operation.confirmAction'])} - - - {t(($) => $['newKnowledge.discardDraftDescription'])} - - - - {tCommon(($) => $['operation.cancel'])} - - {t(($) => $['newKnowledge.discardDraftConfirm'])} - - - - - ) -} diff --git a/web/features/new-rag/settings/retrieval-settings.tsx b/web/features/new-rag/settings/retrieval-settings.tsx index e832168ad6c..18a84348aac 100644 --- a/web/features/new-rag/settings/retrieval-settings.tsx +++ b/web/features/new-rag/settings/retrieval-settings.tsx @@ -48,11 +48,7 @@ import { knowledgeSettingsSettingsAtom, knowledgeSettingsSpaceAtom, } from './state/queries' -import { - finishKnowledgeSettingsRetrievalDraftAtom, - setKnowledgeSettingsSavePendingAtom, - startKnowledgeSettingsRetrievalDraftAtom, -} from './state/workflow' +import { setKnowledgeSettingsSavePendingAtom } from './state/workflow' const REASONING_MODEL_LABEL_ID = 'knowledge-reasoning-model-label' const REASONING_MODEL_ERROR_ID = 'knowledge-reasoning-model-error' @@ -69,8 +65,6 @@ export function RetrievalSettingsSection() { const space = useAtomValue(knowledgeSettingsSpaceAtom) const settings = useAtomValue(knowledgeSettingsSettingsAtom) const invalidateSettings = useSetAtom(invalidateKnowledgeSettingsAtom) - const startDraftSession = useSetAtom(startKnowledgeSettingsRetrievalDraftAtom) - const finishDraftSession = useSetAtom(finishKnowledgeSettingsRetrievalDraftAtom) const setSavePending = useSetAtom(setKnowledgeSettingsSavePendingAtom) const { data: reasoningModelList } = useModelList(ModelTypeEnum.textGeneration) const { data: embeddingModelList } = useModelList(ModelTypeEnum.textEmbedding) @@ -136,7 +130,6 @@ export function RetrievalSettingsSection() { retrievalBaselineRef.current = retrievalFingerprint(current) if (!draft) settingsRevisionRef.current = settings.revision draftSessionActiveRef.current = true - startDraftSession() setSavePending({ owner: 'retrieval', pending: true }) } const next = { ...current, ...patch } @@ -250,7 +243,6 @@ export function RetrievalSettingsSection() { liveDraftRef.current = latestDraft if (latestDraft) setDraft(latestDraft) draftSessionActiveRef.current = false - finishDraftSession() setSavePending({ owner: 'retrieval', pending: false }) } @@ -284,7 +276,6 @@ export function RetrievalSettingsSection() { const latestDraft = liveDraftRef.current if (latestDraft) setDraft(latestDraft) draftSessionActiveRef.current = false - finishDraftSession() setSavePending({ owner: 'retrieval', pending: false }) showSaveSuccess() }) @@ -306,7 +297,6 @@ export function RetrievalSettingsSection() { } // oxlint-disable-next-line react-hooks/exhaustive-deps -- Migration completion is keyed by the observer state; queued saves use the latest ref snapshot. }, [ - finishDraftSession, invalidateSettings, migrationQuery.data, migrationQuery.isError, diff --git a/web/features/new-rag/settings/state/workflow.ts b/web/features/new-rag/settings/state/workflow.ts index 6af3e386c4b..c762c11fbf3 100644 --- a/web/features/new-rag/settings/state/workflow.ts +++ b/web/features/new-rag/settings/state/workflow.ts @@ -1,18 +1,8 @@ import { atom } from 'jotai' -const basicDraftActiveAtom = atom(false) -const retrievalDraftActiveAtom = atom(false) const pendingSaveOwnersAtom = atom>(new globalThis.Set()) -export const knowledgeSettingsScopedAtoms = [ - basicDraftActiveAtom, - retrievalDraftActiveAtom, - pendingSaveOwnersAtom, -] as const - -export const knowledgeSettingsHasUnsavedWorkAtom = atom( - (get) => get(basicDraftActiveAtom) || get(retrievalDraftActiveAtom), -) +export const knowledgeSettingsScopedAtoms = [pendingSaveOwnersAtom] as const export const knowledgeSettingsHasPendingSaveAtom = atom( (get) => get(pendingSaveOwnersAtom).size > 0, @@ -29,19 +19,3 @@ export const setKnowledgeSettingsSavePendingAtom = atom( }) }, ) - -export const startKnowledgeSettingsBasicDraftAtom = atom(null, (_get, set) => { - set(basicDraftActiveAtom, true) -}) - -export const finishKnowledgeSettingsBasicDraftAtom = atom(null, (_get, set) => { - set(basicDraftActiveAtom, false) -}) - -export const startKnowledgeSettingsRetrievalDraftAtom = atom(null, (_get, set) => { - set(retrievalDraftActiveAtom, true) -}) - -export const finishKnowledgeSettingsRetrievalDraftAtom = atom(null, (_get, set) => { - set(retrievalDraftActiveAtom, false) -}) diff --git a/web/features/new-rag/sources/create/__tests__/page.spec.tsx b/web/features/new-rag/sources/create/__tests__/page.spec.tsx index de5a881daae..d47713358d4 100644 --- a/web/features/new-rag/sources/create/__tests__/page.spec.tsx +++ b/web/features/new-rag/sources/create/__tests__/page.spec.tsx @@ -901,7 +901,6 @@ describe('AddSourcePage', () => { it('clears the stored draft when source setup is canceled', async () => { const user = userEvent.setup() - const historyBack = vi.spyOn(window.history, 'back').mockImplementation(() => undefined) const storageKey = newKnowledgeSourceDraftStorageKey('cancel-draft') globalThis.sessionStorage.setItem( storageKey, @@ -920,19 +919,10 @@ describe('AddSourcePage', () => { await user.click( await screen.findByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' }), ) - const confirmation = await screen.findByRole('alertdialog', { - name: 'dataset.newKnowledge.discardSourceDraftTitle', - }) - expect(globalThis.sessionStorage.getItem(storageKey)).not.toBeNull() - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardDraftConfirm' }), - ) expect(globalThis.sessionStorage.getItem(storageKey)).toBeNull() - expect(historyBack).toHaveBeenCalledOnce() - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) expect(routerMock.replace).toHaveBeenCalledWith('/datasets/new/space-1/sources') - expect(confirmation).not.toBeInTheDocument() + expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() }) it('creates the exact Firecrawl provider connection without leaking credentials', async () => { @@ -964,8 +954,6 @@ describe('AddSourcePage', () => { params: { control_space_id: 'space-1' }, }), ) - await screen.findByRole('status', { name: 'appApi.loading' }) - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) expect(queryClientMock.invalidateQueries).toHaveBeenCalledWith({ queryKey: ['source-connections'], }) @@ -1089,7 +1077,6 @@ describe('AddSourcePage', () => { params: { control_space_id: 'space-1' }, }), ) - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) expect( await screen.findByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ }), ).toBeEnabled() @@ -1224,9 +1211,8 @@ describe('AddSourcePage', () => { ).not.toBeInTheDocument() }) - it('releases the parent history guard before the crawl preview owns navigation', async () => { + it('shows the crawl preview immediately after the provider connection becomes active', async () => { const user = userEvent.setup() - const historyBack = vi.spyOn(window.history, 'back').mockImplementation(() => undefined) clientMock.createConnection.mockResolvedValue(connection('active')) render() @@ -1236,14 +1222,9 @@ describe('AddSourcePage', () => { await user.type(screen.getByLabelText(/Api Key/), 'secret-value') await user.click(screen.getByRole('button', { name: connectFirecrawlButtonName })) - await waitFor(() => expect(historyBack).toHaveBeenCalledOnce()) - expect(screen.queryByText(/dataset\.newKnowledge\.providerConnected/)).not.toBeInTheDocument() - - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) await screen.findByText(/dataset\.newKnowledge\.providerConnected/) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - expect(historyBack).toHaveBeenCalledOnce() expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/sources') }) @@ -1285,9 +1266,6 @@ describe('AddSourcePage', () => { view.rerender( , ) - await screen.findByRole('status', { name: 'appApi.loading' }) - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) - expect(screen.getByRole('textbox', { name: /dataset\.newKnowledge\.rootUrl/ })).toHaveValue( 'https://docs.dify.ai', ) @@ -1341,7 +1319,6 @@ describe('AddSourcePage', () => { await user.click(screen.getByRole('button', { name: connectFirecrawlButtonName })) await waitFor(() => expect(clientMock.createConnection).toHaveBeenCalledOnce()) - act(() => window.dispatchEvent(new PopStateEvent('popstate'))) expect(await screen.findByText(/dataset\.newKnowledge\.providerConnected/)).toBeInTheDocument() expect( screen.queryByText('dataset.newKnowledge.connectionFailed:{"provider":"Firecrawl"}'), diff --git a/web/features/new-rag/sources/create/__tests__/website-crawl-preview.spec.tsx b/web/features/new-rag/sources/create/__tests__/website-crawl-preview.spec.tsx index 3388dd1c4a6..6085c3b2aad 100644 --- a/web/features/new-rag/sources/create/__tests__/website-crawl-preview.spec.tsx +++ b/web/features/new-rag/sources/create/__tests__/website-crawl-preview.spec.tsx @@ -1,5 +1,5 @@ import type { Source, SourceWorkflowRun } from '../../source-models' -import { act, screen, waitFor, within } from '@testing-library/react' +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' @@ -397,9 +397,6 @@ describe('WebsiteCrawlPreview', () => { }) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) await waitFor(() => expect(clientMock.deleteSource).toHaveBeenCalledTimes(2)) expect(clientMock.deleteSource).toHaveBeenNthCalledWith(1, { @@ -436,9 +433,6 @@ describe('WebsiteCrawlPreview', () => { }) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) await waitFor(() => expect(clientMock.getSource).toHaveBeenCalledOnce()) expect(clientMock.deleteSource).toHaveBeenCalledOnce() @@ -579,7 +573,7 @@ describe('WebsiteCrawlPreview', () => { expect(clientMock.createSource.mock.calls[0]?.[0].body.metadata.crawlOptions.limit).toBe(50) }) - it('confirms dirty cancellation and protects an unfinished draft from page unload', async () => { + it('cancels a dirty draft directly without protecting page unload', async () => { const user = userEvent.setup() render() @@ -589,23 +583,13 @@ describe('WebsiteCrawlPreview', () => { ) const unload = new Event('beforeunload', { cancelable: true }) window.dispatchEvent(unload) - expect(unload.defaultPrevented).toBe(true) + expect(unload.defaultPrevented).toBe(false) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - expect( - screen.getByRole('alertdialog', { name: 'dataset.newKnowledge.discardSourceChanges' }), - ).toBeInTheDocument() - expect(routerMock.push).not.toHaveBeenCalled() - - await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.keepEditing' })) - expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() - await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) await waitFor(() => expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/sources'), ) + expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() }) it('cancels an active preview before discarding its provisional source', async () => { @@ -617,9 +601,6 @@ describe('WebsiteCrawlPreview', () => { await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce()) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) await waitFor(() => expect(clientMock.cancel).toHaveBeenCalledOnce()) expect(clientMock.cancel).toHaveBeenCalledWith({ @@ -645,12 +626,8 @@ describe('WebsiteCrawlPreview', () => { await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce()) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) - expect(screen.getByRole('button', { name: 'dataset.newKnowledge.keepEditing' })).toBeDisabled() expect( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), + screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' }), ).toHaveAttribute('aria-disabled', 'true') startRequest.resolve(run('running')) @@ -672,9 +649,6 @@ describe('WebsiteCrawlPreview', () => { await screen.findByRole('alert') await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledTimes(2)) expect(clientMock.startPreview.mock.calls[0]?.[0].headers).toEqual( @@ -695,9 +669,6 @@ describe('WebsiteCrawlPreview', () => { await waitFor(() => expect(clientMock.createSource).toHaveBeenCalledOnce()) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) sourceRequest.resolve(source()) await waitFor(() => @@ -707,74 +678,6 @@ describe('WebsiteCrawlPreview', () => { expect(clientMock.cancel).not.toHaveBeenCalled() }) - it('cancels a fresh re-crawl that returns after navigation discard was confirmed', async () => { - const recrawlRequest = deferred() - clientMock.startPreview - .mockResolvedValueOnce(run('running')) - .mockReturnValueOnce(recrawlRequest.promise) - clientMock.cancel - .mockResolvedValueOnce(run('canceled')) - .mockResolvedValueOnce(run('canceled', { id: 'run-2' })) - render( - <> - Documents navigation - - >, - ) - 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.reCrawl' })) - await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledTimes(2)) - - await user.click(screen.getByRole('link', { name: 'Documents navigation' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) - recrawlRequest.resolve(run('running', { id: 'run-2' })) - - await waitFor(() => expect(clientMock.cancel).toHaveBeenCalledTimes(2)) - expect(clientMock.retry).not.toHaveBeenCalled() - await waitFor(() => - expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/documents'), - ) - }) - - it('reconciles a response-lost fresh re-crawl before leaving the preview', async () => { - clientMock.startPreview - .mockResolvedValueOnce(run('running')) - .mockRejectedValueOnce(new Error('response lost')) - .mockResolvedValueOnce(run('running', { id: 'run-2' })) - clientMock.cancel - .mockResolvedValueOnce(run('canceled')) - .mockResolvedValueOnce(run('canceled', { id: 'run-2' })) - render( - <> - Documents navigation - - >, - ) - 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.reCrawl' })) - await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledTimes(2)) - - await user.click(screen.getByRole('link', { name: 'Documents navigation' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) - - await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledTimes(3)) - await waitFor(() => expect(clientMock.cancel).toHaveBeenCalledTimes(2)) - expect(clientMock.startPreview.mock.calls[1]?.[0].headers).toEqual( - clientMock.startPreview.mock.calls[2]?.[0].headers, - ) - await waitFor(() => - expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/documents'), - ) - }) - it('keeps the started run available when discard cancellation must be retried', async () => { clientMock.getRun.mockReturnValue(new Promise(() => {})) clientMock.cancel @@ -786,17 +689,10 @@ describe('WebsiteCrawlPreview', () => { await waitFor(() => expect(clientMock.startPreview).toHaveBeenCalledOnce()) await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) - expect(within(screen.getByRole('alertdialog')).getByRole('alert')).toHaveTextContent( - 'dataset.newKnowledge.crawlFailedDescription', - ) + expect(screen.getByText('dataset.newKnowledge.crawlFailedDescription')).toBeInTheDocument() expect(routerMock.push).not.toHaveBeenCalled() - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) + await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) await waitFor(() => expect(clientMock.cancel).toHaveBeenCalledTimes(2)) expect(clientMock.cancel.mock.calls[0]?.[0].params.run_id).toBe('run-1') @@ -806,16 +702,11 @@ describe('WebsiteCrawlPreview', () => { ) }) - it('keeps the preview available when re-crawl cancellation fails', async () => { + it('cancels the preview after a re-crawl cancellation is retried', async () => { clientMock.cancel .mockRejectedValueOnce(Object.assign(new Error('conflict'), { status: 409 })) .mockResolvedValueOnce(run('canceled')) - render( - <> - Documents navigation - - >, - ) + render() const user = await fillValidForm() await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' })) await screen.findByText('Getting started') @@ -824,66 +715,14 @@ describe('WebsiteCrawlPreview', () => { expect(clientMock.startPreview).toHaveBeenCalledOnce() expect(screen.getByText('Getting started')).toBeInTheDocument() - await user.click(screen.getByRole('link', { name: 'Documents navigation' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) + await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) await waitFor(() => expect(clientMock.cancel).toHaveBeenCalledTimes(2)) await waitFor(() => - expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/documents'), + expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/sources'), ) }) - it('guards sidebar links and browser history after a crawl preview is ready', async () => { - render( - <> - Documents navigation - - >, - ) - const user = await fillValidForm() - await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.crawlAndPreview' })) - await screen.findByText('Getting started') - - act(() => window.history.back()) - expect( - await screen.findByRole('alertdialog', { - name: 'dataset.newKnowledge.discardSourceChanges', - }), - ).toBeInTheDocument() - await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.keepEditing' })) - - await user.click(screen.getByRole('link', { name: 'Documents navigation' })) - expect( - screen.getByRole('alertdialog', { name: 'dataset.newKnowledge.discardSourceChanges' }), - ).toBeInTheDocument() - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) - - await waitFor(() => - expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/documents'), - ) - }) - - it('guards browser history before a crawl preview starts', async () => { - const user = userEvent.setup() - render() - await user.type( - screen.getByLabelText(/^dataset\.newKnowledge\.rootUrl/), - 'https://docs.dify.ai', - ) - - act(() => window.history.back()) - - expect( - await screen.findByRole('alertdialog', { - name: 'dataset.newKnowledge.discardSourceChanges', - }), - ).toBeInTheDocument() - }) - it('leaves through clean Cancel after a dirty form is cleared', async () => { const user = userEvent.setup() render() @@ -899,48 +738,6 @@ describe('WebsiteCrawlPreview', () => { expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() }) - it('leaves through a same-origin link after a dirty form is cleared', async () => { - const user = userEvent.setup() - render( - <> - Documents navigation - - >, - ) - const rootUrl = screen.getByLabelText(/^dataset\.newKnowledge\.rootUrl/) - await user.type(rootUrl, 'x') - await user.clear(rootUrl) - - await user.click(screen.getByRole('link', { name: 'Documents navigation' })) - - await waitFor(() => - expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/documents'), - ) - expect(screen.queryByRole('alertdialog')).not.toBeInTheDocument() - }) - - it('clears a canceled sidebar destination before the form cancel action', async () => { - render( - <> - Documents navigation - - >, - ) - const user = await fillValidForm() - await user.click(screen.getByRole('link', { name: 'Documents navigation' })) - await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.keepEditing' })) - - await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) - - await waitFor(() => - expect(routerMock.push).toHaveBeenCalledWith('/datasets/new/space-1/sources'), - ) - expect(routerMock.push).not.toHaveBeenCalledWith('/datasets/new/space-1/documents') - }) - it('shows pending feedback while a preview-ready crawl is being restarted', async () => { const cancelRequest = deferred() clientMock.cancel.mockReturnValue(cancelRequest.promise) @@ -1453,13 +1250,8 @@ describe('WebsiteCrawlPreview', () => { await screen.findByRole('alert') await user.click(screen.getByRole('button', { name: 'dataset.newKnowledge.cancelAddSource' })) - await user.click( - screen.getByRole('button', { name: 'dataset.newKnowledge.discardSourceChangesConfirm' }), - ) - expect(within(screen.getByRole('alertdialog')).getByRole('alert')).toHaveTextContent( - 'dataset.newKnowledge.crawlFailedDescription', - ) + expect(screen.getByText('dataset.newKnowledge.crawlFailedDescription')).toBeInTheDocument() expect(routerMock.push).not.toHaveBeenCalled() }) diff --git a/web/features/new-rag/sources/create/components/exit-dialog.tsx b/web/features/new-rag/sources/create/components/exit-dialog.tsx deleted file mode 100644 index cd64cb7079b..00000000000 --- a/web/features/new-rag/sources/create/components/exit-dialog.tsx +++ /dev/null @@ -1,65 +0,0 @@ -'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 ( - { - if (!nextOpen && !discarding) onCancel() - }} - > - - - - {t(($) => $['newKnowledge.discardSourceDraftTitle'])} - - } - className="system-md-regular text-text-secondary" - > - {t(($) => $['newKnowledge.discardSourceDraftDescription'])} - - {error && ( - - {t(($) => $['newKnowledge.discardSourceDraftFailed'])} - - )} - - - - {tCommon(($) => $['operation.cancel'])} - - - {t(($) => $['newKnowledge.discardDraftConfirm'])} - - - - - ) -} diff --git a/web/features/new-rag/sources/create/connected-source-workflow.tsx b/web/features/new-rag/sources/create/connected-source-workflow.tsx index c90f0374d06..9c2fed5ea5f 100644 --- a/web/features/new-rag/sources/create/connected-source-workflow.tsx +++ b/web/features/new-rag/sources/create/connected-source-workflow.tsx @@ -513,7 +513,6 @@ function ResourceConfiguration({ knowledgeSpaceId, onCompleted, onDraftChange, - onDirtyChange, onExit, parameters, provider, @@ -524,7 +523,6 @@ function ResourceConfiguration({ knowledgeSpaceId: string onCompleted: () => void onDraftChange: (draft: NewKnowledgeSourceDraft) => void - onDirtyChange: (dirty: boolean) => void onExit: () => void parameters: DatasourceParameters provider: SourceProvider @@ -570,10 +568,6 @@ function ResourceConfiguration({ [], ) - useEffect(() => { - onDirtyChange(selected.size > 0) - }, [onDirtyChange, selected.size]) - useEffect(() => { let active = true let source: Source | undefined @@ -1165,7 +1159,6 @@ function ResourceConfiguration({ setSubmitError(false) const completeSubmission = async () => { committedRef.current = true - onDirtyChange(false) await Promise.all([ queryClient.invalidateQueries({ queryKey: consoleQuery.knowledgeFs.spaces.byControlSpaceId.sources.get.key(), @@ -1431,7 +1424,6 @@ function AppliedResourceConfiguration({ knowledgeSpaceId, onCompleted, onDraftChange, - onDirtyChange, onExit, parameters, parametersValid, @@ -1444,7 +1436,6 @@ function AppliedResourceConfiguration({ knowledgeSpaceId: string onCompleted: () => void onDraftChange: (draft: NewKnowledgeSourceDraft) => void - onDirtyChange: (dirty: boolean) => void onExit: () => void parameters: DatasourceParameters parametersValid: boolean @@ -1492,7 +1483,6 @@ function AppliedResourceConfiguration({ knowledgeSpaceId={knowledgeSpaceId} onCompleted={onCompleted} onDraftChange={onDraftChange} - onDirtyChange={onDirtyChange} onExit={onExit} parameters={appliedParameters} provider={provider} @@ -1508,14 +1498,12 @@ export function ConnectedSourceWorkflow({ knowledgeSpaceId, onCompleted, onDraftChange, - onDirtyChange, onExit, }: { draft: ConnectedSourceDraft knowledgeSpaceId: string onCompleted: () => void onDraftChange: (draft: NewKnowledgeSourceDraft) => void - onDirtyChange: (dirty: boolean) => void onExit: () => void }) { const { t } = useTranslation('dataset') @@ -1822,7 +1810,6 @@ export function ConnectedSourceWorkflow({ knowledgeSpaceId={knowledgeSpaceId} onCompleted={onCompleted} onDraftChange={onDraftChange} - onDirtyChange={onDirtyChange} onExit={onExit} parameters={parameters} parametersValid={parametersValid} diff --git a/web/features/new-rag/sources/create/page.tsx b/web/features/new-rag/sources/create/page.tsx index 03ca10fcf54..ac280a511ed 100644 --- a/web/features/new-rag/sources/create/page.tsx +++ b/web/features/new-rag/sources/create/page.tsx @@ -61,7 +61,6 @@ import { sourceConnectionListFromApi, sourceProviderListFromApi, } from '../source-models' -import { AddSourceExitDialog } from './components/exit-dialog' import { ConnectedSourceWorkflow } from './connected-source-workflow' import { WebsiteCrawlPreview } from './website-crawl-preview' @@ -259,7 +258,6 @@ function ConnectionForm({ datasourceProvider, knowledgeSpaceId, onConnected, - onDraftChange, onReconcile, provider, providerName, @@ -268,7 +266,6 @@ function ConnectionForm({ datasourceProvider: WebsiteDatasourceProvider knowledgeSpaceId: string onConnected: (connection: Connection) => void - onDraftChange: (dirty: boolean) => void onReconcile: () => Promise provider: Provider providerName: string @@ -287,16 +284,6 @@ function ConnectionForm({ const visibleFields = configurableFields.filter( (field) => authKind === 'api-key' || (!field.secret && field.format === 'uri'), ) - const hasDraftChanges = - authKind !== (supportedAuthKinds[0] ?? 'api-key') || - Object.values(configuration).some((value) => Boolean(value.trim())) || - Object.values(credentials).some((value) => Boolean(value.trim())) - - useEffect(() => { - onDraftChange(hasDraftChanges) - return () => onDraftChange(false) - }, [hasDraftChanges, onDraftChange]) - const changeAuthKind = (nextAuthKind: ConnectionAuthKind) => { if (nextAuthKind !== authKind) setCredentials({}) setAuthKind(nextAuthKind) @@ -351,7 +338,6 @@ function ConnectionForm({ }), ) setCredentials({}) - onDraftChange(false) onConnected(createdConnection) } catch { setCredentials({}) @@ -534,7 +520,6 @@ function UnconfiguredProvider({ knowledgeSpaceId, onConnected, onConfigureManagedProvider, - onDraftChange, onReconcile, provider, providerOption, @@ -545,7 +530,6 @@ function UnconfiguredProvider({ knowledgeSpaceId: string onConnected: (connection: Connection) => void onConfigureManagedProvider: () => void - onDraftChange: (dirty: boolean) => void onReconcile: () => Promise provider: Provider providerOption: InstalledSourceProviderOption @@ -575,7 +559,6 @@ function UnconfiguredProvider({ datasourceProvider={datasourceProvider} knowledgeSpaceId={knowledgeSpaceId} onConnected={onConnected} - onDraftChange={onDraftChange} onReconcile={onReconcile} provider={provider} providerName={providerName} @@ -775,25 +758,8 @@ function AddSourcePageContent({ ), ) const [sourceDraft, setSourceDraft] = useState(initialDraftRef.current) - const sourceDraftBaselineRef = useRef( - JSON.stringify( - initialSourceProvider && !initialSourceDraft - ? initialDraftRef.current - : createNewKnowledgeSourceDraft(initialDraftRef.current.sourceType), - ), - ) const [sourceDraftResolved, setSourceDraftResolved] = useState(!sourceDraftKey) - const [connectionDraftDirty, setConnectionDraftDirty] = useState(false) - const [exitOpen, setExitOpen] = useState(false) - const [discarding, setDiscarding] = useState(false) - const [discardError, setDiscardError] = useState(false) const [websiteSetupLocked, setWebsiteSetupLocked] = useState(false) - const [historyGuardReleaseVersion, setHistoryGuardReleaseVersion] = useState(0) - const historyGuardArmedRef = useRef(false) - const historyGuardReleaseRef = useRef(false) - const browserBackExitRef = useRef(false) - const pendingNavigationRef = useRef(undefined) - const exitDestinationRef = useRef(newKnowledgeDetailPath(knowledgeSpaceId)) const sourceDraftsRef = useRef< Partial> >({ [sourceDraft.sourceType]: sourceDraft }) @@ -1039,168 +1005,10 @@ function AddSourcePageContent({ supportsDirectConnection && activeConnection, ) - const websitePreviewReady = - sourceDraftResolved && - websiteReady && - !historyGuardArmedRef.current && - !historyGuardReleaseRef.current - const hasUnsavedChanges = - sourceDraftResolved && - !websiteReady && - (connectionDraftDirty || JSON.stringify(sourceDraft) !== sourceDraftBaselineRef.current) - 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 - } - clearStoredSourceDraft() - replaceAfterHistoryGuard(path) - }, - [clearStoredSourceDraft, 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 - if (historyGuardReleaseRef.current) { - historyGuardReleaseRef.current = false - setHistoryGuardReleaseVersion((version) => version + 1) - return - } - const pendingNavigation = pendingNavigationRef.current - if (pendingNavigation) { - pendingNavigationRef.current = undefined - router.replace(pendingNavigation) - return - } - if (!hasUnsavedChanges) { - clearStoredSourceDraft() - router.replace(detailPath) - return - } - browserBackExitRef.current = true - exitDestinationRef.current = detailPath - setDiscardError(false) - setExitOpen(true) - } - - globalThis.addEventListener('popstate', handlePopState) - return () => globalThis.removeEventListener('popstate', handlePopState) - }, [clearStoredSourceDraft, detailPath, hasUnsavedChanges, router]) - - useEffect(() => { - if ( - !websiteReady || - !historyGuardArmedRef.current || - historyGuardReleaseRef.current || - pendingNavigationRef.current - ) - return - historyGuardReleaseRef.current = true - globalThis.history.back() - }, [websiteReady]) - - 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 requestExit = () => requestNavigation(detailPath) - const cancelExit = () => { - setExitOpen(false) - setDiscardError(false) - if (!browserBackExitRef.current) return - browserBackExitRef.current = false - armHistoryGuard() - } - const confirmExit = () => { - if (discarding) return - setDiscarding(true) - setDiscardError(false) - try { - clearStoredSourceDraft() - sourceDraftBaselineRef.current = JSON.stringify(sourceDraft) - setConnectionDraftDirty(false) - setExitOpen(false) - browserBackExitRef.current = false - const destination = exitDestinationRef.current - exitDestinationRef.current = detailPath - replaceAfterHistoryGuard(destination) - } catch { - setDiscardError(true) - } finally { - setDiscarding(false) - } + const websitePreviewReady = sourceDraftResolved && websiteReady + const requestExit = () => { + clearStoredSourceDraft() + router.replace(detailPath) } if ( @@ -1308,7 +1116,7 @@ function AddSourcePageContent({ ) : activeConnection && websitePreviewReady ? ( { clearStoredSourceDraft() - sourceDraftBaselineRef.current = JSON.stringify(sourceDraft) - setConnectionDraftDirty(false) - replaceAfterHistoryGuard(detailPath) + router.replace(detailPath) }} onDraftChange={(draft) => { updateSourceDraft(draft) }} - onDirtyChange={setConnectionDraftDirty} onExit={requestExit} /> )} @@ -1409,13 +1213,6 @@ function AddSourcePageContent({ )} - > ) } diff --git a/web/features/new-rag/sources/create/website-crawl-preview.tsx b/web/features/new-rag/sources/create/website-crawl-preview.tsx index 39d6959eefa..2ce419f362b 100644 --- a/web/features/new-rag/sources/create/website-crawl-preview.tsx +++ b/web/features/new-rag/sources/create/website-crawl-preview.tsx @@ -6,15 +6,6 @@ import type { InstalledSourceProviderOption } from '../setup/provider-options' import type { NewKnowledgeWebsiteSourceDraft } from '../setup/source-draft' import type { SyncPolicyValue } from '../setup/sync-policy-field' import type { CrawlPreviewPage as PreviewPage, Source, SourceWorkflowRun } from '../source-models' -import { - AlertDialog, - AlertDialogActions, - AlertDialogCancelButton, - AlertDialogConfirmButton, - AlertDialogContent, - AlertDialogDescription, - AlertDialogTitle, -} from '@langgenius/dify-ui/alert-dialog' import { Button } from '@langgenius/dify-ui/button' import { Checkbox } from '@langgenius/dify-ui/checkbox' import { cn } from '@langgenius/dify-ui/cn' @@ -31,7 +22,6 @@ import { newKnowledgeDetailPath } from '../../routes' import { WebsiteDatasourceParameterForm } from '../setup/datasource-parameter-form' import { datasourceIncludeSubpages, - datasourceParameterDefaults, invalidDatasourceParameters, missingRequiredDatasourceParameters, websiteDatasourceParameterSchemas, @@ -76,8 +66,6 @@ type PreviewDraft = { source?: Source } -type PendingNavigation = { type: 'back' } | { href: string; type: 'push' } - function previewPagesEqual(left: PreviewPage, right: PreviewPage) { return ( left.pageId === right.pageId && @@ -459,10 +447,6 @@ export function WebsiteCrawlPreview({ : websiteDatasourceParameterSchemas(), [providerOption], ) - const defaultParameters = useMemo( - () => datasourceParameterDefaults(parameterSchemas), - [parameterSchemas], - ) const [parameters, setParameters] = useState(() => { const initialParameters = withDatasourceParameterDefaults( parameterSchemas, @@ -485,7 +469,6 @@ export function WebsiteCrawlPreview({ return initialParameters }) const [sourceName, setSourceName] = useState(initialDraft?.sourceName ?? '') - const initialSyncPolicyRef = useRef(initialSyncPolicyValue(initialDraft)) const syncPolicy = initialSyncPolicyValue(initialDraft) const [run, setRun] = useState() const [pages, setPages] = useState([]) @@ -495,7 +478,6 @@ export function WebsiteCrawlPreview({ const [stopping, setStopping] = useState(false) const [pollPaused, setPollPaused] = useState(false) const [requestError, setRequestError] = useState() - const [cancelConfirmationOpen, setCancelConfirmationOpen] = useState(false) const [discarding, setDiscarding] = useState(false) const [discardError, setDiscardError] = useState(false) const [workflowUncertain, setWorkflowUncertain] = useState(false) @@ -521,9 +503,6 @@ export function WebsiteCrawlPreview({ const uncertainWorkflowRef = useRef<(() => Promise) | undefined>( undefined, ) - const pendingNavigationRef = useRef(undefined) - const historyGuardRef = useRef(undefined) - const historyGuardCompletionRef = useRef<(() => void) | undefined>(undefined) const deletePreviewDraftSource = useCallback( async (draft: PreviewDraft) => { @@ -655,12 +634,6 @@ export function WebsiteCrawlPreview({ ) const runId = run?.id const locked = starting || stopping || active || uncertainOperation || selectionInteractionLocked - const dirty = Boolean( - sourceName || - run || - JSON.stringify(parameters) !== JSON.stringify(defaultParameters) || - JSON.stringify(syncPolicy) !== JSON.stringify(initialSyncPolicyRef.current), - ) const host = normalizedURL?.host ?? providerName const completedCount = Math.max(run?.progressCompleted ?? 0, pages.length) const crawlingStatusText = t(($) => $['newKnowledge.crawlingPages'], { @@ -704,110 +677,6 @@ export function WebsiteCrawlPreview({ }) }, []) - useEffect(() => { - if (!dirty) return - const preventUnsavedUnload = (event: BeforeUnloadEvent) => { - if (submittedRef.current) return - event.preventDefault() - event.returnValue = '' - } - window.addEventListener('beforeunload', preventUnsavedUnload) - return () => window.removeEventListener('beforeunload', preventUnsavedUnload) - }, [dirty]) - - useEffect(() => { - if ((!dirty && !historyGuardRef.current) || submittedRef.current) return - const guardId = historyGuardRef.current ?? createRequestId() - const currentState = - window.history.state && typeof window.history.state === 'object' ? window.history.state : {} - if (!historyGuardRef.current) { - window.history.pushState( - { ...currentState, difyUnsavedSourceGuard: guardId }, - '', - location.href, - ) - historyGuardRef.current = guardId - } - - const handlePopState = () => { - if (submittedRef.current) { - historyGuardRef.current = undefined - const complete = historyGuardCompletionRef.current - historyGuardCompletionRef.current = undefined - complete?.() - return - } - if (!dirty) { - window.removeEventListener('popstate', handlePopState) - historyGuardRef.current = undefined - window.history.back() - return - } - window.history.pushState( - { ...currentState, difyUnsavedSourceGuard: guardId }, - '', - location.href, - ) - pendingNavigationRef.current = { type: 'back' } - setDiscardError(false) - setCancelConfirmationOpen(true) - } - const handleLinkClick = (event: MouseEvent) => { - if ( - event.defaultPrevented || - event.button !== 0 || - event.metaKey || - event.ctrlKey || - event.shiftKey || - event.altKey - ) - return - const target = event.target - if (!(target instanceof Element)) return - const anchor = target.closest('a[href]') - if ( - !(anchor instanceof HTMLAnchorElement) || - anchor.target === '_blank' || - anchor.hasAttribute('download') - ) - return - const destination = new URL(anchor.href, location.href) - if (destination.origin !== location.origin || destination.href === location.href) return - event.preventDefault() - event.stopPropagation() - if (!dirty) { - submittedRef.current = true - onDraftFinished?.() - historyGuardCompletionRef.current = () => - router.push(`${destination.pathname}${destination.search}${destination.hash}`) - window.history.back() - return - } - pendingNavigationRef.current = { - href: `${destination.pathname}${destination.search}${destination.hash}`, - type: 'push', - } - setDiscardError(false) - setCancelConfirmationOpen(true) - } - - window.addEventListener('popstate', handlePopState) - document.addEventListener('click', handleLinkClick, true) - return () => { - window.removeEventListener('popstate', handlePopState) - document.removeEventListener('click', handleLinkClick, true) - } - }, [dirty, onDraftFinished, router]) - - const leaveHistoryGuard = useCallback((complete: () => void) => { - if (!historyGuardRef.current) { - complete() - return - } - historyGuardCompletionRef.current = complete - window.history.back() - }, []) - const ensureProvisionalSource = useCallback( async (nextConfiguration: CrawlConfiguration) => { const nextConfigurationKey = configurationKey(nextConfiguration) @@ -1253,18 +1122,6 @@ export function WebsiteCrawlPreview({ (run ? ['timed_out', 'timeout'].includes(normalizedState(run.state)) : false) const isProviderError = errorCode?.toUpperCase().includes('PROVIDER') - const cancel = () => { - if (dirty) { - pendingNavigationRef.current = undefined - setDiscardError(false) - setCancelConfirmationOpen(true) - return - } - submittedRef.current = true - onDraftFinished?.() - leaveHistoryGuard(() => router.push(newKnowledgeDetailPath(knowledgeSpaceId))) - } - const discardAndCancel = async () => { if (discarding) return setDiscarding(true) @@ -1314,28 +1171,10 @@ export function WebsiteCrawlPreview({ retryPredecessorRef.current = undefined submittedRef.current = true onDraftFinished?.() - setCancelConfirmationOpen(false) - const pendingNavigation = pendingNavigationRef.current - pendingNavigationRef.current = undefined - leaveHistoryGuard(() => { - if (pendingNavigation?.type === 'back') window.history.back() - else - router.push( - pendingNavigation?.type === 'push' - ? pendingNavigation.href - : newKnowledgeDetailPath(knowledgeSpaceId), - ) - }) + router.push(newKnowledgeDetailPath(knowledgeSpaceId)) } - const handleCancelConfirmationOpenChange = (open: boolean) => { - if (discarding) return - setCancelConfirmationOpen(open) - if (!open) { - pendingNavigationRef.current = undefined - setDiscardError(false) - } - } + const cancel = () => void discardAndCancel() return ( $['newKnowledge.crawlAndPreview'])}> @@ -1439,7 +1278,7 @@ export function WebsiteCrawlPreview({ )} {showSuccess && run && draftRef.current?.source && configuration && ( discardRequestedRef.current} initialSyncMode={ initialDraft?.syncPolicy === 'daily' ? 'interval' : initialDraft?.syncPolicy @@ -1450,14 +1289,10 @@ export function WebsiteCrawlPreview({ onInteractionLockChange={setSelectionInteractionLocked} onRecrawl={handlePrimaryAction} onSubmissionUncertainChange={updateSelectionUncertain} - onSubmitted={() => - new Promise((resolve) => { - pendingNavigationRef.current = undefined - submittedRef.current = true - onDraftFinished?.() - leaveHistoryGuard(resolve) - }) - } + onSubmitted={() => { + submittedRef.current = true + onDraftFinished?.() + }} onWorkflowPending={trackPendingWorkflow} onWorkflowRun={(nextRun) => { pendingCancelRunRef.current = nextRun @@ -1531,7 +1366,7 @@ export function WebsiteCrawlPreview({ {!showSuccess && syncPolicyField && {syncPolicyField}} {!showSuccess && ( - + {t(($) => $['newKnowledge.cancelAddSource'])} @@ -1542,35 +1377,11 @@ export function WebsiteCrawlPreview({ )} - - - - - {t(($) => $['newKnowledge.discardSourceChanges'])} - - - {t(($) => $['newKnowledge.discardSourceChangesDescription'])} - - {discardError && ( - - {t(($) => $['newKnowledge.crawlFailedDescription'])} - - )} - - - - {t(($) => $['newKnowledge.keepEditing'])} - - void discardAndCancel()} - > - {t(($) => $['newKnowledge.discardSourceChangesConfirm'])} - - - - + {discardError && requestError !== 'CANCEL_FAILED' && ( + + {t(($) => $['newKnowledge.crawlFailedDescription'])} + + )} ) } diff --git a/web/i18n/ar-TN/dataset.json b/web/i18n/ar-TN/dataset.json index be445d7fefc..6dc634153b9 100644 --- a/web/i18n/ar-TN/dataset.json +++ b/web/i18n/ar-TN/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "لم نتمكن من تحميل قاعدة المعرفة هذه. حاول ثانية.", "newKnowledge.detailErrorTitle": "حدث خطأ ما", "newKnowledge.disableSource": "تعطيل", - "newKnowledge.discardDraftConfirm": "تجاهل المسودة", - "newKnowledge.discardDraftDescription": "ستُفقد تغييراتك على مسودة قاعدة المعرفة هذه.", - "newKnowledge.discardDraftTitle": "تجاهل مسودة قاعدة المعرفة هذه؟", - "newKnowledge.discardSourceChanges": "هل تريد تجاهل تغييرات المصدر؟", - "newKnowledge.discardSourceChangesConfirm": "تجاهل التغييرات", - "newKnowledge.discardSourceChangesDescription": "ستفقد معاينة الزحف وتحديد الصفحات وإعدادات المزامنة.", - "newKnowledge.discardSourceDraftDescription": "ستتم إزالة إعداد المصدر ومعاينة الزحف.", - "newKnowledge.discardSourceDraftFailed": "تعذّر تجاهل مسودة المصدر. أعد المحاولة.", - "newKnowledge.discardSourceDraftTitle": "هل تريد تجاهل مسودة المصدر هذه؟", "newKnowledge.documentActions": "إجراءات {{name}}", "newKnowledge.documentActionsUnavailable": "إجراءات المستند غير متاحة لقاعدة المعرفة هذه حتى الآن.", "newKnowledge.documentChunksEmpty": "لا توجد مقاطع متاحة لهذه المراجعة بعد.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "إيقاف", "newKnowledge.invalidDatasourceParameter": "أدخل قيمة صالحة لـ {{parameter}}.", "newKnowledge.invalidRootUrl": "أدخل عنوان URL صالحًا يبدأ بـ http(s).", - "newKnowledge.keepEditing": "متابعة التحرير", "newKnowledge.lastIndexed": "آخر فهرسة", "newKnowledge.lastReadyRevisionHint": "لا تؤدي المعالجة الفاشلة إلى مقاطعة الاسترداد مطلقًا، حيث تظل آخر مراجعة جاهزة متاحة في فهرس المحتوى.", "newKnowledge.lastSyncColumn": "آخر مزامنة", "newKnowledge.learnMore": "معرفة المزيد", - "newKnowledge.leavePartialSetupConfirm": "مغادرة الإعداد", - "newKnowledge.leavePartialSetupDescription": "تم إنشاء قاعدة المعرفة، لكن تعذّر تأكيد أذوناتها. عند المغادرة سيتم الاحتفاظ بقاعدة المعرفة؛ يمكنك مراجعة الوصول لاحقًا.", - "newKnowledge.leavePartialSetupTitle": "مغادرة الإعداد غير المكتمل؟", "newKnowledge.legacy": "قديم", "newKnowledge.loadMore": "تحميل المزيد", "newKnowledge.loadMoreRevisions": "تحميل مراجعات أقدم", diff --git a/web/i18n/de-DE/dataset.json b/web/i18n/de-DE/dataset.json index 72b6c749a94..1cc3efb6134 100644 --- a/web/i18n/de-DE/dataset.json +++ b/web/i18n/de-DE/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Diese Wissensdatenbank konnte nicht geladen werden. Versuchen Sie es erneut.", "newKnowledge.detailErrorTitle": "Etwas ist schief gelaufen", "newKnowledge.disableSource": "Deaktivieren", - "newKnowledge.discardDraftConfirm": "Entwurf verwerfen", - "newKnowledge.discardDraftDescription": "Ihre Änderungen an diesem Wissensdatenbank-Entwurf gehen verloren.", - "newKnowledge.discardDraftTitle": "Diesen Wissensdatenbank-Entwurf verwerfen?", - "newKnowledge.discardSourceChanges": "Änderungen an der Quelle verwerfen?", - "newKnowledge.discardSourceChangesConfirm": "Änderungen verwerfen", - "newKnowledge.discardSourceChangesDescription": "Crawl-Vorschau, Seitenauswahl und Synchronisierungseinstellungen gehen verloren.", - "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.documentActions": "Aktionen für {{name}}", "newKnowledge.documentActionsUnavailable": "Für diese Wissensdatenbank sind noch keine Dokumentaktionen verfügbar.", "newKnowledge.documentChunksEmpty": "Für diese Revision sind noch keine Abschnitte verfügbar.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Unterbrechen", "newKnowledge.invalidDatasourceParameter": "Gib einen gültigen Wert für {{parameter}} ein.", "newKnowledge.invalidRootUrl": "Gib eine gültige http(s)-URL ein.", - "newKnowledge.keepEditing": "Weiter bearbeiten", "newKnowledge.lastIndexed": "Zuletzt indexiert", "newKnowledge.lastReadyRevisionHint": "Eine fehlgeschlagene Verarbeitung unterbricht nie den Abruf – die letzte fertige Revision bleibt im Inhaltsindex verfügbar.", "newKnowledge.lastSyncColumn": "Letzte Synchronisierung", "newKnowledge.learnMore": "Mehr erfahren", - "newKnowledge.leavePartialSetupConfirm": "Einrichtung verlassen", - "newKnowledge.leavePartialSetupDescription": "Die Wissensdatenbank wurde erstellt, aber ihre Berechtigung konnte nicht bestätigt werden. Beim Verlassen bleibt die Wissensdatenbank erhalten; Sie können den Zugriff später überprüfen.", - "newKnowledge.leavePartialSetupTitle": "Unvollständige Einrichtung verlassen?", "newKnowledge.legacy": "Legacy", "newKnowledge.loadMore": "Mehr laden", "newKnowledge.loadMoreRevisions": "Ältere Revisionen laden", diff --git a/web/i18n/en-US/dataset.json b/web/i18n/en-US/dataset.json index 939e3e9bd2b..6cdb6cd5f5b 100644 --- a/web/i18n/en-US/dataset.json +++ b/web/i18n/en-US/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "We couldn't load this knowledge base. Try again.", "newKnowledge.detailErrorTitle": "Something went wrong", "newKnowledge.disableSource": "Disable", - "newKnowledge.discardDraftConfirm": "Discard draft", - "newKnowledge.discardDraftDescription": "Your changes to this knowledge base draft will be lost.", - "newKnowledge.discardDraftTitle": "Discard this knowledge base draft?", - "newKnowledge.discardSourceChanges": "Discard source changes?", - "newKnowledge.discardSourceChangesConfirm": "Discard changes", - "newKnowledge.discardSourceChangesDescription": "Your crawl preview, page selection, and sync settings will be lost.", - "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.documentActions": "Actions for {{name}}", "newKnowledge.documentActionsUnavailable": "Document actions aren't available for this knowledge base yet.", "newKnowledge.documentChunksEmpty": "No chunks are available for this revision yet.", @@ -301,14 +292,10 @@ "newKnowledge.interruptTask": "Interrupt", "newKnowledge.invalidDatasourceParameter": "Enter a valid value for {{parameter}}.", "newKnowledge.invalidRootUrl": "Enter a valid http(s) URL.", - "newKnowledge.keepEditing": "Keep editing", "newKnowledge.lastIndexed": "Last indexed", "newKnowledge.lastReadyRevisionHint": "Failed processing never interrupts retrieval — the last ready revision stays available in the content index.", "newKnowledge.lastSyncColumn": "Last sync", "newKnowledge.learnMore": "Learn more", - "newKnowledge.leavePartialSetupConfirm": "Leave setup", - "newKnowledge.leavePartialSetupDescription": "The knowledge base was created, but its permission could not be confirmed. Leaving keeps the knowledge base; you can review access later.", - "newKnowledge.leavePartialSetupTitle": "Leave incomplete setup?", "newKnowledge.legacy": "Legacy", "newKnowledge.loadMore": "Load more", "newKnowledge.loadMoreRevisions": "Load older revisions", diff --git a/web/i18n/es-ES/dataset.json b/web/i18n/es-ES/dataset.json index a38255ed732..210d81b170b 100644 --- a/web/i18n/es-ES/dataset.json +++ b/web/i18n/es-ES/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "No pudimos cargar esta base de conocimientos. Intentar otra vez.", "newKnowledge.detailErrorTitle": "algo salió mal", "newKnowledge.disableSource": "Desactivar", - "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.discardSourceChanges": "¿Descartar los cambios de la fuente?", - "newKnowledge.discardSourceChangesConfirm": "Descartar cambios", - "newKnowledge.discardSourceChangesDescription": "Se perderán la vista previa del rastreo, la selección de páginas y la configuración de sincronización.", - "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.documentActions": "Acciones para {{name}}", "newKnowledge.documentActionsUnavailable": "Las acciones de documentos aún no están disponibles para esta base de conocimientos.", "newKnowledge.documentChunksEmpty": "Aún no hay fragmentos disponibles para esta revisión.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Interrumpir", "newKnowledge.invalidDatasourceParameter": "Introduce un valor válido para {{parameter}}.", "newKnowledge.invalidRootUrl": "Introduce una URL http(s) válida.", - "newKnowledge.keepEditing": "Seguir editando", "newKnowledge.lastIndexed": "Última indexación", "newKnowledge.lastReadyRevisionHint": "El procesamiento fallido nunca interrumpe la recuperación: la última revisión lista permanece disponible en el índice de contenido.", "newKnowledge.lastSyncColumn": "Última sincronización", "newKnowledge.learnMore": "Más información", - "newKnowledge.leavePartialSetupConfirm": "Salir de la configuración", - "newKnowledge.leavePartialSetupDescription": "La base de conocimientos se creó, pero no se pudo confirmar su permiso. Si sales, la base de conocimientos se conservará; puedes revisar el acceso más adelante.", - "newKnowledge.leavePartialSetupTitle": "¿Salir de la configuración incompleta?", "newKnowledge.legacy": "Anterior", "newKnowledge.loadMore": "Cargar más", "newKnowledge.loadMoreRevisions": "Cargar revisiones anteriores", diff --git a/web/i18n/fa-IR/dataset.json b/web/i18n/fa-IR/dataset.json index 5aed05a345c..8a683870a3a 100644 --- a/web/i18n/fa-IR/dataset.json +++ b/web/i18n/fa-IR/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "ما نتوانستیم این پایگاه دانش را بارگیری کنیم. دوباره امتحان کنید.", "newKnowledge.detailErrorTitle": "مشکلی پیش آمد", "newKnowledge.disableSource": "غیر فعال کردن", - "newKnowledge.discardDraftConfirm": "حذف پیشنویس", - "newKnowledge.discardDraftDescription": "تغییرات شما در این پیشنویس پایگاه دانش از بین خواهد رفت.", - "newKnowledge.discardDraftTitle": "این پیشنویس پایگاه دانش حذف شود؟", - "newKnowledge.discardSourceChanges": "تغییرات منبع کنار گذاشته شود؟", - "newKnowledge.discardSourceChangesConfirm": "کنار گذاشتن تغییرات", - "newKnowledge.discardSourceChangesDescription": "پیشنمایش خزش، انتخاب صفحهها و تنظیمات همگامسازی از دست میروند.", - "newKnowledge.discardSourceDraftDescription": "پیکربندی منبع و پیشنمایش پیمایش حذف خواهند شد.", - "newKnowledge.discardSourceDraftFailed": "حذف پیشنویس منبع ممکن نشد. دوباره تلاش کنید.", - "newKnowledge.discardSourceDraftTitle": "این پیشنویس منبع حذف شود؟", "newKnowledge.documentActions": "اقدامات برای {{name}}", "newKnowledge.documentActionsUnavailable": "اقدامات سند هنوز برای این پایگاه دانش در دسترس نیست.", "newKnowledge.documentChunksEmpty": "هنوز قطعهای برای این بازبینی موجود نیست.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "توقف", "newKnowledge.invalidDatasourceParameter": "یک مقدار معتبر برای {{parameter}} وارد کنید.", "newKnowledge.invalidRootUrl": "یک نشانی معتبر http(s) وارد کنید.", - "newKnowledge.keepEditing": "ادامه ویرایش", "newKnowledge.lastIndexed": "آخرین نمایهسازی", "newKnowledge.lastReadyRevisionHint": "پردازش ناموفق هرگز بازیابی را قطع نمی کند - آخرین نسخه آماده در فهرست محتوا در دسترس باقی می ماند.", "newKnowledge.lastSyncColumn": "آخرین همگام سازی", "newKnowledge.learnMore": "بیشتر بدانید", - "newKnowledge.leavePartialSetupConfirm": "خروج از راهاندازی", - "newKnowledge.leavePartialSetupDescription": "پایگاه دانش ایجاد شد، اما مجوز آن تأیید نشد. با خروج، پایگاه دانش حفظ میشود؛ میتوانید بعداً دسترسی را بررسی کنید.", - "newKnowledge.leavePartialSetupTitle": "از راهاندازی ناتمام خارج میشوید؟", "newKnowledge.legacy": "قدیمی", "newKnowledge.loadMore": "بارگذاری بیشتر", "newKnowledge.loadMoreRevisions": "بارگیری بازبینیهای قدیمیتر", diff --git a/web/i18n/fr-FR/dataset.json b/web/i18n/fr-FR/dataset.json index d492d511a88..83c47d1680b 100644 --- a/web/i18n/fr-FR/dataset.json +++ b/web/i18n/fr-FR/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Nous n'avons pas pu charger cette base de connaissances. Essayer à nouveau.", "newKnowledge.detailErrorTitle": "Quelque chose s'est mal passé", "newKnowledge.disableSource": "Désactiver", - "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.discardSourceChanges": "Ignorer les modifications de la source ?", - "newKnowledge.discardSourceChangesConfirm": "Ignorer les modifications", - "newKnowledge.discardSourceChangesDescription": "L’aperçu de l’exploration, la sélection des pages et les paramètres de synchronisation seront perdus.", - "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.documentActions": "Actions pour {{name}}", "newKnowledge.documentActionsUnavailable": "Les actions sur les documents ne sont pas encore disponibles pour cette base de connaissances.", "newKnowledge.documentChunksEmpty": "Aucun segment n’est encore disponible pour cette révision.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Interrompre", "newKnowledge.invalidDatasourceParameter": "Saisissez une valeur valide pour {{parameter}}.", "newKnowledge.invalidRootUrl": "Saisissez une URL http(s) valide.", - "newKnowledge.keepEditing": "Continuer la modification", "newKnowledge.lastIndexed": "Dernière indexation", "newKnowledge.lastReadyRevisionHint": "Un traitement échoué n'interrompt jamais la récupération : la dernière révision prête reste disponible dans l'index de contenu.", "newKnowledge.lastSyncColumn": "Dernière synchronisation", "newKnowledge.learnMore": "En savoir plus", - "newKnowledge.leavePartialSetupConfirm": "Quitter la configuration", - "newKnowledge.leavePartialSetupDescription": "La base de connaissances a été créée, mais son autorisation n’a pas pu être confirmée. Si vous quittez, la base de connaissances sera conservée ; vous pourrez vérifier l’accès plus tard.", - "newKnowledge.leavePartialSetupTitle": "Quitter la configuration incomplète ?", "newKnowledge.legacy": "Ancien", "newKnowledge.loadMore": "Charger plus", "newKnowledge.loadMoreRevisions": "Charger les anciennes révisions", diff --git a/web/i18n/hi-IN/dataset.json b/web/i18n/hi-IN/dataset.json index df0b1e0ef88..49db1b64d5d 100644 --- a/web/i18n/hi-IN/dataset.json +++ b/web/i18n/hi-IN/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "हम इस ज्ञानकोष को लोड नहीं कर सके. पुनः प्रयास करें।", "newKnowledge.detailErrorTitle": "कुछ ग़लत हो गया", "newKnowledge.disableSource": "अक्षम करें", - "newKnowledge.discardDraftConfirm": "ड्राफ़्ट हटाएँ", - "newKnowledge.discardDraftDescription": "इस नॉलेज बेस ड्राफ़्ट में किए गए आपके बदलाव खो जाएँगे।", - "newKnowledge.discardDraftTitle": "क्या यह नॉलेज बेस ड्राफ़्ट हटाना है?", - "newKnowledge.discardSourceChanges": "स्रोत में किए बदलाव छोड़ें?", - "newKnowledge.discardSourceChangesConfirm": "बदलाव छोड़ें", - "newKnowledge.discardSourceChangesDescription": "क्रॉल पूर्वावलोकन, पेज चयन और सिंक सेटिंग खो जाएँगी।", - "newKnowledge.discardSourceDraftDescription": "स्रोत कॉन्फ़िगरेशन और क्रॉल पूर्वावलोकन हटा दिए जाएँगे।", - "newKnowledge.discardSourceDraftFailed": "स्रोत ड्राफ़्ट हटाया नहीं जा सका। फिर से प्रयास करें।", - "newKnowledge.discardSourceDraftTitle": "यह स्रोत ड्राफ़्ट हटाएँ?", "newKnowledge.documentActions": "{{name}} के लिए क्रियाएँ", "newKnowledge.documentActionsUnavailable": "इस ज्ञानकोष के लिए दस्तावेज़ क्रियाएँ अभी तक उपलब्ध नहीं हैं।", "newKnowledge.documentChunksEmpty": "इस संशोधन के लिए अभी कोई खंड उपलब्ध नहीं है।", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "रोकें", "newKnowledge.invalidDatasourceParameter": "{{parameter}} के लिए मान्य मान दर्ज करें।", "newKnowledge.invalidRootUrl": "मान्य http(s) URL दर्ज करें।", - "newKnowledge.keepEditing": "संपादन जारी रखें", "newKnowledge.lastIndexed": "पिछली बार अनुक्रमित", "newKnowledge.lastReadyRevisionHint": "विफल प्रसंस्करण कभी भी पुनर्प्राप्ति को बाधित नहीं करता है - अंतिम तैयार संशोधन सामग्री सूचकांक में उपलब्ध रहता है।", "newKnowledge.lastSyncColumn": "अंतिम सिंक", "newKnowledge.learnMore": "और जानें", - "newKnowledge.leavePartialSetupConfirm": "सेटअप छोड़ें", - "newKnowledge.leavePartialSetupDescription": "नॉलेज बेस बन गया है, लेकिन उसकी अनुमति की पुष्टि नहीं हो सकी। छोड़ने पर नॉलेज बेस बना रहेगा; आप बाद में एक्सेस की समीक्षा कर सकते हैं।", - "newKnowledge.leavePartialSetupTitle": "क्या अधूरा सेटअप छोड़ना है?", "newKnowledge.legacy": "पुराना", "newKnowledge.loadMore": "और लोड करें", "newKnowledge.loadMoreRevisions": "पुराने संशोधन लोड करें", diff --git a/web/i18n/id-ID/dataset.json b/web/i18n/id-ID/dataset.json index 92f72e35edc..387134f1f01 100644 --- a/web/i18n/id-ID/dataset.json +++ b/web/i18n/id-ID/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Kami tidak dapat memuat basis pengetahuan ini. Coba lagi.", "newKnowledge.detailErrorTitle": "Ada yang tidak beres", "newKnowledge.disableSource": "Nonaktifkan", - "newKnowledge.discardDraftConfirm": "Buang draf", - "newKnowledge.discardDraftDescription": "Perubahan pada draf basis pengetahuan ini akan hilang.", - "newKnowledge.discardDraftTitle": "Buang draf basis pengetahuan ini?", - "newKnowledge.discardSourceChanges": "Buang perubahan sumber?", - "newKnowledge.discardSourceChangesConfirm": "Buang perubahan", - "newKnowledge.discardSourceChangesDescription": "Pratinjau crawl, pilihan halaman, dan pengaturan sinkronisasi akan hilang.", - "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.documentActions": "Tindakan untuk {{name}}", "newKnowledge.documentActionsUnavailable": "Tindakan dokumen belum tersedia untuk basis pengetahuan ini.", "newKnowledge.documentChunksEmpty": "Belum ada potongan yang tersedia untuk revisi ini.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Hentikan", "newKnowledge.invalidDatasourceParameter": "Masukkan nilai yang valid untuk {{parameter}}.", "newKnowledge.invalidRootUrl": "Masukkan URL http(s) yang valid.", - "newKnowledge.keepEditing": "Lanjutkan mengedit", "newKnowledge.lastIndexed": "Terakhir diindeks", "newKnowledge.lastReadyRevisionHint": "Pemrosesan yang gagal tidak pernah mengganggu pengambilan — revisi terakhir yang siap tetap tersedia di indeks konten.", "newKnowledge.lastSyncColumn": "Sinkronisasi terakhir", "newKnowledge.learnMore": "Pelajari lebih lanjut", - "newKnowledge.leavePartialSetupConfirm": "Keluar dari penyiapan", - "newKnowledge.leavePartialSetupDescription": "Basis pengetahuan telah dibuat, tetapi izinnya tidak dapat dikonfirmasi. Jika keluar, basis pengetahuan akan tetap tersimpan; Anda dapat meninjau akses nanti.", - "newKnowledge.leavePartialSetupTitle": "Keluar dari penyiapan yang belum selesai?", "newKnowledge.legacy": "Lama", "newKnowledge.loadMore": "Muat lebih banyak", "newKnowledge.loadMoreRevisions": "Muat revisi lama", diff --git a/web/i18n/it-IT/dataset.json b/web/i18n/it-IT/dataset.json index d6330329a6a..2d4e63848dc 100644 --- a/web/i18n/it-IT/dataset.json +++ b/web/i18n/it-IT/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Impossibile caricare questa knowledge base. Riprova.", "newKnowledge.detailErrorTitle": "Qualcosa è andato storto", "newKnowledge.disableSource": "Disabilita", - "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.discardSourceChanges": "Ignorare le modifiche all’origine?", - "newKnowledge.discardSourceChangesConfirm": "Ignora modifiche", - "newKnowledge.discardSourceChangesDescription": "L’anteprima della scansione, la selezione delle pagine e le impostazioni di sincronizzazione andranno perse.", - "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.documentActions": "Azioni per {{name}}", "newKnowledge.documentActionsUnavailable": "Le azioni del documento non sono ancora disponibili per questa knowledge base.", "newKnowledge.documentChunksEmpty": "Non sono ancora disponibili segmenti per questa revisione.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Interrompere", "newKnowledge.invalidDatasourceParameter": "Inserisci un valore valido per {{parameter}}.", "newKnowledge.invalidRootUrl": "Inserisci un URL http(s) valido.", - "newKnowledge.keepEditing": "Continua a modificare", "newKnowledge.lastIndexed": "Ultima indicizzazione", "newKnowledge.lastReadyRevisionHint": "L'elaborazione non riuscita non interrompe mai il recupero: l'ultima revisione pronta rimane disponibile nell'indice del contenuto.", "newKnowledge.lastSyncColumn": "Ultima sincronizzazione", "newKnowledge.learnMore": "Scopri di più", - "newKnowledge.leavePartialSetupConfirm": "Esci dalla configurazione", - "newKnowledge.leavePartialSetupDescription": "La knowledge base è stata creata, ma non è stato possibile confermarne l’autorizzazione. Uscendo, la knowledge base verrà mantenuta; potrai verificare l’accesso in seguito.", - "newKnowledge.leavePartialSetupTitle": "Uscire dalla configurazione incompleta?", "newKnowledge.legacy": "Legacy", "newKnowledge.loadMore": "Carica altro", "newKnowledge.loadMoreRevisions": "Carica revisioni precedenti", diff --git a/web/i18n/ja-JP/dataset.json b/web/i18n/ja-JP/dataset.json index acf5eb79a4e..583e4996ea8 100644 --- a/web/i18n/ja-JP/dataset.json +++ b/web/i18n/ja-JP/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "このナレッジベースをロードできませんでした。もう一度やり直してください。", "newKnowledge.detailErrorTitle": "何か問題が発生しました", "newKnowledge.disableSource": "無効にする", - "newKnowledge.discardDraftConfirm": "下書きを破棄", - "newKnowledge.discardDraftDescription": "このナレッジベースの下書きに加えた変更は失われます。", - "newKnowledge.discardDraftTitle": "このナレッジベースの下書きを破棄しますか?", - "newKnowledge.discardSourceChanges": "ソースの変更を破棄しますか?", - "newKnowledge.discardSourceChangesConfirm": "変更を破棄", - "newKnowledge.discardSourceChangesDescription": "クロールのプレビュー、ページの選択、同期設定は失われます。", - "newKnowledge.discardSourceDraftDescription": "ソース設定とクロールプレビューは削除されます。", - "newKnowledge.discardSourceDraftFailed": "ソースの下書きを破棄できませんでした。もう一度お試しください。", - "newKnowledge.discardSourceDraftTitle": "このソースの下書きを破棄しますか?", "newKnowledge.documentActions": "{{name}} のアクション", "newKnowledge.documentActionsUnavailable": "ドキュメント アクションは、このナレッジ ベースではまだ利用できません。", "newKnowledge.documentChunksEmpty": "このリビジョンで利用できるチャンクはまだありません。", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "中断", "newKnowledge.invalidDatasourceParameter": "{{parameter}} に有効な値を入力してください。", "newKnowledge.invalidRootUrl": "有効なhttp(s) URLを入力してください。", - "newKnowledge.keepEditing": "編集を続ける", "newKnowledge.lastIndexed": "最終インデックス日時", "newKnowledge.lastReadyRevisionHint": "処理が失敗しても取得が中断されることはありません。準備ができた最後のリビジョンはコンテンツ インデックス内で利用可能なままになります。", "newKnowledge.lastSyncColumn": "最終同期", "newKnowledge.learnMore": "詳細を見る", - "newKnowledge.leavePartialSetupConfirm": "セットアップを終了", - "newKnowledge.leavePartialSetupDescription": "ナレッジベースは作成されましたが、権限を確認できませんでした。終了してもナレッジベースは保持され、アクセス権は後で確認できます。", - "newKnowledge.leavePartialSetupTitle": "未完了のセットアップを終了しますか?", "newKnowledge.legacy": "旧バージョン", "newKnowledge.loadMore": "さらに読み込む", "newKnowledge.loadMoreRevisions": "古いリビジョンを読み込む", diff --git a/web/i18n/ko-KR/dataset.json b/web/i18n/ko-KR/dataset.json index 3382953483c..abd2690c019 100644 --- a/web/i18n/ko-KR/dataset.json +++ b/web/i18n/ko-KR/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "이 기술 자료를 로드할 수 없습니다. 다시 시도해 보세요.", "newKnowledge.detailErrorTitle": "문제가 발생했습니다.", "newKnowledge.disableSource": "비활성화", - "newKnowledge.discardDraftConfirm": "초안 삭제", - "newKnowledge.discardDraftDescription": "이 지식 베이스 초안의 변경 사항이 삭제됩니다.", - "newKnowledge.discardDraftTitle": "이 지식 베이스 초안을 삭제할까요?", - "newKnowledge.discardSourceChanges": "소스 변경 사항을 삭제할까요?", - "newKnowledge.discardSourceChangesConfirm": "변경 사항 삭제", - "newKnowledge.discardSourceChangesDescription": "크롤링 미리보기, 페이지 선택 및 동기화 설정이 사라집니다.", - "newKnowledge.discardSourceDraftDescription": "소스 구성과 크롤링 미리보기가 삭제됩니다.", - "newKnowledge.discardSourceDraftFailed": "소스 초안을 삭제할 수 없습니다. 다시 시도하세요.", - "newKnowledge.discardSourceDraftTitle": "이 소스 초안을 삭제할까요?", "newKnowledge.documentActions": "{{name}}에 대한 작업", "newKnowledge.documentActionsUnavailable": "이 기술 자료에는 아직 문서 작업을 사용할 수 없습니다.", "newKnowledge.documentChunksEmpty": "이 리비전에 사용할 수 있는 청크가 아직 없습니다.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "중단", "newKnowledge.invalidDatasourceParameter": "{{parameter}}에 유효한 값을 입력하세요.", "newKnowledge.invalidRootUrl": "유효한 http(s) URL을 입력하세요.", - "newKnowledge.keepEditing": "계속 편집", "newKnowledge.lastIndexed": "마지막 인덱싱", "newKnowledge.lastReadyRevisionHint": "실패한 처리는 검색을 중단하지 않습니다. 마지막으로 준비된 개정은 콘텐츠 인덱스에서 계속 사용할 수 있습니다.", "newKnowledge.lastSyncColumn": "마지막 동기화", "newKnowledge.learnMore": "자세히 알아보기", - "newKnowledge.leavePartialSetupConfirm": "설정 나가기", - "newKnowledge.leavePartialSetupDescription": "지식 베이스가 생성되었지만 권한을 확인하지 못했습니다. 나가도 지식 베이스는 유지되며 나중에 액세스 권한을 검토할 수 있습니다.", - "newKnowledge.leavePartialSetupTitle": "완료되지 않은 설정을 나갈까요?", "newKnowledge.legacy": "레거시", "newKnowledge.loadMore": "더 보기", "newKnowledge.loadMoreRevisions": "이전 리비전 불러오기", diff --git a/web/i18n/lo-LA/dataset.json b/web/i18n/lo-LA/dataset.json index 2fec6ca034b..32bd9c8bc08 100644 --- a/web/i18n/lo-LA/dataset.json +++ b/web/i18n/lo-LA/dataset.json @@ -205,15 +205,6 @@ "newKnowledge.detailErrorDescription": "ພວກເຮົາບໍ່ສາມາດໂຫຼດຖານຄວາມຮູ້ນີ້ໄດ້. ລອງໃໝ່ອີກຄັ້ງ.", "newKnowledge.detailErrorTitle": "ມີບາງຢ່າງຜິດພາດ", "newKnowledge.disableSource": "ປິດໃຊ້ງານ", - "newKnowledge.discardDraftConfirm": "ຖິ້ມສະບັບຮ່າງ", - "newKnowledge.discardDraftDescription": "ການປ່ຽນແປງຂອງທ່ານໃນສະບັບຮ່າງຖານຄວາມຮູ້ນີ້ຈະສູນຫາຍໄປ.", - "newKnowledge.discardDraftTitle": "ຖິ້ມສະບັບຮ່າງຖານຄວາມຮູ້ນີ້ຫຼືບໍ່?", - "newKnowledge.discardSourceChanges": "ຍົກເລີກການປ່ຽນແປງແຫຼ່ງ?", - "newKnowledge.discardSourceChangesConfirm": "ຍົກເລີກການປ່ຽນແປງ", - "newKnowledge.discardSourceChangesDescription": "ຕົວຢ່າງການລວບລວມຂໍ້ມູນ, ການເລືອກໜ້າ ແລະການຕັ້ງຄ່າການຊິງຄ໌ຂອງທ່ານຈະເສຍໄປ.", - "newKnowledge.discardSourceDraftDescription": "ການກຳນົດຄ່າແຫຼ່ງທີ່ມາ ແລະການສະແດງຕົວຢ່າງການລວບລວມຂໍ້ມູນຈະຖືກລຶບອອກ.", - "newKnowledge.discardSourceDraftFailed": "ພວກເຮົາບໍ່ສາມາດຍົກເລີກສະບັບຮ່າງຕົ້ນສະບັບໄດ້. ລອງອີກຄັ້ງ.", - "newKnowledge.discardSourceDraftTitle": "ຍົກເລີກສະບັບຮ່າງຕົ້ນສະບັບນີ້ບໍ?", "newKnowledge.documentActions": "ຄຳສັ່ງສຳລັບ {{name}}", "newKnowledge.documentActionsUnavailable": "ການດໍາເນີນການເອກະສານແມ່ນຍັງບໍ່ທັນມີໃຫ້ສໍາລັບພື້ນຖານຄວາມຮູ້ນີ້.", "newKnowledge.documentChunksEmpty": "ບໍ່ມີການແກ້ໄຂສໍາລັບການແກ້ໄຂນີ້.", @@ -289,14 +280,10 @@ "newKnowledge.interruptTask": "ຂັດຂວາງ", "newKnowledge.invalidDatasourceParameter": "ປ້ອນຄ່າທີ່ຖືກຕ້ອງສຳລັບ {{parameter}}.", "newKnowledge.invalidRootUrl": "ລະບຸ URL http(s) ທີ່ຖືກຕ້ອງ.", - "newKnowledge.keepEditing": "ສືບຕໍ່ແກ້ໄຂ", "newKnowledge.lastIndexed": "ດັດສະນີຫຼ້າສຸດ", "newKnowledge.lastReadyRevisionHint": "ການປະມວນຜົນທີ່ລົ້ມເຫລວບໍ່ເຄີຍຂັດຂວາງການດຶງຂໍ້ມູນ — ການແກ້ໄຂທີ່ກຽມພ້ອມຫຼ້າສຸດຈະມີຢູ່ໃນດັດຊະນີເນື້ອຫາ.", "newKnowledge.lastSyncColumn": "ຊິງຄ໌ຄັ້ງສຸດທ້າຍ", "newKnowledge.learnMore": "ຮຽນຮູ້ເພີ່ມເຕີມ", - "newKnowledge.leavePartialSetupConfirm": "ອອກຈາກການຕັ້ງຄ່າ", - "newKnowledge.leavePartialSetupDescription": "ຖານຄວາມຮູ້ຖືກສ້າງຂຶ້ນແລ້ວ, ແຕ່ຍັງບໍ່ສາມາດຢືນຢັນສິດອະນຸຍາດໄດ້. ການອອກຈະຍັງຄົງຮັກສາຖານຄວາມຮູ້ໄວ້; ທ່ານສາມາດກວດສອບສິດການເຂົ້າເຖິງພາຍຫຼັງໄດ້.", - "newKnowledge.leavePartialSetupTitle": "ອອກຈາກການຕັ້ງຄ່າທີ່ຍັງບໍ່ສຳເລັດຫຼືບໍ່?", "newKnowledge.legacy": "ແບບເກົ່າ (Legacy)", "newKnowledge.loadMore": "ໂຫຼດເພີ່ມເຕີມ", "newKnowledge.loadMoreRevisions": "ໂຫຼດການດັດແກ້ເກົ່າ", diff --git a/web/i18n/nl-NL/dataset.json b/web/i18n/nl-NL/dataset.json index c48ef53423b..a9e8de2e049 100644 --- a/web/i18n/nl-NL/dataset.json +++ b/web/i18n/nl-NL/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "We kunnen deze kennisbank niet laden. Probeer het opnieuw.", "newKnowledge.detailErrorTitle": "Er is iets misgegaan", "newKnowledge.disableSource": "Uitschakelen", - "newKnowledge.discardDraftConfirm": "Concept verwijderen", - "newKnowledge.discardDraftDescription": "Uw wijzigingen aan dit kennisbankconcept gaan verloren.", - "newKnowledge.discardDraftTitle": "Dit kennisbankconcept verwijderen?", - "newKnowledge.discardSourceChanges": "Wijzigingen aan de bron negeren?", - "newKnowledge.discardSourceChangesConfirm": "Wijzigingen negeren", - "newKnowledge.discardSourceChangesDescription": "De crawlvoorvertoning, paginaselectie en synchronisatie-instellingen gaan verloren.", - "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.documentActions": "Acties voor {{name}}", "newKnowledge.documentActionsUnavailable": "Documentacties zijn nog niet beschikbaar voor deze kennisbank.", "newKnowledge.documentChunksEmpty": "Er zijn nog geen fragmenten beschikbaar voor deze revisie.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Onderbreken", "newKnowledge.invalidDatasourceParameter": "Voer een geldige waarde in voor {{parameter}}.", "newKnowledge.invalidRootUrl": "Voer een geldige http(s)-URL in.", - "newKnowledge.keepEditing": "Doorgaan met bewerken", "newKnowledge.lastIndexed": "Laatst geïndexeerd", "newKnowledge.lastReadyRevisionHint": "Een mislukte verwerking onderbreekt het ophalen nooit; de laatste gereedstaande revisie blijft beschikbaar in de inhoudsindex.", "newKnowledge.lastSyncColumn": "Laatste synchronisatie", "newKnowledge.learnMore": "Meer informatie", - "newKnowledge.leavePartialSetupConfirm": "Configuratie verlaten", - "newKnowledge.leavePartialSetupDescription": "De kennisbank is gemaakt, maar de machtiging kon niet worden bevestigd. Als u vertrekt, blijft de kennisbank behouden; u kunt de toegang later controleren.", - "newKnowledge.leavePartialSetupTitle": "Onvoltooide configuratie verlaten?", "newKnowledge.legacy": "Oud", "newKnowledge.loadMore": "Meer laden", "newKnowledge.loadMoreRevisions": "Oudere revisies laden", diff --git a/web/i18n/pl-PL/dataset.json b/web/i18n/pl-PL/dataset.json index 2bae56bcda4..4182aab5adb 100644 --- a/web/i18n/pl-PL/dataset.json +++ b/web/i18n/pl-PL/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Nie mogliśmy załadować tej bazy wiedzy. Spróbuj ponownie.", "newKnowledge.detailErrorTitle": "Coś poszło nie tak", "newKnowledge.disableSource": "Wyłącz", - "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.discardSourceChanges": "Odrzucić zmiany źródła?", - "newKnowledge.discardSourceChangesConfirm": "Odrzuć zmiany", - "newKnowledge.discardSourceChangesDescription": "Podgląd indeksowania, wybór stron i ustawienia synchronizacji zostaną utracone.", - "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.documentActions": "Działania dla {{name}}", "newKnowledge.documentActionsUnavailable": "Działania dotyczące dokumentów nie są jeszcze dostępne dla tej bazy wiedzy.", "newKnowledge.documentChunksEmpty": "Dla tej wersji nie ma jeszcze dostępnych fragmentów.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Przerwij", "newKnowledge.invalidDatasourceParameter": "Wprowadź prawidłową wartość dla {{parameter}}.", "newKnowledge.invalidRootUrl": "Wprowadź prawidłowy adres URL http(s).", - "newKnowledge.keepEditing": "Kontynuuj edycję", "newKnowledge.lastIndexed": "Ostatnio zindeksowano", "newKnowledge.lastReadyRevisionHint": "Nieudane przetwarzanie nigdy nie przerywa pobierania — ostatnia gotowa wersja pozostaje dostępna w indeksie zawartości.", "newKnowledge.lastSyncColumn": "Ostatnia synchronizacja", "newKnowledge.learnMore": "Dowiedz się więcej", - "newKnowledge.leavePartialSetupConfirm": "Opuść konfigurację", - "newKnowledge.leavePartialSetupDescription": "Baza wiedzy została utworzona, ale nie udało się potwierdzić jej uprawnień. Po opuszczeniu baza wiedzy zostanie zachowana; dostęp można sprawdzić później.", - "newKnowledge.leavePartialSetupTitle": "Opuścić nieukończoną konfigurację?", "newKnowledge.legacy": "Starsza wersja", "newKnowledge.loadMore": "Załaduj więcej", "newKnowledge.loadMoreRevisions": "Wczytaj starsze wersje", diff --git a/web/i18n/pt-BR/dataset.json b/web/i18n/pt-BR/dataset.json index d06f2b4e38f..8a195fa3756 100644 --- a/web/i18n/pt-BR/dataset.json +++ b/web/i18n/pt-BR/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Não foi possível carregar esta base de conhecimento. Tente novamente.", "newKnowledge.detailErrorTitle": "Algo deu errado", "newKnowledge.disableSource": "Desativar", - "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.discardSourceChanges": "Descartar alterações da fonte?", - "newKnowledge.discardSourceChangesConfirm": "Descartar alterações", - "newKnowledge.discardSourceChangesDescription": "A prévia do rastreamento, a seleção de páginas e as configurações de sincronização serão perdidas.", - "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.documentActions": "Ações para {{name}}", "newKnowledge.documentActionsUnavailable": "As ações do documento ainda não estão disponíveis para esta base de conhecimento.", "newKnowledge.documentChunksEmpty": "Ainda não há trechos disponíveis para esta revisão.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Interromper", "newKnowledge.invalidDatasourceParameter": "Insira um valor válido para {{parameter}}.", "newKnowledge.invalidRootUrl": "Insira uma URL http(s) válida.", - "newKnowledge.keepEditing": "Continuar editando", "newKnowledge.lastIndexed": "Última indexação", "newKnowledge.lastReadyRevisionHint": "O processamento com falha nunca interrompe a recuperação — a última revisão pronta permanece disponível no índice de conteúdo.", "newKnowledge.lastSyncColumn": "Última sincronização", "newKnowledge.learnMore": "Saiba mais", - "newKnowledge.leavePartialSetupConfirm": "Sair da configuração", - "newKnowledge.leavePartialSetupDescription": "A base de conhecimento foi criada, mas não foi possível confirmar sua permissão. Ao sair, a base de conhecimento será mantida; você poderá revisar o acesso depois.", - "newKnowledge.leavePartialSetupTitle": "Sair da configuração incompleta?", "newKnowledge.legacy": "Legado", "newKnowledge.loadMore": "Carregar mais", "newKnowledge.loadMoreRevisions": "Carregar revisões anteriores", diff --git a/web/i18n/ro-RO/dataset.json b/web/i18n/ro-RO/dataset.json index 4f6da593b51..e93d1833a84 100644 --- a/web/i18n/ro-RO/dataset.json +++ b/web/i18n/ro-RO/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Nu am putut încărca această bază de cunoștințe. Încearcă din nou.", "newKnowledge.detailErrorTitle": "Ceva a mers prost", "newKnowledge.disableSource": "Dezactivați", - "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.discardSourceChanges": "Renunți la modificările sursei?", - "newKnowledge.discardSourceChangesConfirm": "Renunță la modificări", - "newKnowledge.discardSourceChangesDescription": "Previzualizarea accesării cu crawlere, selectarea paginilor și setările de sincronizare se vor pierde.", - "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.documentActions": "Acțiuni pentru {{name}}", "newKnowledge.documentActionsUnavailable": "Acțiunile documentului nu sunt încă disponibile pentru această bază de cunoștințe.", "newKnowledge.documentChunksEmpty": "Nu există încă fragmente disponibile pentru această revizie.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Întrerupe", "newKnowledge.invalidDatasourceParameter": "Introdu o valoare validă pentru {{parameter}}.", "newKnowledge.invalidRootUrl": "Introdu o adresă URL http(s) validă.", - "newKnowledge.keepEditing": "Continuă editarea", "newKnowledge.lastIndexed": "Ultima indexare", "newKnowledge.lastReadyRevisionHint": "Procesarea eșuată nu întrerupe niciodată recuperarea — ultima revizuire gata rămâne disponibilă în indexul de conținut.", "newKnowledge.lastSyncColumn": "Ultima sincronizare", "newKnowledge.learnMore": "Află mai multe", - "newKnowledge.leavePartialSetupConfirm": "Ieși din configurare", - "newKnowledge.leavePartialSetupDescription": "Baza de cunoștințe a fost creată, dar permisiunea nu a putut fi confirmată. Dacă ieșiți, baza de cunoștințe va fi păstrată; puteți verifica accesul mai târziu.", - "newKnowledge.leavePartialSetupTitle": "Ieșiți din configurarea incompletă?", "newKnowledge.legacy": "Versiune veche", "newKnowledge.loadMore": "Încarcă mai multe", "newKnowledge.loadMoreRevisions": "Încarcă revizii mai vechi", diff --git a/web/i18n/ru-RU/dataset.json b/web/i18n/ru-RU/dataset.json index 568103e7bde..e4d4e39b7b0 100644 --- a/web/i18n/ru-RU/dataset.json +++ b/web/i18n/ru-RU/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Нам не удалось загрузить эту базу знаний. Попробуйте еще раз.", "newKnowledge.detailErrorTitle": "Что-то пошло не так", "newKnowledge.disableSource": "Отключить", - "newKnowledge.discardDraftConfirm": "Удалить черновик", - "newKnowledge.discardDraftDescription": "Изменения в этом черновике базы знаний будут потеряны.", - "newKnowledge.discardDraftTitle": "Удалить этот черновик базы знаний?", - "newKnowledge.discardSourceChanges": "Отменить изменения источника?", - "newKnowledge.discardSourceChangesConfirm": "Отменить изменения", - "newKnowledge.discardSourceChangesDescription": "Предпросмотр сканирования, выбор страниц и настройки синхронизации будут потеряны.", - "newKnowledge.discardSourceDraftDescription": "Конфигурация источника и предварительное сканирование будут удалены.", - "newKnowledge.discardSourceDraftFailed": "Не удалось удалить черновик источника. Повторите попытку.", - "newKnowledge.discardSourceDraftTitle": "Удалить этот черновик источника?", "newKnowledge.documentActions": "Действия для {{name}}", "newKnowledge.documentActionsUnavailable": "Действия с документами пока недоступны для этой базы знаний.", "newKnowledge.documentChunksEmpty": "Для этой редакции пока нет доступных фрагментов.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Прерывание", "newKnowledge.invalidDatasourceParameter": "Введите допустимое значение для {{parameter}}.", "newKnowledge.invalidRootUrl": "Введите корректный URL с http(s).", - "newKnowledge.keepEditing": "Продолжить редактирование", "newKnowledge.lastIndexed": "Последняя индексация", "newKnowledge.lastReadyRevisionHint": "Неудачная обработка никогда не прерывает извлечение — последняя готовая редакция остается доступной в индексе контента.", "newKnowledge.lastSyncColumn": "Последняя синхронизация", "newKnowledge.learnMore": "Подробнее", - "newKnowledge.leavePartialSetupConfirm": "Выйти из настройки", - "newKnowledge.leavePartialSetupDescription": "База знаний создана, но подтвердить её разрешения не удалось. При выходе база знаний сохранится; доступ можно проверить позже.", - "newKnowledge.leavePartialSetupTitle": "Выйти из незавершённой настройки?", "newKnowledge.legacy": "Предыдущая версия", "newKnowledge.loadMore": "Загрузить ещё", "newKnowledge.loadMoreRevisions": "Загрузить предыдущие редакции", diff --git a/web/i18n/sl-SI/dataset.json b/web/i18n/sl-SI/dataset.json index 4c6e2e73496..ebb78490e7c 100644 --- a/web/i18n/sl-SI/dataset.json +++ b/web/i18n/sl-SI/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Te baze znanja nismo mogli naložiti. Poskusite znova.", "newKnowledge.detailErrorTitle": "Nekaj je šlo narobe", "newKnowledge.disableSource": "Onemogoči", - "newKnowledge.discardDraftConfirm": "Zavrzi osnutek", - "newKnowledge.discardDraftDescription": "Spremembe tega osnutka zbirke znanja bodo izgubljene.", - "newKnowledge.discardDraftTitle": "Želite zavreči ta osnutek zbirke znanja?", - "newKnowledge.discardSourceChanges": "Zavreči spremembe vira?", - "newKnowledge.discardSourceChangesConfirm": "Zavrzi spremembe", - "newKnowledge.discardSourceChangesDescription": "Predogled iskanja po vsebini, izbira strani in nastavitve sinhronizacije bodo izgubljeni.", - "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.documentActions": "Dejanja za {{name}}", "newKnowledge.documentActionsUnavailable": "Dejanja dokumentov še niso na voljo za to bazo znanja.", "newKnowledge.documentChunksEmpty": "Za to različico še ni razpoložljivih delov.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Prekini", "newKnowledge.invalidDatasourceParameter": "Vnesite veljavno vrednost za {{parameter}}.", "newKnowledge.invalidRootUrl": "Vnesite veljaven URL http(s).", - "newKnowledge.keepEditing": "Nadaljuj urejanje", "newKnowledge.lastIndexed": "Nazadnje indeksirano", "newKnowledge.lastReadyRevisionHint": "Neuspešna obdelava nikoli ne prekine pridobivanja — zadnja pripravljena revizija ostane na voljo v indeksu vsebine.", "newKnowledge.lastSyncColumn": "Zadnja sinhronizacija", "newKnowledge.learnMore": "Več informacij", - "newKnowledge.leavePartialSetupConfirm": "Zapusti nastavitev", - "newKnowledge.leavePartialSetupDescription": "Zbirka znanja je bila ustvarjena, vendar njenega dovoljenja ni bilo mogoče potrditi. Če zapustite nastavitev, bo zbirka znanja ohranjena; dostop lahko preverite pozneje.", - "newKnowledge.leavePartialSetupTitle": "Želite zapustiti nedokončano nastavitev?", "newKnowledge.legacy": "Staro", "newKnowledge.loadMore": "Naloži več", "newKnowledge.loadMoreRevisions": "Naloži starejše različice", diff --git a/web/i18n/th-TH/dataset.json b/web/i18n/th-TH/dataset.json index 3eddbba9168..720a75c2a90 100644 --- a/web/i18n/th-TH/dataset.json +++ b/web/i18n/th-TH/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "เราไม่สามารถโหลดฐานความรู้นี้ได้ ลองอีกครั้ง", "newKnowledge.detailErrorTitle": "มีบางอย่างผิดพลาด", "newKnowledge.disableSource": "ปิดการใช้งาน", - "newKnowledge.discardDraftConfirm": "ละทิ้งฉบับร่าง", - "newKnowledge.discardDraftDescription": "การเปลี่ยนแปลงในฉบับร่างฐานความรู้นี้จะสูญหาย", - "newKnowledge.discardDraftTitle": "ละทิ้งฉบับร่างฐานความรู้นี้หรือไม่?", - "newKnowledge.discardSourceChanges": "ละทิ้งการเปลี่ยนแปลงแหล่งข้อมูลหรือไม่", - "newKnowledge.discardSourceChangesConfirm": "ละทิ้งการเปลี่ยนแปลง", - "newKnowledge.discardSourceChangesDescription": "ตัวอย่างการรวบรวมข้อมูล การเลือกหน้า และการตั้งค่าการซิงค์จะสูญหาย", - "newKnowledge.discardSourceDraftDescription": "การกำหนดค่าแหล่งข้อมูลและตัวอย่างการรวบรวมข้อมูลจะถูกลบ", - "newKnowledge.discardSourceDraftFailed": "ไม่สามารถละทิ้งฉบับร่างแหล่งข้อมูลได้ ลองอีกครั้ง", - "newKnowledge.discardSourceDraftTitle": "ละทิ้งฉบับร่างแหล่งข้อมูลนี้หรือไม่", "newKnowledge.documentActions": "การดำเนินการสำหรับ {{name}}", "newKnowledge.documentActionsUnavailable": "การดำเนินการกับเอกสารยังไม่พร้อมใช้งานสำหรับฐานความรู้นี้", "newKnowledge.documentChunksEmpty": "ยังไม่มีส่วนข้อมูลสำหรับรุ่นแก้ไขนี้", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "ขัดจังหวะ", "newKnowledge.invalidDatasourceParameter": "ป้อนค่าที่ถูกต้องสำหรับ {{parameter}}", "newKnowledge.invalidRootUrl": "ป้อน URL http(s) ที่ถูกต้อง", - "newKnowledge.keepEditing": "แก้ไขต่อ", "newKnowledge.lastIndexed": "จัดทำดัชนีล่าสุด", "newKnowledge.lastReadyRevisionHint": "การประมวลผลที่ล้มเหลวจะไม่ขัดจังหวะการดึงข้อมูล — การแก้ไขที่พร้อมใช้ครั้งล่าสุดจะยังคงอยู่ในดัชนีเนื้อหา", "newKnowledge.lastSyncColumn": "ซิงค์ครั้งล่าสุด", "newKnowledge.learnMore": "เรียนรู้เพิ่มเติม", - "newKnowledge.leavePartialSetupConfirm": "ออกจากการตั้งค่า", - "newKnowledge.leavePartialSetupDescription": "สร้างฐานความรู้แล้ว แต่ไม่สามารถยืนยันสิทธิ์ได้ หากออก ฐานความรู้จะยังคงอยู่ และคุณสามารถตรวจสอบการเข้าถึงภายหลังได้", - "newKnowledge.leavePartialSetupTitle": "ออกจากการตั้งค่าที่ยังไม่เสร็จหรือไม่?", "newKnowledge.legacy": "แบบเดิม", "newKnowledge.loadMore": "โหลดเพิ่มเติม", "newKnowledge.loadMoreRevisions": "โหลดรุ่นแก้ไขก่อนหน้า", diff --git a/web/i18n/tr-TR/dataset.json b/web/i18n/tr-TR/dataset.json index 6b876a43340..60206c3f110 100644 --- a/web/i18n/tr-TR/dataset.json +++ b/web/i18n/tr-TR/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Bu bilgi tabanını yükleyemedik. Tekrar deneyin.", "newKnowledge.detailErrorTitle": "Bir şeyler ters gitti", "newKnowledge.disableSource": "Devre Dışı Bırak", - "newKnowledge.discardDraftConfirm": "Taslağı sil", - "newKnowledge.discardDraftDescription": "Bu bilgi tabanı taslağındaki değişiklikleriniz kaybolacak.", - "newKnowledge.discardDraftTitle": "Bu bilgi tabanı taslağı silinsin mi?", - "newKnowledge.discardSourceChanges": "Kaynak değişiklikleri silinsin mi?", - "newKnowledge.discardSourceChangesConfirm": "Değişiklikleri sil", - "newKnowledge.discardSourceChangesDescription": "Tarama önizlemesi, sayfa seçimi ve eşitleme ayarları kaybolacak.", - "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.documentActions": "{{name}} için eylemler", "newKnowledge.documentActionsUnavailable": "Belge eylemleri henüz bu bilgi tabanında kullanılamıyor.", "newKnowledge.documentChunksEmpty": "Bu revizyon için henüz parça yok.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Kesinti", "newKnowledge.invalidDatasourceParameter": "{{parameter}} için geçerli bir değer girin.", "newKnowledge.invalidRootUrl": "Geçerli bir http(s) URL’si girin.", - "newKnowledge.keepEditing": "Düzenlemeye devam et", "newKnowledge.lastIndexed": "Son dizinleme", "newKnowledge.lastReadyRevisionHint": "Başarısız işleme hiçbir zaman alımı kesintiye uğratmaz; son hazır revizyon içerik dizininde mevcut kalır.", "newKnowledge.lastSyncColumn": "Son senkronizasyon", "newKnowledge.learnMore": "Daha fazla bilgi", - "newKnowledge.leavePartialSetupConfirm": "Kurulumdan çık", - "newKnowledge.leavePartialSetupDescription": "Bilgi tabanı oluşturuldu ancak izni doğrulanamadı. Çıkarsanız bilgi tabanı korunur; erişimi daha sonra gözden geçirebilirsiniz.", - "newKnowledge.leavePartialSetupTitle": "Tamamlanmamış kurulumdan çıkılsın mı?", "newKnowledge.legacy": "Eski", "newKnowledge.loadMore": "Daha fazla yükle", "newKnowledge.loadMoreRevisions": "Eski revizyonları yükle", diff --git a/web/i18n/uk-UA/dataset.json b/web/i18n/uk-UA/dataset.json index c84b7bdd403..63986f1c500 100644 --- a/web/i18n/uk-UA/dataset.json +++ b/web/i18n/uk-UA/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Нам не вдалося завантажити цю базу знань. Спробуйте знову.", "newKnowledge.detailErrorTitle": "Щось пішло не так", "newKnowledge.disableSource": "Вимкнути", - "newKnowledge.discardDraftConfirm": "Відхилити чернетку", - "newKnowledge.discardDraftDescription": "Зміни в цій чернетці бази знань буде втрачено.", - "newKnowledge.discardDraftTitle": "Відхилити цю чернетку бази знань?", - "newKnowledge.discardSourceChanges": "Відхилити зміни джерела?", - "newKnowledge.discardSourceChangesConfirm": "Відхилити зміни", - "newKnowledge.discardSourceChangesDescription": "Попередній перегляд сканування, вибір сторінок і налаштування синхронізації буде втрачено.", - "newKnowledge.discardSourceDraftDescription": "Конфігурацію джерела й попередній перегляд сканування буде видалено.", - "newKnowledge.discardSourceDraftFailed": "Не вдалося відхилити чернетку джерела. Повторіть спробу.", - "newKnowledge.discardSourceDraftTitle": "Відхилити цю чернетку джерела?", "newKnowledge.documentActions": "Дії для {{name}}", "newKnowledge.documentActionsUnavailable": "Дії з документами поки що недоступні для цієї бази знань.", "newKnowledge.documentChunksEmpty": "Для цієї редакції ще немає доступних фрагментів.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Переривати", "newKnowledge.invalidDatasourceParameter": "Введіть припустиме значення для {{parameter}}.", "newKnowledge.invalidRootUrl": "Введіть дійсну URL-адресу http(s).", - "newKnowledge.keepEditing": "Продовжити редагування", "newKnowledge.lastIndexed": "Останнє індексування", "newKnowledge.lastReadyRevisionHint": "Невдала обробка ніколи не перериває пошук — остання готова версія залишається доступною в індексі вмісту.", "newKnowledge.lastSyncColumn": "Остання синхронізація", "newKnowledge.learnMore": "Докладніше", - "newKnowledge.leavePartialSetupConfirm": "Вийти з налаштування", - "newKnowledge.leavePartialSetupDescription": "Базу знань створено, але не вдалося підтвердити її дозвіл. Якщо вийти, базу знань буде збережено; доступ можна перевірити пізніше.", - "newKnowledge.leavePartialSetupTitle": "Вийти з незавершеного налаштування?", "newKnowledge.legacy": "Попередня версія", "newKnowledge.loadMore": "Завантажити ще", "newKnowledge.loadMoreRevisions": "Завантажити попередні редакції", diff --git a/web/i18n/vi-VN/dataset.json b/web/i18n/vi-VN/dataset.json index 1cacce48a41..220e6d06988 100644 --- a/web/i18n/vi-VN/dataset.json +++ b/web/i18n/vi-VN/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "Chúng tôi không thể tải cơ sở kiến thức này. Hãy thử lại.", "newKnowledge.detailErrorTitle": "Đã xảy ra lỗi", "newKnowledge.disableSource": "Tắt", - "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.discardSourceChanges": "Hủy thay đổi nguồn?", - "newKnowledge.discardSourceChangesConfirm": "Hủy thay đổi", - "newKnowledge.discardSourceChangesDescription": "Bản xem trước thu thập dữ liệu, lựa chọn trang và cài đặt đồng bộ sẽ bị mất.", - "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.documentActions": "Các hành động dành cho {{name}}", "newKnowledge.documentActionsUnavailable": "Hành động tài liệu chưa có sẵn cho cơ sở kiến thức này.", "newKnowledge.documentChunksEmpty": "Chưa có đoạn nào cho bản sửa đổi này.", @@ -297,14 +288,10 @@ "newKnowledge.interruptTask": "Ngắt", "newKnowledge.invalidDatasourceParameter": "Nhập giá trị hợp lệ cho {{parameter}}.", "newKnowledge.invalidRootUrl": "Nhập URL http(s) hợp lệ.", - "newKnowledge.keepEditing": "Tiếp tục chỉnh sửa", "newKnowledge.lastIndexed": "Lập chỉ mục gần nhất", "newKnowledge.lastReadyRevisionHint": "Quá trình xử lý không thành công không bao giờ làm gián đoạn quá trình truy xuất — bản sửa đổi sẵn sàng cuối cùng vẫn có sẵn trong chỉ mục nội dung.", "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", - "newKnowledge.leavePartialSetupDescription": "Cơ sở kiến thức đã được tạo nhưng không thể xác nhận quyền. Nếu thoát, cơ sở kiến thức vẫn được giữ lại; bạn có thể xem lại quyền truy cập sau.", - "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.loadMoreRevisions": "Tải các bản sửa đổi cũ hơn", diff --git a/web/i18n/zh-Hans/dataset.json b/web/i18n/zh-Hans/dataset.json index 2d8e06956cb..89a1b0cd9d6 100644 --- a/web/i18n/zh-Hans/dataset.json +++ b/web/i18n/zh-Hans/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "无法加载此知识库,请重试。", "newKnowledge.detailErrorTitle": "出现错误", "newKnowledge.disableSource": "禁用", - "newKnowledge.discardDraftConfirm": "放弃草稿", - "newKnowledge.discardDraftDescription": "你对该知识库草稿所做的更改将丢失。", - "newKnowledge.discardDraftTitle": "放弃此知识库草稿?", - "newKnowledge.discardSourceChanges": "放弃数据源更改?", - "newKnowledge.discardSourceChangesConfirm": "放弃更改", - "newKnowledge.discardSourceChangesDescription": "抓取预览、页面选择和同步设置将会丢失。", - "newKnowledge.discardSourceDraftDescription": "数据源配置和抓取预览将被移除。", - "newKnowledge.discardSourceDraftFailed": "无法放弃数据源草稿,请重试。", - "newKnowledge.discardSourceDraftTitle": "放弃此数据源草稿?", "newKnowledge.documentActions": "{{name}} 的操作", "newKnowledge.documentActionsUnavailable": "此知识库暂不支持文档操作。", "newKnowledge.documentChunksEmpty": "此修订版本暂时没有可用分段。", @@ -301,14 +292,10 @@ "newKnowledge.interruptTask": "中断", "newKnowledge.invalidDatasourceParameter": "请输入有效的 {{parameter}}。", "newKnowledge.invalidRootUrl": "请输入有效的 http(s) URL。", - "newKnowledge.keepEditing": "继续编辑", "newKnowledge.lastIndexed": "最近索引时间", "newKnowledge.lastReadyRevisionHint": "处理失败不会中断检索,系统仍会使用最近一个已就绪的修订版本。", "newKnowledge.lastSyncColumn": "上次同步", "newKnowledge.learnMore": "了解更多", - "newKnowledge.leavePartialSetupConfirm": "离开设置", - "newKnowledge.leavePartialSetupDescription": "知识库已创建,但无法确认其权限状态。离开后知识库仍会保留,你可以稍后检查访问权限。", - "newKnowledge.leavePartialSetupTitle": "离开未完成的设置?", "newKnowledge.legacy": "旧版", "newKnowledge.loadMore": "加载更多", "newKnowledge.loadMoreRevisions": "加载更早的修订版本", diff --git a/web/i18n/zh-Hant/dataset.json b/web/i18n/zh-Hant/dataset.json index f5b595c7b18..4f3bbb47bf8 100644 --- a/web/i18n/zh-Hant/dataset.json +++ b/web/i18n/zh-Hant/dataset.json @@ -211,15 +211,6 @@ "newKnowledge.detailErrorDescription": "無法載入此知識庫,請再試一次。", "newKnowledge.detailErrorTitle": "發生錯誤", "newKnowledge.disableSource": "停用", - "newKnowledge.discardDraftConfirm": "放棄草稿", - "newKnowledge.discardDraftDescription": "對此知識庫草稿的變更將會遺失。", - "newKnowledge.discardDraftTitle": "放棄此知識庫草稿?", - "newKnowledge.discardSourceChanges": "放棄來源變更?", - "newKnowledge.discardSourceChangesConfirm": "放棄變更", - "newKnowledge.discardSourceChangesDescription": "檢索預覽、頁面選取和同步設定將會遺失。", - "newKnowledge.discardSourceDraftDescription": "來源設定和抓取預覽將被移除。", - "newKnowledge.discardSourceDraftFailed": "無法捨棄來源草稿。請重試。", - "newKnowledge.discardSourceDraftTitle": "捨棄此來源草稿?", "newKnowledge.documentActions": "{{name}} 的操作", "newKnowledge.documentActionsUnavailable": "此知識庫暫不支援文件操作。", "newKnowledge.documentChunksEmpty": "此修訂版本暫時沒有可用分段。", @@ -300,14 +291,10 @@ "newKnowledge.interruptTask": "中斷", "newKnowledge.invalidDatasourceParameter": "請輸入有效的 {{parameter}}。", "newKnowledge.invalidRootUrl": "請輸入有效的 http(s) URL。", - "newKnowledge.keepEditing": "繼續編輯", "newKnowledge.lastIndexed": "最近建立索引時間", "newKnowledge.lastReadyRevisionHint": "處理失敗不會中斷檢索,內容索引中會繼續保留上一個就緒的修訂。", "newKnowledge.lastSyncColumn": "上次同步", "newKnowledge.learnMore": "瞭解更多", - "newKnowledge.leavePartialSetupConfirm": "離開設定", - "newKnowledge.leavePartialSetupDescription": "知識庫已建立,但無法確認其權限狀態。離開後知識庫仍會保留,你可以稍後檢查存取權限。", - "newKnowledge.leavePartialSetupTitle": "離開未完成的設定?", "newKnowledge.legacy": "舊版", "newKnowledge.loadMore": "載入更多", "newKnowledge.loadMoreRevisions": "載入較早的修訂版本",
- {t(($) => $['newKnowledge.discardSourceDraftFailed'])} -
- {t(($) => $['newKnowledge.crawlFailedDescription'])} -
+ {t(($) => $['newKnowledge.crawlFailedDescription'])} +