diff --git a/oxlint-suppressions.json b/oxlint-suppressions.json index 3252fe193fd..4bdd3ebfec8 100644 --- a/oxlint-suppressions.json +++ b/oxlint-suppressions.json @@ -5082,11 +5082,6 @@ "count": 4 } }, - "web/features/agent-v2/agent-detail/configure/use-agent-configure-build-draft.ts": { - "@tanstack/query/prefer-query-options": { - "count": 1 - } - }, "web/features/agent-v2/agent-detail/logs/__tests__/page.spec.tsx": { "@tanstack/query/prefer-query-options": { "count": 1 diff --git a/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx b/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx index e9673e63cee..c6597e09d95 100644 --- a/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx +++ b/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx @@ -535,10 +535,26 @@ vi.mock('../components/preview/header', () => ({ })) vi.mock('../components/preview/versions-panel', () => ({ - AgentPreviewVersionsPanel: (props: { onSelectVersion: (versionId: string) => void }) => ( - + AgentPreviewVersionsPanel: (props: { + onBeforeRestore?: () => Promise + onSelectVersion: (versionId: string | null) => void + onVersionRestored?: () => Promise + }) => ( + <> + + + ), })) @@ -2859,6 +2875,64 @@ describe('AgentConfigurePage', () => { expect(screen.queryByRole('region', { name: 'build-draft-bar' })).not.toBeInTheDocument() }) + it('should save pending draft edits before restoring from the version menu and rebase the composer', async () => { + const user = userEvent.setup() + const queryClient = createQueryClient() + const draftSave = createDeferredPromise<{ agent_soul: object }>() + mocks.saveComposerDraft.mockReturnValue(draftSave.promise) + const refetchComposer = vi.fn(async () => { + mocks.queryState.composer = { + ...mocks.queryState.composer, + data: { + agent_soul: { + prompt: { system_prompt: 'restored prompt' }, + }, + }, + } + return {} + }) + mocks.queryState.composer = { + data: { + agent_soul: { + prompt: { system_prompt: 'draft prompt' }, + }, + }, + isFetching: false, + isError: false, + isPending: false, + isSuccess: true, + refetch: refetchComposer, + } + + render( + + + , + ) + + await user.click(screen.getByRole('button', { name: 'edit prompt' })) + await user.click(screen.getByRole('button', { name: 'open versions' })) + await user.click(screen.getByRole('button', { name: 'restore from version menu' })) + + expect(mocks.saveComposerDraft).toHaveBeenCalledTimes(1) + expect(refetchComposer).not.toHaveBeenCalled() + expect(screen.getByRole('region', { name: 'orchestrate-panel' })).toHaveTextContent( + 'prompt:edited draft prompt', + ) + + draftSave.resolve({ agent_soul: {} }) + + await waitFor(() => { + expect(screen.getByRole('region', { name: 'orchestrate-panel' })).toHaveTextContent( + 'prompt:restored prompt', + ) + }) + expect(refetchComposer).toHaveBeenCalledTimes(1) + expect(screen.getByRole('region', { name: 'orchestrate-panel' })).toHaveTextContent( + 'readonly:no', + ) + }) + it('should rebase the composer from the restored version', async () => { const user = userEvent.setup() const queryClient = createQueryClient() diff --git a/web/features/agent-v2/agent-detail/configure/__tests__/use-agent-configure-build-draft.spec.tsx b/web/features/agent-v2/agent-detail/configure/__tests__/use-agent-configure-build-draft.spec.tsx new file mode 100644 index 00000000000..08040d8c76b --- /dev/null +++ b/web/features/agent-v2/agent-detail/configure/__tests__/use-agent-configure-build-draft.spec.tsx @@ -0,0 +1,101 @@ +import type { PropsWithChildren } from 'react' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { act, renderHook, waitFor } from '@testing-library/react' +import { useAgentConfigureBuildDraftData } from '../use-agent-configure-build-draft' + +const mocks = vi.hoisted(() => ({ + request: vi.fn(), + toastError: vi.fn(), +})) + +vi.mock('@/app/notifications', () => ({ + toast: { error: mocks.toastError }, +})) + +vi.mock('@/service/console', () => ({ + consoleQuery: { + agent: { + byAgentId: { + buildDraft: { + get: { + queryOptions: ({ context }: { context?: { silent?: boolean } }) => ({ + queryKey: ['agent', 'agent-1', 'build-draft'], + queryFn: async () => { + try { + return await mocks.request() + } catch (error) { + if (!context?.silent) mocks.toastError('Request failed') + throw error + } + }, + }), + }, + }, + }, + }, + }, +})) + +function setup() { + const queryClient = new QueryClient({ + defaultOptions: { queries: { retry: false } }, + }) + const setSoulSourceOverride = vi.fn() + const wrapper = ({ children }: PropsWithChildren) => ( + {children} + ) + const hook = renderHook( + () => + useAgentConfigureBuildDraftData({ + agentId: 'agent-1', + activeVersionId: 'version-1', + isBuildMode: true, + isViewingVersion: false, + setSoulSourceOverride, + soulSourceOverride: null, + }), + { wrapper }, + ) + + return { ...hook, setSoulSourceOverride } +} + +describe('build draft refresh errors', () => { + beforeEach(() => { + vi.clearAllMocks() + mocks.request.mockReset() + }) + + it('returns to the normal draft without a toast when a later refresh finds no build draft', async () => { + mocks.request.mockResolvedValueOnce({ draft: { id: 'build-draft-1' } }) + const { result, setSoulSourceOverride } = setup() + await waitFor(() => expect(result.current.isActive).toBe(true)) + + const notFound = new Response(null, { status: 404 }) + mocks.request.mockRejectedValueOnce(notFound) + await act(async () => { + const refreshed = await result.current.refetch() + expect(refreshed.error).toBe(notFound) + }) + + await waitFor(() => expect(result.current.soulSource).toBe('draft')) + expect(setSoulSourceOverride).toHaveBeenCalledWith('draft') + expect(mocks.toastError).not.toHaveBeenCalled() + }) + + it('still notifies when refreshing the build draft fails unexpectedly', async () => { + mocks.request.mockResolvedValueOnce({ draft: { id: 'build-draft-1' } }) + const { result, setSoulSourceOverride } = setup() + await waitFor(() => expect(result.current.isActive).toBe(true)) + + const serverError = new Response(null, { status: 500 }) + mocks.request.mockRejectedValueOnce(serverError) + await act(async () => { + const refreshed = await result.current.refetch() + expect(refreshed.error).toBe(serverError) + }) + + expect(mocks.toastError).toHaveBeenCalledTimes(1) + expect(setSoulSourceOverride).not.toHaveBeenCalled() + }) +}) diff --git a/web/features/agent-v2/agent-detail/configure/components/composer-session.tsx b/web/features/agent-v2/agent-detail/configure/components/composer-session.tsx index 0cf1139cd32..f996b9a5b83 100644 --- a/web/features/agent-v2/agent-detail/configure/components/composer-session.tsx +++ b/web/features/agent-v2/agent-detail/configure/components/composer-session.tsx @@ -628,6 +628,22 @@ function AgentConfigurePageComposerContent({ agentId={agentId} activeVersionId={activeVersionId} onSelectVersion={selectVersion} + restoreDisabled={ + buildDraft.isActive || + buildDraftActionsDisabled || + isEnteringBuildMode || + isPublishing + } + onBeforeRestore={async () => { + if (!isViewingVersion) { + await waitForPendingPreviewDraftSave() + await saveDraft() + } + }} + onVersionRestored={async () => { + await composerQuery.refetch() + onComposerRebase() + }} onClose={() => setShowPreviewVersions(false)} /> )} diff --git a/web/features/agent-v2/agent-detail/configure/components/orchestrate/__tests__/publish-bar.spec.tsx b/web/features/agent-v2/agent-detail/configure/components/orchestrate/__tests__/publish-bar.spec.tsx index 954167d03ee..59545c03e78 100644 --- a/web/features/agent-v2/agent-detail/configure/components/orchestrate/__tests__/publish-bar.spec.tsx +++ b/web/features/agent-v2/agent-detail/configure/components/orchestrate/__tests__/publish-bar.spec.tsx @@ -14,11 +14,26 @@ import { agentComposerSavedDraftAtom, } from '@/features/agent-v2/agent-composer/store' import { agentComposerPromptAtom } from '@/features/agent-v2/agent-composer/store-modules/prompt' +import { consoleQuery } from '@/service/console' +import { createNuqsTestWrapper } from '@/test/nuqs-testing' import { AgentConfigurePublishBar } from '../publish-bar' type PublishHandler = NonNullable['onPublish']> type PublishMock = Mock +const restoreAccess = vi.hoisted(() => ({ + canRestore: true, + plan: 'professional', + onUrlUpdate: vi.fn(), +})) +vi.mock('@/features/agent-v2/permissions', () => ({ + useAgentPermissions: () => ({ canReleaseAndVersion: restoreAccess.canRestore }), +})) +vi.mock('@/features/system-features/state', async () => { + const { atom } = await import('jotai') + return { deploymentEditionAtom: atom('CLOUD') } +}) + const hotkeyRegistrations = vi.hoisted( () => new Map< @@ -84,8 +99,24 @@ vi.mock('@/hooks/use-timestamp', () => ({ }), })) +vi.mock('@/features/system-features/client', () => ({ + systemFeaturesQueryOptions: () => ({ + queryKey: ['system-features'], + queryFn: async () => ({ deployment_edition: 'CLOUD' }), + }), +})) + vi.mock('@/service/console', () => ({ consoleQuery: { + features: { + get: { + queryOptions: (options: Record) => ({ + ...options, + queryKey: ['features'], + queryFn: async () => ({ billing: { subscription: { plan: restoreAccess.plan } } }), + }), + }, + }, agent: { byAgentId: { get: { @@ -137,7 +168,10 @@ vi.mock('@/service/console', () => ({ byVersionId: { restore: { post: { - mutationOptions: () => ({ mutationFn: restoreVersionMutation }), + mutationOptions: (options: Record) => ({ + ...options, + mutationFn: restoreVersionMutation, + }), }, }, }, @@ -239,6 +273,10 @@ function renderPublishBar({ mutations: { retry: false }, }, }) + queryClient.setQueryData(consoleQuery.features.get.queryOptions({}).queryKey, { + billing: { subscription: { plan: restoreAccess.plan } }, + }) + const { wrapper: NuqsWrapper } = createNuqsTestWrapper({ onUrlUpdate: restoreAccess.onUrlUpdate }) const store = createStore() store.set(agentComposerPromptAtom, prompt) setupStore?.(store) @@ -270,20 +308,22 @@ function renderPublishBar({ } const renderPublishBarTree = (nextProps?: { isPublishing?: boolean }) => ( - - - - - + + + + + + + ) const view = render(renderPublishBarTree()) @@ -301,6 +341,8 @@ describe('AgentConfigurePublishBar', () => { beforeEach(() => { vi.clearAllMocks() hotkeyRegistrations.clear() + restoreAccess.canRestore = true + restoreAccess.plan = 'professional' restoreVersionMutation.mockResolvedValue({ active_config_snapshot_id: 'snapshot-2', result: 'success', @@ -393,8 +435,13 @@ describe('AgentConfigurePublishBar', () => { expect(screen.getByText('Stable version')).toBeInTheDocument() expect(screen.getByText('agentV2.agentDetail.versionHistory.viewOnly')).toBeInTheDocument() expect(screen.getByText('formatted:1710000000 · Alice')).toBeInTheDocument() - fireEvent.click( - screen.getByRole('button', { name: 'agentV2.agentDetail.versionHistory.restore' }), + const user = userEvent.setup() + await user.click( + screen.getByRole('button', { name: /agentV2.agentDetail.versionHistory.restore/ }), + ) + expect(restoreVersionMutation).not.toHaveBeenCalled() + await user.click( + within(await screen.findByRole('alertdialog')).getByRole('button', { name: /restore/i }), ) await waitFor(() => { @@ -413,6 +460,75 @@ describe('AgentConfigurePublishBar', () => { expect(toastMock.success).toHaveBeenCalledWith('common.api.actionSuccess') }) + it('shows the agent upgrade dialog before opening pricing on the sandbox plan', async () => { + restoreAccess.plan = 'sandbox' + const user = userEvent.setup() + const { onExitVersions, onVersionRestored } = renderPublishBar({ + selectedVersionSnapshot: activeConfigSnapshot, + }) + await user.click( + screen.getByRole('button', { name: /agentV2.agentDetail.versionHistory.restore/ }), + ) + const dialog = await screen.findByRole('dialog', { name: 'billing.upgrade.agentRestore.title' }) + expect(dialog).toHaveAccessibleDescription('billing.upgrade.agentRestore.description') + expect(restoreAccess.onUrlUpdate).not.toHaveBeenCalled() + expect(restoreVersionMutation).not.toHaveBeenCalled() + await user.click( + within(dialog).getByRole('button', { name: 'billing.triggerLimitModal.upgrade' }), + ) + expect(restoreAccess.onUrlUpdate).toHaveBeenCalledWith( + expect.objectContaining({ queryString: '?pricing=open' }), + ) + await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument()) + expect(restoreVersionMutation).not.toHaveBeenCalled() + expect(onExitVersions).not.toHaveBeenCalled() + expect(onVersionRestored).not.toHaveBeenCalled() + }) + + it('prevents duplicate restoration and cancellation while the request is pending', async () => { + const deferred = createDeferredPromise() + restoreVersionMutation.mockImplementationOnce(async () => { + await deferred.promise + return { active_config_snapshot_id: 'snapshot-2', result: 'success' } + }) + const user = userEvent.setup() + const { onExitVersions } = renderPublishBar({ selectedVersionSnapshot: activeConfigSnapshot }) + await user.click( + screen.getByRole('button', { name: /agentV2.agentDetail.versionHistory.restore/ }), + ) + const dialog = await screen.findByRole('alertdialog') + const confirm = within(dialog).getByRole('button', { name: /restore/i }) + await user.click(confirm) + await waitFor(() => expect(confirm).toHaveAttribute('aria-disabled', 'true')) + expect(within(dialog).getByRole('button', { name: /cancel/i })).toBeDisabled() + await user.click(confirm) + expect(restoreVersionMutation).toHaveBeenCalledTimes(1) + expect(onExitVersions).not.toHaveBeenCalled() + await act(async () => { + deferred.resolve() + await deferred.promise + }) + await waitFor(() => expect(onExitVersions).toHaveBeenCalledTimes(1)) + }) + + it('keeps the selected version open when restoration fails', async () => { + restoreVersionMutation.mockRejectedValueOnce(new Error('Restore failed')) + const user = userEvent.setup() + const { onExitVersions, onVersionRestored } = renderPublishBar({ + selectedVersionSnapshot: activeConfigSnapshot, + }) + await user.click( + screen.getByRole('button', { name: /agentV2.agentDetail.versionHistory.restore/ }), + ) + await user.click( + within(await screen.findByRole('alertdialog')).getByRole('button', { name: /restore/i }), + ) + await waitFor(() => expect(restoreVersionMutation).toHaveBeenCalledTimes(1)) + expect(onExitVersions).not.toHaveBeenCalled() + expect(onVersionRestored).not.toHaveBeenCalled() + expect(screen.getByRole('alertdialog')).toBeInTheDocument() + }) + it('should render saved time from the latest draft save timestamp', () => { renderPublishBar({ draftSavedAt: 1710000100000 }) diff --git a/web/features/agent-v2/agent-detail/configure/components/orchestrate/publish-bar/index.tsx b/web/features/agent-v2/agent-detail/configure/components/orchestrate/publish-bar/index.tsx index 5efe1ed2266..6c643b2eaab 100644 --- a/web/features/agent-v2/agent-detail/configure/components/orchestrate/publish-bar/index.tsx +++ b/web/features/agent-v2/agent-detail/configure/components/orchestrate/publish-bar/index.tsx @@ -12,7 +12,7 @@ import { Kbd, KbdGroup } from '@langgenius/dify-ui/kbd' import { StatusDot } from '@langgenius/dify-ui/status-dot' import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { formatForDisplay, useHotkey } from '@tanstack/react-hotkeys' -import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { useQuery, useQueryClient } from '@tanstack/react-query' import { useAtomValue } from 'jotai' import { useId, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -21,6 +21,8 @@ import { isAgentComposerDirtyAtom } from '@/features/agent-v2/agent-composer/sto import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now' import useTimestamp from '@/hooks/use-timestamp' import { consoleQuery } from '@/service/console' +import { AgentVersionRestoreDialogs } from '../../preview/versions-panel/restore-dialogs' +import { useAgentVersionRestore } from '../../preview/versions-panel/use-agent-version-restore' import { AgentPublishImpactDetails } from './publish-impact-details' const PUBLISH_AGENT_HOTKEY = 'Mod+Shift+P' satisfies Hotkey @@ -133,57 +135,15 @@ export function AgentConfigurePublishBar({ enabled: publishIsAvailable && !isPublishing && !selectedVersionSnapshot, }) useQuery(workflowReferencesQueryOptions) - const restoreVersionMutation = useMutation( - consoleQuery.agent.byAgentId.versions.byVersionId.restore.post.mutationOptions(), - ) + const restore = useAgentVersionRestore({ + agentId, + onRestored: async () => { + await onVersionRestored?.() + onExitVersions?.() + }, + }) const canPublish = publishIsAvailable && !isPublishing - const handleRestoreVersion = (versionId: string) => { - if (restoreVersionMutation.isPending) return - - restoreVersionMutation.mutate( - { - params: { - agent_id: agentId, - version_id: versionId, - }, - }, - { - onSuccess: async () => { - await Promise.all([ - queryClient.invalidateQueries({ - queryKey: consoleQuery.agent.byAgentId.get.queryKey({ - input: { - params: { - agent_id: agentId, - }, - }, - }), - }), - queryClient.invalidateQueries({ - queryKey: consoleQuery.agent.byAgentId.composer.get.queryKey({ - input: { - params: { - agent_id: agentId, - }, - }, - }), - }), - queryClient.invalidateQueries({ - queryKey: consoleQuery.agent.byAgentId.versions.get.key(), - }), - ]) - await onVersionRestored?.() - onExitVersions?.() - toast.success(tCommon(($) => $['api.actionSuccess'])) - }, - onError: () => { - toast.error(tCommon(($) => $['api.actionFailed'])) - }, - }, - ) - } - const handlePublish = async () => { if (!canPublish) return @@ -237,12 +197,27 @@ export function AgentConfigurePublishBar({ if (selectedVersionSnapshot) { return ( - + <> + restore.requestRestore(selectedVersionSnapshot) : undefined + } + /> + + ) } @@ -420,11 +395,13 @@ function PublishBarActions({ function AgentVersionRestoreBar({ version, isRestoring = false, + restoreDisabled, onExitVersions, onRestoreVersion, }: { version: AgentConfigSnapshotSummaryResponse isRestoring?: boolean + restoreDisabled?: boolean onExitVersions?: () => void onRestoreVersion?: (versionId: string) => void }) { @@ -461,9 +438,9 @@ function AgentVersionRestoreBar({ - {onExport && ( + {(onExport || onRestore) && ( - onExport(version.id)} - className="gap-2" - > - - {t(($) => $.exportApp, { ns: 'app' })} - {showUpgrade && ( - - {t(($) => $['upgradeBtn.encourageShort'], { ns: 'billing' })} - - )} - + {onRestore && ( + onRestore(version)} + className="gap-2" + > + + {tWorkflow(($) => $['common.restore'])} + {showUpgrade && ( + + {t(($) => $['upgradeBtn.encourageShort'], { ns: 'billing' })} + + )} + + )} + {onExport && ( + onExport(version.id)} + className="gap-2" + > + + {t(($) => $.exportApp, { ns: 'app' })} + {showUpgrade && ( + + {t(($) => $['upgradeBtn.encourageShort'], { ns: 'billing' })} + + )} + + )} )} diff --git a/web/features/agent-v2/agent-detail/configure/use-agent-configure-build-draft.ts b/web/features/agent-v2/agent-detail/configure/use-agent-configure-build-draft.ts index 4c09def0579..c62c08ceb11 100644 --- a/web/features/agent-v2/agent-detail/configure/use-agent-configure-build-draft.ts +++ b/web/features/agent-v2/agent-detail/configure/use-agent-configure-build-draft.ts @@ -11,7 +11,7 @@ import type { AgentFileNode, AgentSoulConfigFormState, } from '@/features/agent-v2/agent-composer/form-state' -import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { queryOptions, useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import isEqual from 'fast-deep-equal' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -156,51 +156,42 @@ export function useAgentConfigureBuildDraftData({ setSoulSourceOverride: (source: AgentConfigureSoulSource | null) => void soulSourceOverride: AgentConfigureSoulSource | null }) { - const shouldSilenceBuildDraftCheckRef = useRef(true) + const { t } = useTranslation('common') const buildDraftQueryInput = { params: { agent_id: agentId, }, } const buildDraftQueryOptions = consoleQuery.agent.byAgentId.buildDraft.get.queryOptions({ - input: { - params: buildDraftQueryInput.params, - }, - context: {}, - }) - const silentBuildDraftQueryOptions = consoleQuery.agent.byAgentId.buildDraft.get.queryOptions({ input: { params: buildDraftQueryInput.params, }, context: { silent: true, }, - queryKey: buildDraftQueryOptions.queryKey, - }) - const buildDraftQuery = useQuery({ - ...buildDraftQueryOptions, - enabled: - isBuildMode && - !isViewingVersion && - soulSourceOverride !== 'draft' && - soulSourceOverride !== 'view-version', - queryFn: async (context) => { - try { - const queryOptions = shouldSilenceBuildDraftCheckRef.current - ? silentBuildDraftQueryOptions - : buildDraftQueryOptions - - shouldSilenceBuildDraftCheckRef.current = false - return await queryOptions.queryFn(context) - } catch (error) { - if (isNotFoundResponse(error)) setSoulSourceOverride('draft') - throw error - } - }, - retry: false, - refetchOnReconnect: false, - refetchOnWindowFocus: false, }) + const buildDraftQuery = useQuery( + queryOptions({ + ...buildDraftQueryOptions, + enabled: + isBuildMode && + !isViewingVersion && + soulSourceOverride !== 'draft' && + soulSourceOverride !== 'view-version', + queryFn: async (context) => { + try { + return await buildDraftQueryOptions.queryFn(context) + } catch (error) { + if (isNotFoundResponse(error)) setSoulSourceOverride('draft') + else toast.error(t(($) => $['api.actionFailed'])) + throw error + } + }, + retry: false, + refetchOnReconnect: false, + refetchOnWindowFocus: false, + }), + ) const { data: buildDraftData, dataUpdatedAt: buildDraftDataUpdatedAt, diff --git a/web/i18n/locales/ar-TN/billing.json b/web/i18n/locales/ar-TN/billing.json index 291b2bea519..d6ed2f1f5e3 100644 --- a/web/i18n/locales/ar-TN/billing.json +++ b/web/i18n/locales/ar-TN/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "أحداث المشغل", "upgrade.addChunks.description": "لقد وصلت إلى الحد الأقصى لإضافة الأجزاء لهذا الخطة.", "upgrade.addChunks.title": "قم بالترقية لمواصلة إضافة المقاطع", + "upgrade.agentRestore.description": "استعادة إصدارات تطبيق الوكيل غير متاحة في خطتك الحالية.", + "upgrade.agentRestore.title": "قم بالترقية لاستعادة إصدارات تطبيق الوكيل", "upgrade.uploadMultipleFiles.description": "ارفع عدة مستندات دفعة واحدة وزِد الحد الأقصى لحجم كل ملف إلى 50 MB.", "upgrade.uploadMultipleFiles.title": "قم بالترقية لإتاحة رفع الملفات دفعة واحدة والملفات الأكبر حجمًا", "upgrade.uploadMultiplePages.description": "لقد وصلت إلى حد التحميل — يمكن اختيار ورفع مستند واحد فقط في كل مرة على الخطة الحالية الخاصة بك.", diff --git a/web/i18n/locales/az-AZ/billing.json b/web/i18n/locales/az-AZ/billing.json index 0ff11c7b562..94d4c5a681b 100644 --- a/web/i18n/locales/az-AZ/billing.json +++ b/web/i18n/locales/az-AZ/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "Tətikləmə hadisələri", "upgrade.addChunks.description": "Bu plan üzrə fraqment əlavə etmə limitinə çatmısınız.", "upgrade.addChunks.title": "Fraqment əlavə etməyə davam etmək üçün planın yüksəldilməsi", + "upgrade.agentRestore.description": "Cari planınızda agent tətbiqinin versiyalarının bərpası əlçatan deyil.", + "upgrade.agentRestore.title": "Agent tətbiqinin versiyalarını bərpa etmək üçün planın yüksəldilməsi", "upgrade.uploadMultipleFiles.description": "Bir neçə sənədi eyni anda yüklə və hər faylın maksimum ölçüsünü 50 MB-a qədər artır.", "upgrade.uploadMultipleFiles.title": "Toplu yükləmə və daha böyük fayllar üçün planın yüksəldilməsi", "upgrade.uploadMultiplePages.description": "Yükləmə limitinə çatmısınız: cari planınızda eyni anda yalnız bir sənəd seçib yükləyə bilərsiniz.", diff --git a/web/i18n/locales/de-DE/billing.json b/web/i18n/locales/de-DE/billing.json index 7c2d546157d..2ee83981b93 100644 --- a/web/i18n/locales/de-DE/billing.json +++ b/web/i18n/locales/de-DE/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "AUSLÖSEEREIGNISSE", "upgrade.addChunks.description": "Sie haben das Limit für das Hinzufügen von Abschnitten in diesem Tarif erreicht.", "upgrade.addChunks.title": "Upgraden, um weiterhin Abschnitte hinzuzufügen", + "upgrade.agentRestore.description": "Die Wiederherstellung von Versionen der Agenten-App ist in Ihrem aktuellen Tarif nicht verfügbar.", + "upgrade.agentRestore.title": "Upgraden, um Versionen der Agenten-App wiederherzustellen", "upgrade.uploadMultipleFiles.description": "Laden Sie mehrere Dokumente gleichzeitig hoch und erhöhen Sie die maximale Größe pro Datei auf 50 MB.", "upgrade.uploadMultipleFiles.title": "Upgrade durchführen, um Batch-Uploads und größere Dateien freizuschalten", "upgrade.uploadMultiplePages.description": "Sie haben das Upload-Limit erreicht – in Ihrem aktuellen Tarif kann jeweils nur ein Dokument ausgewählt und hochgeladen werden.", diff --git a/web/i18n/locales/en-US/billing.json b/web/i18n/locales/en-US/billing.json index e083ccd185e..04cc06479a6 100644 --- a/web/i18n/locales/en-US/billing.json +++ b/web/i18n/locales/en-US/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "TRIGGER EVENTS", "upgrade.addChunks.description": "You’ve reached the limit of adding chunks for this plan.", "upgrade.addChunks.title": "Upgrade to continue adding chunks", + "upgrade.agentRestore.description": "Agent app version restoration is not available on your current plan.", + "upgrade.agentRestore.title": "Upgrade to restore agent app versions", "upgrade.uploadMultipleFiles.description": "Upload multiple documents at once and increase the maximum size per file to 50 MB.", "upgrade.uploadMultipleFiles.title": "Upgrade to unlock batch uploads and larger files", "upgrade.uploadMultiplePages.description": "You’ve reached the upload limit — only one document can be selected and uploaded at a time on your current plan.", diff --git a/web/i18n/locales/es-ES/billing.json b/web/i18n/locales/es-ES/billing.json index f0e9c648e88..0cce83c59ee 100644 --- a/web/i18n/locales/es-ES/billing.json +++ b/web/i18n/locales/es-ES/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "EVENTOS DESENCADENANTES", "upgrade.addChunks.description": "Has alcanzado el límite de agregar fragmentos para este plan.", "upgrade.addChunks.title": "Actualiza para seguir agregando fragmentos", + "upgrade.agentRestore.description": "La restauración de versiones de la aplicación de agente no está disponible en tu plan actual.", + "upgrade.agentRestore.title": "Actualiza para restaurar versiones de la aplicación de agente", "upgrade.uploadMultipleFiles.description": "Sube varios documentos a la vez y aumenta el tamaño máximo por archivo a 50 MB.", "upgrade.uploadMultipleFiles.title": "Mejora tu plan para desbloquear las cargas por lotes y los archivos de mayor tamaño", "upgrade.uploadMultiplePages.description": "Has alcanzado el límite de carga: solo se puede seleccionar y subir un documento a la vez en tu plan actual.", diff --git a/web/i18n/locales/fa-IR/billing.json b/web/i18n/locales/fa-IR/billing.json index 996579466e7..4ef916cee0b 100644 --- a/web/i18n/locales/fa-IR/billing.json +++ b/web/i18n/locales/fa-IR/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "رویدادهای محرک", "upgrade.addChunks.description": "شما به حد اضافه کردن بخش‌ها برای این طرح رسیده‌اید.", "upgrade.addChunks.title": "برای ادامه افزودن بخش‌ها ارتقا دهید", + "upgrade.agentRestore.description": "بازیابی نسخه‌های برنامهٔ عامل در طرح فعلی شما در دسترس نیست.", + "upgrade.agentRestore.title": "برای بازیابی نسخه‌های برنامهٔ عامل ارتقا دهید", "upgrade.uploadMultipleFiles.description": "چند سند را به‌طور هم‌زمان بارگذاری کنید و حداکثر اندازه هر فایل را به 50 MB افزایش دهید.", "upgrade.uploadMultipleFiles.title": "برای فعال‌کردن بارگذاری گروهی و فایل‌های بزرگ‌تر، ارتقا دهید", "upgrade.uploadMultiplePages.description": "شما به حد آپلود رسیده‌اید — در طرح فعلی خود تنها می‌توانید یک سند را در هر بار انتخاب و آپلود کنید.", diff --git a/web/i18n/locales/fr-FR/billing.json b/web/i18n/locales/fr-FR/billing.json index a3d3b2504f7..2bc33c3486a 100644 --- a/web/i18n/locales/fr-FR/billing.json +++ b/web/i18n/locales/fr-FR/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "ÉVÉNEMENTS DÉCLENCHEURS", "upgrade.addChunks.description": "Vous avez atteint la limite d'ajout de morceaux pour ce plan.", "upgrade.addChunks.title": "Mettez à niveau pour continuer à ajouter des morceaux", + "upgrade.agentRestore.description": "La restauration des versions de l’application d’agent n'est pas disponible avec votre plan actuel.", + "upgrade.agentRestore.title": "Mettez à niveau pour restaurer les versions de l’application d’agent", "upgrade.uploadMultipleFiles.description": "Importez plusieurs documents à la fois et augmentez la taille maximale par fichier à 50 MB.", "upgrade.uploadMultipleFiles.title": "Passez à une offre supérieure pour débloquer les importations groupées et les fichiers plus volumineux", "upgrade.uploadMultiplePages.description": "Vous avez atteint la limite de téléchargement — un seul document peut être sélectionné et téléchargé à la fois avec votre abonnement actuel.", diff --git a/web/i18n/locales/hi-IN/billing.json b/web/i18n/locales/hi-IN/billing.json index 8e8bdcbd2fe..faa8e515a55 100644 --- a/web/i18n/locales/hi-IN/billing.json +++ b/web/i18n/locales/hi-IN/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "ट्रिगर घटनाएँ", "upgrade.addChunks.description": "आप इस योजना के लिए टुकड़े जोड़ने की सीमा तक पहुँच चुके हैं।", "upgrade.addChunks.title": "अधिक चंक्स जोड़ने के लिए अपग्रेड करें", + "upgrade.agentRestore.description": "आपकी वर्तमान योजना में एजेंट ऐप संस्करण पुनर्स्थापना उपलब्ध नहीं है।", + "upgrade.agentRestore.title": "एजेंट ऐप संस्करणों को पुनर्स्थापित करने के लिए अपग्रेड करें", "upgrade.uploadMultipleFiles.description": "एक साथ कई दस्तावेज़ अपलोड करें और प्रति फ़ाइल अधिकतम साइज़ सीमा बढ़ाकर 50 MB करें।", "upgrade.uploadMultipleFiles.title": "बैच अपलोड और बड़ी फ़ाइलों की सुविधा अनलॉक करने के लिए अपग्रेड करें", "upgrade.uploadMultiplePages.description": "आपने अपलोड की सीमा तक पहुँच लिया है — आपके वर्तमान प्लान पर एक समय में केवल एक ही दस्तावेज़ चुना और अपलोड किया जा सकता है।", diff --git a/web/i18n/locales/id-ID/billing.json b/web/i18n/locales/id-ID/billing.json index f0b6c986624..5af8b7c650c 100644 --- a/web/i18n/locales/id-ID/billing.json +++ b/web/i18n/locales/id-ID/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "PERISTIWA PEMICU", "upgrade.addChunks.description": "Anda telah mencapai batas penambahan potongan untuk paket ini.", "upgrade.addChunks.title": "Tingkatkan untuk terus menambahkan potongan", + "upgrade.agentRestore.description": "Pemulihan versi aplikasi agen tidak tersedia di paket Anda saat ini.", + "upgrade.agentRestore.title": "Tingkatkan untuk memulihkan versi aplikasi agen", "upgrade.uploadMultipleFiles.description": "Upload beberapa dokumen sekaligus dan tingkatkan ukuran maksimum per file menjadi 50 MB.", "upgrade.uploadMultipleFiles.title": "Upgrade untuk membuka upload batch dan file berukuran lebih besar", "upgrade.uploadMultiplePages.description": "Anda telah mencapai batas unggah — hanya satu dokumen yang dapat dipilih dan diunggah sekaligus dengan paket Anda saat ini.", diff --git a/web/i18n/locales/it-IT/billing.json b/web/i18n/locales/it-IT/billing.json index 7af48590d6f..fac0800abbf 100644 --- a/web/i18n/locales/it-IT/billing.json +++ b/web/i18n/locales/it-IT/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "EVENTI DI ATTIVAZIONE", "upgrade.addChunks.description": "Hai raggiunto il limite di aggiunta di blocchi per questo piano.", "upgrade.addChunks.title": "Aggiorna per continuare ad aggiungere blocchi", + "upgrade.agentRestore.description": "Il ripristino delle versioni dell'app agente non è disponibile nel tuo piano attuale.", + "upgrade.agentRestore.title": "Esegui l'upgrade per ripristinare le versioni dell'app agente", "upgrade.uploadMultipleFiles.description": "Carica più documenti contemporaneamente e aumenta la dimensione massima per file a 50 MB.", "upgrade.uploadMultipleFiles.title": "Passa a un piano superiore per sbloccare i caricamenti in batch e i file di dimensioni maggiori", "upgrade.uploadMultiplePages.description": "Hai raggiunto il limite di caricamento: sul tuo piano attuale può essere selezionato e caricato un solo documento alla volta.", diff --git a/web/i18n/locales/ja-JP/billing.json b/web/i18n/locales/ja-JP/billing.json index 436bca4a009..c463002f26a 100644 --- a/web/i18n/locales/ja-JP/billing.json +++ b/web/i18n/locales/ja-JP/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "TRIGGER EVENTS", "upgrade.addChunks.description": "このプランでは、チャンク追加の上限に達しています。", "upgrade.addChunks.title": "アップグレードして、チャンクを引き続き追加できるようにしてください。", + "upgrade.agentRestore.description": "現在のプランでは、エージェントアプリのバージョンの復元は利用できません。", + "upgrade.agentRestore.title": "アップグレードしてエージェントアプリのバージョンを復元", "upgrade.uploadMultipleFiles.description": "複数のドキュメントを一度にアップロードでき、1ファイルあたりのサイズ上限も50 MBに引き上げられます。", "upgrade.uploadMultipleFiles.title": "アップグレードして一括アップロードと大容量ファイルを利用", "upgrade.uploadMultiplePages.description": "現在のプランではアップロード上限に達しています。1回の操作で選択・アップロードできるドキュメントは1つのみです。", diff --git a/web/i18n/locales/ko-KR/billing.json b/web/i18n/locales/ko-KR/billing.json index 7f8be34c418..0e9a21d59d2 100644 --- a/web/i18n/locales/ko-KR/billing.json +++ b/web/i18n/locales/ko-KR/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "트리거 이벤트", "upgrade.addChunks.description": "이 요금제에서는 더 이상 청크를 추가할 수 있는 한도에 도달했습니다.", "upgrade.addChunks.title": "계속해서 조각을 추가하려면 업그레이드하세요", + "upgrade.agentRestore.description": "현재 플랜에서는 에이전트 앱 버전 복원을 사용할 수 없습니다.", + "upgrade.agentRestore.title": "에이전트 앱 버전을 복원하려면 업그레이드하세요", "upgrade.uploadMultipleFiles.description": "여러 문서를 한 번에 업로드하고 파일당 최대 크기를 50MB로 늘리세요.", "upgrade.uploadMultipleFiles.title": "업그레이드하여 일괄 업로드와 대용량 파일을 이용하세요", "upgrade.uploadMultiplePages.description": "업로드 한도에 도달했습니다 — 현재 요금제에서는 한 번에 한 개의 문서만 선택하고 업로드할 수 있습니다.", diff --git a/web/i18n/locales/lo-LA/billing.json b/web/i18n/locales/lo-LA/billing.json index 0a8b63d3cf8..ed51dfa9681 100644 --- a/web/i18n/locales/lo-LA/billing.json +++ b/web/i18n/locales/lo-LA/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "ເຫດການຕົວເລີ່ມຕົ້ນ", "upgrade.addChunks.description": "ທ່ານໄດ້ໃຊ້ງານຮອດຂີດຈຳກັດໃນການເພີ່ມ Chunk ສຳລັບແພັກເກດນີ້ແລ້ວ.", "upgrade.addChunks.title": "ອັບເກຣດເພື່ອເພີ່ມ Chunk ຕໍ່", + "upgrade.agentRestore.description": "ການກູ້ຄືນເວີຊັນແອັບ Agent ບໍ່ສາມາດໃຊ້ງານໄດ້ໃນແພັກເກດປັດຈຸບັນຂອງທ່ານ.", + "upgrade.agentRestore.title": "ອັບເກຣດເພື່ອກູ້ຄືນເວີຊັນແອັບ Agent", "upgrade.uploadMultipleFiles.description": "ອັບໂຫລດເອກະສານຫຼາຍອັນພ້ອມກັນເພື່ອປະຢັດເວລາ ແລະ ເພີ່ມປະສິດທິພາບ.", "upgrade.uploadMultipleFiles.title": "ອັບເກຣດເພື່ອປົດລັອກການອັບໂຫລດເອກະສານແບບເປັນກຸ່ມ", "upgrade.uploadMultiplePages.description": "ທ່ານຮອດຂີດຈຳກັດການອັບໂຫລດແລ້ວ — ສາມາດເລືອກ ແລະ ອັບໂຫລດເອກະສານໄດ້ເທື່ອລະອັນໃນແພັກເກດປັດຈຸບັນ.", diff --git a/web/i18n/locales/nl-NL/billing.json b/web/i18n/locales/nl-NL/billing.json index d8fdb375b7c..6f31346fbdb 100644 --- a/web/i18n/locales/nl-NL/billing.json +++ b/web/i18n/locales/nl-NL/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "TRIGGER EVENTS", "upgrade.addChunks.description": "You’ve reached the limit of adding chunks for this plan.", "upgrade.addChunks.title": "Upgrade to continue adding chunks", + "upgrade.agentRestore.description": "Het herstellen van versies van de agent-app is niet beschikbaar in je huidige abonnement.", + "upgrade.agentRestore.title": "Upgrade om versies van de agent-app te herstellen", "upgrade.uploadMultipleFiles.description": "Upload meerdere documenten tegelijk en verhoog de maximale bestandsgrootte naar 50 MB.", "upgrade.uploadMultipleFiles.title": "Upgrade je abonnement om batchuploads en grotere bestanden te ontgrendelen", "upgrade.uploadMultiplePages.description": "You’ve reached the upload limit — only one document can be selected and uploaded at a time on your current plan.", diff --git a/web/i18n/locales/pl-PL/billing.json b/web/i18n/locales/pl-PL/billing.json index 566f19fc8d8..5f0ee8c2430 100644 --- a/web/i18n/locales/pl-PL/billing.json +++ b/web/i18n/locales/pl-PL/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "WYDARZENIA WYZWALAJĄCE", "upgrade.addChunks.description": "Osiągnąłeś limit dodawania fragmentów w tym planie.", "upgrade.addChunks.title": "Uaktualnij, aby kontynuować dodawanie fragmentów", + "upgrade.agentRestore.description": "Przywracanie wersji aplikacji agenta nie jest dostępne w obecnym planie.", + "upgrade.agentRestore.title": "Ulepsz plan, aby przywracać wersje aplikacji agenta", "upgrade.uploadMultipleFiles.description": "Przesyłaj wiele dokumentów jednocześnie i zwiększ maksymalny rozmiar pojedynczego pliku do 50 MB.", "upgrade.uploadMultipleFiles.title": "Przejdź na wyższy plan, aby odblokować przesyłanie zbiorcze i większe pliki", "upgrade.uploadMultiplePages.description": "Osiągnąłeś limit przesyłania — w ramach obecnego planu można wybrać i przesłać tylko jeden dokument naraz.", diff --git a/web/i18n/locales/pt-BR/billing.json b/web/i18n/locales/pt-BR/billing.json index 66901d210b6..6c1246601e3 100644 --- a/web/i18n/locales/pt-BR/billing.json +++ b/web/i18n/locales/pt-BR/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "EVENTOS DE GATILHO", "upgrade.addChunks.description": "Você atingiu o limite de adição de blocos para este plano.", "upgrade.addChunks.title": "Faça upgrade para continuar adicionando blocos", + "upgrade.agentRestore.description": "A restauração de versões do aplicativo de agente não está disponível no seu plano atual.", + "upgrade.agentRestore.title": "Faça upgrade para restaurar versões do aplicativo de agente", "upgrade.uploadMultipleFiles.description": "Envie vários documentos de uma só vez e aumente o tamanho máximo por arquivo para 50 MB.", "upgrade.uploadMultipleFiles.title": "Faça upgrade para liberar uploads em lote e arquivos maiores", "upgrade.uploadMultiplePages.description": "Você atingiu o limite de upload — apenas um documento pode ser selecionado e enviado por vez no seu plano atual.", diff --git a/web/i18n/locales/ro-RO/billing.json b/web/i18n/locales/ro-RO/billing.json index a8fa038ef9e..8d2fe1c6e62 100644 --- a/web/i18n/locales/ro-RO/billing.json +++ b/web/i18n/locales/ro-RO/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "EVENIMENTE DECLANȘATOARE", "upgrade.addChunks.description": "Ai atins limita de adăugare a segmentelor pentru acest plan.", "upgrade.addChunks.title": "Actualizează pentru a continua să adaugi segmente", + "upgrade.agentRestore.description": "Restaurarea versiunilor aplicației agent nu este disponibilă în planul tău actual.", + "upgrade.agentRestore.title": "Fă upgrade pentru a restaura versiunile aplicației agent", "upgrade.uploadMultipleFiles.description": "Încarcă mai multe documente simultan și mărește dimensiunea maximă pentru fiecare fișier la 50 MB.", "upgrade.uploadMultipleFiles.title": "Treci la un plan superior pentru a debloca încărcările în lot și fișierele mai mari", "upgrade.uploadMultiplePages.description": "Ați atins limita de încărcare — poate fi selectat și încărcat doar un singur document odată în planul dvs. actual.", diff --git a/web/i18n/locales/ru-RU/billing.json b/web/i18n/locales/ru-RU/billing.json index 3e0d130ac6c..135a5488ab7 100644 --- a/web/i18n/locales/ru-RU/billing.json +++ b/web/i18n/locales/ru-RU/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "СОБЫТИЯ-ИНИЦИАТОРЫ", "upgrade.addChunks.description": "Вы достигли предела добавления чанков по этому тарифному плану.", "upgrade.addChunks.title": "Обновите версию, чтобы продолжить добавление блоков", + "upgrade.agentRestore.description": "Восстановление версий приложения агента недоступно в вашем текущем плане.", + "upgrade.agentRestore.title": "Обновите план, чтобы восстанавливать версии приложения агента", "upgrade.uploadMultipleFiles.description": "Загружайте несколько документов одновременно и увеличьте максимальный размер одного файла до 50 МБ.", "upgrade.uploadMultipleFiles.title": "Перейдите на более высокий тариф, чтобы разблокировать пакетную загрузку и файлы большего размера", "upgrade.uploadMultiplePages.description": "Вы достигли лимита загрузки — на вашем текущем тарифном плане можно выбрать и загрузить только один документ за раз.", diff --git a/web/i18n/locales/sl-SI/billing.json b/web/i18n/locales/sl-SI/billing.json index 6a965eb97c3..e6feee1f0e4 100644 --- a/web/i18n/locales/sl-SI/billing.json +++ b/web/i18n/locales/sl-SI/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "SPROŽITVENI DOGODKI", "upgrade.addChunks.description": "Dosegli ste omejitev dodajanja delov za ta načrt.", "upgrade.addChunks.title": "Nadgradite, da nadaljujete z dodajanjem delov", + "upgrade.agentRestore.description": "Obnovitev različic aplikacije agenta v vašem trenutnem paketu ni na voljo.", + "upgrade.agentRestore.title": "Nadgradite za obnovitev različic aplikacije agenta", "upgrade.uploadMultipleFiles.description": "Naložite več dokumentov hkrati in povečajte največjo velikost posamezne datoteke na 50 MB.", "upgrade.uploadMultipleFiles.title": "Nadgradite paket, da odklenete paketno nalaganje in večje datoteke", "upgrade.uploadMultiplePages.description": "Dosegli ste omejitev nalaganja — na vašem trenutnem načrtu je mogoče izbrati in naložiti le en dokument naenkrat.", diff --git a/web/i18n/locales/th-TH/billing.json b/web/i18n/locales/th-TH/billing.json index a48941b8220..8d50b2891f3 100644 --- a/web/i18n/locales/th-TH/billing.json +++ b/web/i18n/locales/th-TH/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "เหตุการณ์ทริกเกอร์", "upgrade.addChunks.description": "คุณได้ถึงขีดจำกัดในการเพิ่มชิ้นส่วนสำหรับแผนนี้แล้ว", "upgrade.addChunks.title": "อัปเกรดเพื่อเพิ่มชิ้นส่วนต่อ", + "upgrade.agentRestore.description": "การกู้คืนเวอร์ชันแอปเอเจนต์ไม่พร้อมใช้งานในแผนปัจจุบันของคุณ", + "upgrade.agentRestore.title": "อัปเกรดเพื่อกู้คืนเวอร์ชันแอปเอเจนต์", "upgrade.uploadMultipleFiles.description": "อัปโหลดเอกสารหลายไฟล์พร้อมกัน และเพิ่มขนาดสูงสุดต่อไฟล์เป็น 50 MB", "upgrade.uploadMultipleFiles.title": "อัปเกรดเพื่อปลดล็อกการอัปโหลดแบบเป็นชุดและไฟล์ขนาดใหญ่ขึ้น", "upgrade.uploadMultiplePages.description": "คุณได้ถึงขีดจำกัดการอัปโหลดแล้ว — สามารถเลือกและอัปโหลดเอกสารได้เพียงไฟล์เดียวต่อครั้งในแผนปัจจุบันของคุณ", diff --git a/web/i18n/locales/tr-TR/billing.json b/web/i18n/locales/tr-TR/billing.json index 1a48ee18b17..371fa676801 100644 --- a/web/i18n/locales/tr-TR/billing.json +++ b/web/i18n/locales/tr-TR/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "TETİKLEYİCİ OLAYLAR", "upgrade.addChunks.description": "Bu plan için parça ekleme sınırına ulaştınız.", "upgrade.addChunks.title": "Parçalar eklemeye devam etmek için yükseltin", + "upgrade.agentRestore.description": "Ajan uygulaması sürümü geri yükleme mevcut planınızda kullanılamaz.", + "upgrade.agentRestore.title": "Ajan uygulaması sürümlerini geri yüklemek için yükseltin", "upgrade.uploadMultipleFiles.description": "Birden fazla belgeyi aynı anda yükleyin ve dosya başına maksimum boyutu 50 MB'a çıkarın.", "upgrade.uploadMultipleFiles.title": "Toplu yüklemelerin ve daha büyük dosyaların kilidini açmak için yükseltin", "upgrade.uploadMultiplePages.description": "Yükleme sınırına ulaştınız — mevcut planınızda aynı anda yalnızca bir belge seçip yükleyebilirsiniz.", diff --git a/web/i18n/locales/uk-UA/billing.json b/web/i18n/locales/uk-UA/billing.json index 41def182026..7b54159213b 100644 --- a/web/i18n/locales/uk-UA/billing.json +++ b/web/i18n/locales/uk-UA/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "ПОДІЇ-ТРИГЕРИ", "upgrade.addChunks.description": "Ви досягли межі додавання фрагментів для цього плану.", "upgrade.addChunks.title": "Оновіть, щоб продовжити додавати частини", + "upgrade.agentRestore.description": "Відновлення версій застосунку агента недоступне у вашому поточному плані.", + "upgrade.agentRestore.title": "Оновіть план, щоб відновлювати версії застосунку агента", "upgrade.uploadMultipleFiles.description": "Завантажуйте кілька документів одночасно та збільште максимальний розмір одного файлу до 50 МБ.", "upgrade.uploadMultipleFiles.title": "Перейдіть на вищий тариф, щоб розблокувати пакетне завантаження та більші файли", "upgrade.uploadMultiplePages.description": "Ви досягли ліміту завантаження — на вашому поточному плані можна вибрати та завантажити лише один документ одночасно.", diff --git a/web/i18n/locales/vi-VN/billing.json b/web/i18n/locales/vi-VN/billing.json index 24636225fbc..c74de88548c 100644 --- a/web/i18n/locales/vi-VN/billing.json +++ b/web/i18n/locales/vi-VN/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "SỰ KIỆN KÍCH HOẠT", "upgrade.addChunks.description": "Bạn đã đạt đến giới hạn thêm phần cho gói này.", "upgrade.addChunks.title": "Nâng cấp để tiếp tục thêm các phần", + "upgrade.agentRestore.description": "Tính năng khôi phục phiên bản ứng dụng tác tử không khả dụng trong gói hiện tại của bạn.", + "upgrade.agentRestore.title": "Nâng cấp để khôi phục các phiên bản ứng dụng tác tử", "upgrade.uploadMultipleFiles.description": "Tải lên nhiều tài liệu cùng lúc và tăng kích thước tối đa cho mỗi tệp lên 50 MB.", "upgrade.uploadMultipleFiles.title": "Nâng cấp để mở khóa tính năng tải lên hàng loạt và tệp có dung lượng lớn hơn", "upgrade.uploadMultiplePages.description": "Bạn đã đạt đến giới hạn tải lên — chỉ có thể chọn và tải lên một tài liệu trong một lần với gói hiện tại của bạn.", diff --git a/web/i18n/locales/zh-Hans/billing.json b/web/i18n/locales/zh-Hans/billing.json index 73ed83814b3..1965de8175d 100644 --- a/web/i18n/locales/zh-Hans/billing.json +++ b/web/i18n/locales/zh-Hans/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "触发事件额度", "upgrade.addChunks.description": "您已达到此计划的添加分段上限。", "upgrade.addChunks.title": "升级以继续添加分段", + "upgrade.agentRestore.description": "当前套餐不支持恢复 Agent 应用版本。", + "upgrade.agentRestore.title": "升级以恢复 Agent 应用版本", "upgrade.uploadMultipleFiles.description": "一次可上传多个文档,单个文件大小上限也将提升至 50 MB。", "upgrade.uploadMultipleFiles.title": "升级以解锁批量上传和更大的文件", "upgrade.uploadMultiplePages.description": "您已达到当前套餐的上传限制 —— 该套餐每次只能选择并上传 1 个文档。", diff --git a/web/i18n/locales/zh-Hant/billing.json b/web/i18n/locales/zh-Hant/billing.json index 33f0824a325..940ca6b0aad 100644 --- a/web/i18n/locales/zh-Hant/billing.json +++ b/web/i18n/locales/zh-Hant/billing.json @@ -160,6 +160,8 @@ "triggerLimitModal.usageTitle": "觸發事件", "upgrade.addChunks.description": "您已達到此方案可新增區塊的上限。", "upgrade.addChunks.title": "升級以繼續添加區塊", + "upgrade.agentRestore.description": "目前方案不支援還原 Agent 應用程式版本。", + "upgrade.agentRestore.title": "升級以還原 Agent 應用程式版本", "upgrade.uploadMultipleFiles.description": "一次上傳多份文件,並將單一檔案的大小上限提高至 50 MB。", "upgrade.uploadMultipleFiles.title": "升級方案,解鎖批次上傳與更大檔案", "upgrade.uploadMultiplePages.description": "您已達到上傳限制 — 在您目前的方案下,每次只能選擇並上傳一個文件。",