From 4cb5298768dc8c920f0e6d43e86f38b1dc29c484 Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Thu, 27 Aug 2026 01:43:06 +0200 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20migrate=20hardcoded=20German=20st?= =?UTF-8?q?rings=20to=20t()=20across=20104=20components/pages=20=E2=80=94?= =?UTF-8?q?=20AST-based=20batch=20with=20re-parse=20gate,=20423=20new=20de?= =?UTF-8?q?.json=20keys;=20tsc=20clean;=20vitest=20failures=20byte-identic?= =?UTF-8?q?al=20to=20clean-tree=20baseline=20(pre-existing)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 8 +- .../components/activity/ActivityFilter.tsx | 2 +- .../src/components/ai/ImprovementPanel.tsx | 23 +- .../src/components/ai/SuggestionBadge.tsx | 4 +- frontend/src/components/ai/SuggestionCard.tsx | 6 +- .../src/components/ai/SuggestionSidebar.tsx | 9 +- .../components/comm/blocks/BlockRenderer.tsx | 4 +- .../comm/blocks/ContactCardBlock.tsx | 4 +- .../components/comm/blocks/MiniAppBlock.tsx | 4 +- .../components/common/EntityHistoryPanel.tsx | 3 +- .../src/components/common/PrintButton.tsx | 8 +- .../components/common/SaveFilterDialog.tsx | 4 +- .../src/components/common/ShareDialog.tsx | 23 +- .../components/contacts/ContactEditForm.tsx | 6 +- .../components/contacts/ContactFolderTree.tsx | 17 +- .../src/components/contacts/ContactList.tsx | 22 +- .../src/components/contacts/FilterPanel.tsx | 22 +- .../contacts/FolderPermissionDialog.tsx | 20 +- .../src/components/contacts/GroupPanel.tsx | 12 +- .../components/contacts/SaveViewDialog.tsx | 12 +- .../src/components/contacts/SortPanel.tsx | 12 +- .../custom-fields/CustomFieldRenderer.tsx | 12 +- frontend/src/components/layout/AISidebar.tsx | 18 +- .../src/components/layout/MessageSidebar.tsx | 18 +- .../src/components/layout/PluginToolbar.tsx | 5 +- frontend/src/components/layout/Sidebar.tsx | 8 +- .../components/layout/SortableMenuItem.tsx | 4 +- frontend/src/components/layout/TopBar.tsx | 2 +- frontend/src/components/mail/ComposeModal.tsx | 8 +- .../src/components/mail/MailComposeForm.tsx | 8 +- .../src/components/mail/MailFilterPanel.tsx | 22 +- .../src/components/mail/MailFolderTree.tsx | 3 +- .../src/components/mail/MailGroupPanel.tsx | 12 +- .../src/components/mail/MailSortPanel.tsx | 12 +- frontend/src/components/mail/PgpSettings.tsx | 10 +- .../src/components/mail/RichTextEditor.tsx | 4 +- .../src/components/mail/SignatureManager.tsx | 2 +- .../notifications/NotificationItem.tsx | 6 +- .../plugins/PluginRouteRenderer.tsx | 8 +- .../components/settings/WorkspaceManager.tsx | 20 +- .../src/components/shared/ActivityFeed.tsx | 4 +- frontend/src/components/shared/DataGrid.tsx | 2 +- .../src/components/shared/SearchDropdown.tsx | 2 +- frontend/src/components/shared/TeamPanel.tsx | 10 +- frontend/src/components/tasks/TaskDetail.tsx | 2 +- frontend/src/components/ui/Modal.tsx | 4 +- frontend/src/components/ui/Pagination.tsx | 2 +- frontend/src/components/ui/Skeleton.tsx | 7 +- frontend/src/components/ui/Table.tsx | 6 +- frontend/src/components/ui/Toast.tsx | 4 +- .../src/components/window/AiChatPanel.tsx | 16 +- frontend/src/components/window/Window.tsx | 14 +- .../components/workflows/StepConfigPanel.tsx | 60 +- .../components/workflows/WorkflowEditor.tsx | 20 +- .../workflows/WorkflowInstanceList.tsx | 8 +- frontend/src/i18n/locales/de.json | 631 +++++++++++++++++- frontend/src/pages/AISettings.tsx | 37 +- frontend/src/pages/AgentDashboard.tsx | 8 +- frontend/src/pages/Agents.tsx | 9 +- frontend/src/pages/AuditLog.tsx | 6 +- frontend/src/pages/Automation.tsx | 9 +- frontend/src/pages/AutomationDashboard.tsx | 18 +- frontend/src/pages/AutomationSettings.tsx | 12 +- frontend/src/pages/Communication.tsx | 23 +- frontend/src/pages/ContactsList.tsx | 8 +- frontend/src/pages/CustomFields.tsx | 6 +- frontend/src/pages/Dashboard.tsx | 6 +- frontend/src/pages/GuestContacts.tsx | 4 +- frontend/src/pages/GuestLogin.tsx | 4 +- frontend/src/pages/Help.tsx | 6 +- frontend/src/pages/ImportExport.tsx | 2 +- frontend/src/pages/Logs.tsx | 9 +- frontend/src/pages/Mail.tsx | 4 +- frontend/src/pages/MailSettings.tsx | 14 +- frontend/src/pages/NoAccessPage.tsx | 9 +- frontend/src/pages/Reports.tsx | 2 +- frontend/src/pages/Settings.tsx | 4 +- frontend/src/pages/SettingsBackup.tsx | 2 +- frontend/src/pages/SettingsMcp.tsx | 2 +- frontend/src/pages/SettingsPlugins.tsx | 2 +- frontend/src/pages/SettingsRechte.tsx | 12 +- frontend/src/pages/SettingsSequences.tsx | 2 +- frontend/src/pages/SettingsStammdaten.tsx | 18 +- frontend/src/pages/SettingsSystem.tsx | 2 +- frontend/src/pages/SettingsTaxes.tsx | 2 +- frontend/src/pages/SettingsTheme.tsx | 16 +- frontend/src/pages/SettingsUserManagement.tsx | 2 +- frontend/src/pages/SettingsUsers.tsx | 2 +- frontend/src/pages/StartPage.tsx | 8 +- frontend/src/pages/Tasks.tsx | 10 +- frontend/src/pages/Workflows.tsx | 16 +- frontend/src/pages/agents/AgentsOverview.tsx | 4 +- .../src/pages/agents/AgentsPlaceholder.tsx | 4 +- .../pages/automation/AutomationOverview.tsx | 10 +- .../automation/AutomationPlaceholder.tsx | 4 +- frontend/src/pages/help/HelpApiDocs.tsx | 24 +- frontend/src/pages/help/HelpContacts.tsx | 14 +- frontend/src/pages/help/HelpLogin.tsx | 16 +- frontend/src/pages/help/HelpMailSetup.tsx | 22 +- frontend/src/pages/help/HelpNavigation.tsx | 14 +- frontend/src/pages/help/HelpPlaceholder.tsx | 6 +- frontend/src/pages/help/HelpWelcome.tsx | 30 +- frontend/src/pages/logs/LogsOverview.tsx | 12 +- frontend/src/pages/logs/LogsPlaceholder.tsx | 4 +- frontend/src/routes/index.tsx | 4 +- 105 files changed, 1204 insertions(+), 459 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 013f484..5758755 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -8,9 +8,11 @@ import { useThemeStore } from '@/store/themeStore'; import { ErrorBoundary } from '@/components/common/ErrorBoundary'; import { useToast } from '@/components/ui/Toast'; import { useOnlineStatus } from '@/hooks/useOnlineStatus'; +import { useTranslation } from 'react-i18next'; function QueryClientWrapper({ children }: { children: React.ReactNode }) { + const { t } = useTranslation(); const toast = useToast(); const [queryClient] = React.useState(() => new QueryClient({ @@ -40,18 +42,20 @@ function QueryClientWrapper({ children }: { children: React.ReactNode }) { } function OfflineBanner() { + const { t } = useTranslation(); const isOnline = useOnlineStatus(); if (isOnline) return null; return (
- Sie sind offline. Änderungen werden gespeichert wenn die Verbindung wiederhergestellt ist. + {t('app.siesindofflineänderungenwerdengespeicher')}
); } export default function App() { + const { t } = useTranslation(); const { logout } = useAuthStore(); const loadThemeFromStorage = useThemeStore((s) => s.loadFromStorage); const toast = useToast(); @@ -76,7 +80,7 @@ export default function App() { href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-[300] focus:px-4 focus:py-2 focus:bg-primary-600 focus:text-white focus:rounded-md" > - Zum Hauptinhalt springen + {t('app.zumhauptinhaltspringen')} diff --git a/frontend/src/components/activity/ActivityFilter.tsx b/frontend/src/components/activity/ActivityFilter.tsx index e670683..32b1181 100644 --- a/frontend/src/components/activity/ActivityFilter.tsx +++ b/frontend/src/components/activity/ActivityFilter.tsx @@ -80,7 +80,7 @@ export function ActivityFilter({ onFilter, initialValues }: ActivityFilterProps) type="text" value={user} onChange={(e) => setUser(e.target.value)} - placeholder="Benutzername" + placeholder={t('activityFilter.benutzername')} className="block w-full rounded-md border border-secondary-300 px-3 py-2 text-base min-h-touch text-secondary-900 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500" /> diff --git a/frontend/src/components/ai/ImprovementPanel.tsx b/frontend/src/components/ai/ImprovementPanel.tsx index cca6328..07f4f87 100644 --- a/frontend/src/components/ai/ImprovementPanel.tsx +++ b/frontend/src/components/ai/ImprovementPanel.tsx @@ -6,10 +6,12 @@ import { useState } from 'react'; import { useSignals, useCollectSignals, usePatterns, useDetectPatterns, useProposals, useEvaluateProposal, useActivateProposal, useRollbackProposal, useMeasureImpact } from '@/api/improvement'; import { TrendingUp, AlertCircle, CheckCircle, RefreshCw, Play, RotateCcw, BarChart3 } from 'lucide-react'; +import { useTranslation } from 'react-i18next'; type SubView = 'signals' | 'patterns' | 'proposals'; export function ImprovementPanel() { + const { t } = useTranslation(); const [subView, setSubView] = useState('signals'); return ( @@ -47,6 +49,7 @@ export function ImprovementPanel() { } function SignalsView() { + const { t } = useTranslation(); const { data, isLoading } = useSignals(1, 20); const collectMut = useCollectSignals(); const signals = data?.items ?? []; @@ -59,7 +62,7 @@ function SignalsView() { onClick={() => collectMut.mutate({ limit: 100 })} disabled={collectMut.isPending} className="inline-flex items-center gap-1 px-2 py-1 rounded text-xs font-medium text-primary-600 hover:bg-primary-50 disabled:opacity-50 min-h-touch" - aria-label="Signale sammeln" + aria-label={t('improvementPanel.signalesammeln')} >