diff --git a/src/components/FlowEditor/nodes/start/ScheduleStartNodeConfig.tsx b/src/components/FlowEditor/nodes/start/ScheduleStartNodeConfig.tsx index 479712a..d144771 100644 --- a/src/components/FlowEditor/nodes/start/ScheduleStartNodeConfig.tsx +++ b/src/components/FlowEditor/nodes/start/ScheduleStartNodeConfig.tsx @@ -28,20 +28,13 @@ function _getModeOptions(t: (key: string) => string): { value: ScheduleMode; tit ]; } -const MONTH_NAMES_DE = [ - 'Januar', - 'Februar', - 'März', - 'April', - 'Mai', - 'Juni', - 'Juli', - 'August', - 'September', - 'Oktober', - 'November', - 'Dezember', -]; +function _monthNames(t: (k: string) => string): string[] { + return [ + t('Januar'), t('Februar'), t('März'), t('April'), + t('Mai'), t('Juni'), t('Juli'), t('August'), + t('September'), t('Oktober'), t('November'), t('Dezember'), + ]; +} function _getIntervalUnits(t: (key: string) => string): { value: IntervalUnit; label: string; title: string }[] { return [ @@ -285,7 +278,7 @@ export const ScheduleStartNodeConfig: React.FC = ({ par
{t('Wochentage')}
- {WEEKDAYS_MO_SO.map(({ cronDow, label }) => ( + {WEEKDAYS_MO_SO.map(({ cronDow }) => ( ))}
@@ -365,9 +358,9 @@ export const ScheduleStartNodeConfig: React.FC = ({ par value={spec.monthIndex} onChange={(e) => push({ ...spec, monthIndex: Number(e.target.value) })} > - {MONTH_NAMES_DE.map((name, i) => ( + {_monthNames(t).map((name, i) => ( ))} diff --git a/src/components/FlowEditor/nodes/switch/SwitchNodeConfig.tsx b/src/components/FlowEditor/nodes/switch/SwitchNodeConfig.tsx index 5135cb7..647abda 100644 --- a/src/components/FlowEditor/nodes/switch/SwitchNodeConfig.tsx +++ b/src/components/FlowEditor/nodes/switch/SwitchNodeConfig.tsx @@ -117,7 +117,7 @@ export const SwitchNodeConfig: React.FC = ({ params, up {mimeTypeOptions.map((o) => ( ))} @@ -221,7 +221,7 @@ export const SwitchNodeConfig: React.FC = ({ params, up > {operators.map((o) => ( ))} diff --git a/src/components/FormGenerator/ActionButtons/CustomActionButton/CustomActionButton.tsx b/src/components/FormGenerator/ActionButtons/CustomActionButton/CustomActionButton.tsx index 51eb11c..8458ab3 100644 --- a/src/components/FormGenerator/ActionButtons/CustomActionButton/CustomActionButton.tsx +++ b/src/components/FormGenerator/ActionButtons/CustomActionButton/CustomActionButton.tsx @@ -53,7 +53,7 @@ export function CustomActionButton({ if (typeof title === 'function') { buttonTitle = title(row); } else if (typeof title === 'string') { - buttonTitle = t(title, title); // Try to translate, fallback to original + buttonTitle = title; } // Determine the final tooltip diff --git a/src/components/Navigation/MandateNavigation.tsx b/src/components/Navigation/MandateNavigation.tsx index bda6857..b7ae1b0 100644 --- a/src/components/Navigation/MandateNavigation.tsx +++ b/src/components/Navigation/MandateNavigation.tsx @@ -258,7 +258,7 @@ export const MandateNavigation: React.FC = () => { for (const sg of systemBlock.subgroups) { children.push({ id: sg.id, - label: t(sg.title), + label: sg.title, children: sg.items.map(i => navigationItemToTreeNode(i, t)), defaultExpanded: true, }); @@ -288,7 +288,7 @@ export const MandateNavigation: React.FC = () => { if (items.length > 0) items.push({ type: 'separator' }); const subgroupNodes: TreeNodeItem[] = adminSubgroups.map(sg => ({ id: sg.id, - label: t(sg.title), + label: sg.title, children: sg.items.map(i => navigationItemToTreeNode(i, t)), defaultExpanded: false, })); diff --git a/src/components/ProviderSelector/ProviderSelector.tsx b/src/components/ProviderSelector/ProviderSelector.tsx index 43a073f..dbc421d 100644 --- a/src/components/ProviderSelector/ProviderSelector.tsx +++ b/src/components/ProviderSelector/ProviderSelector.tsx @@ -87,9 +87,9 @@ const _PROVIDER_LABEL_KEYS: Record = { internal: 'Internal', }; -function _providerLabel(provider: string, t: (key: string) => string): string { +function _providerLabel(provider: string): string { const key = _PROVIDER_LABEL_KEYS[provider]; - return key ? t(key) : provider; + return key ? key : provider; } const PROVIDER_ICONS: Record = { @@ -135,7 +135,7 @@ export const ProviderSelect: React.FC = ({ value, const providerOptions = useMemo(() => { return allowedProviders.map((provider) => ({ value: provider, - label: `${PROVIDER_ICONS[provider] || '🔌'} ${_providerLabel(provider, t)}`, + label: `${PROVIDER_ICONS[provider] || '🔌'} ${_providerLabel(provider)}`, })); }, [allowedProviders, t]); @@ -325,7 +325,7 @@ export const ProviderMultiSelect: React.FC = ({ /> {PROVIDER_ICONS[provider] || '🔌'} - {_providerLabel(provider, t)} + {_providerLabel(provider)} ))} @@ -361,7 +361,7 @@ export const ProviderBadges: React.FC = ({
{providers.map((provider) => ( - {PROVIDER_ICONS[provider] || '🔌'} {_providerLabel(provider, t)} + {PROVIDER_ICONS[provider] || '🔌'} {_providerLabel(provider)} ))}
diff --git a/src/components/UiComponents/Button/CreateButton/CreateButton.tsx b/src/components/UiComponents/Button/CreateButton/CreateButton.tsx index 565d1a7..63a2320 100644 --- a/src/components/UiComponents/Button/CreateButton/CreateButton.tsx +++ b/src/components/UiComponents/Button/CreateButton/CreateButton.tsx @@ -144,21 +144,8 @@ const CreateButton: React.FC = ({ const isDisabled = disabled || loading || isCreating; - // Resolve language text for popup title - const resolvedPopupTitle = typeof popupTitle === 'string' - ? t(popupTitle, popupTitle) - : popupTitle; - - // Resolve language text for attributes - const resolvedAttributes: AttributeDefinition[] = useMemo(() => { - return attributes.map(attr => ({ - ...attr, - label: typeof attr.label === 'string' ? t(attr.label, attr.label) : attr.label, - placeholder: attr.placeholder - ? (typeof attr.placeholder === 'string' ? t(attr.placeholder, attr.placeholder) : attr.placeholder) - : undefined - })); - }, [attributes, t]); + const resolvedPopupTitle = popupTitle; + const resolvedAttributes = attributes; return ( <> diff --git a/src/components/UiComponents/Log/Log.tsx b/src/components/UiComponents/Log/Log.tsx index c3d15db..2891dcc 100644 --- a/src/components/UiComponents/Log/Log.tsx +++ b/src/components/UiComponents/Log/Log.tsx @@ -23,13 +23,13 @@ const getStatusBadgeClass = (status?: string | null): string => { const Log: React.FC = ({ className = '', - emptyMessage = 'Keine Log-Informationen verfügbar', + emptyMessage, dashboardTree, onToggleOperationExpanded, getChildOperations }) => { const { t } = useLanguage(); - const resolvedEmptyMessage = typeof emptyMessage === 'string' ? t(emptyMessage, emptyMessage) : emptyMessage; + const resolvedEmptyMessage = emptyMessage || t('Keine Log-Informationen verfügbar'); const formatLogTimestamp = (timestamp: number): string => { try { const formatted = formatUnixTimestamp(timestamp, undefined, { diff --git a/src/components/UiComponents/MapView/MapViewLeaflet.tsx b/src/components/UiComponents/MapView/MapViewLeaflet.tsx index 08905b8..99e09d2 100644 --- a/src/components/UiComponents/MapView/MapViewLeaflet.tsx +++ b/src/components/UiComponents/MapView/MapViewLeaflet.tsx @@ -48,7 +48,7 @@ const MapViewLeaflet: React.FC = ({ parcels = [], onParcelClick, height = '600px', className = '', - emptyMessage = 'Klicken Sie auf die Karte, um einen Standort auszuwählen', + emptyMessage, showWfsParcels = false, parcelsApiBaseUrl = '' }) => { @@ -361,7 +361,7 @@ const MapViewLeaflet: React.FC = ({ parcels = [],
{parcels.length === 0 && !center && (
-

{typeof emptyMessage === 'string' ? t(emptyMessage, emptyMessage) : emptyMessage}

+

{emptyMessage || t('Klicken Sie auf die Karte, um einen Standort auszuwählen')}

)} {showWfsParcels && isWfsLoading && ( diff --git a/src/components/UiComponents/Messages/Messages.tsx b/src/components/UiComponents/Messages/Messages.tsx index 2dd4a8b..bf09661 100644 --- a/src/components/UiComponents/Messages/Messages.tsx +++ b/src/components/UiComponents/Messages/Messages.tsx @@ -16,7 +16,7 @@ const Messages: React.FC = ({ showProgress = true, renderMessage, renderDocument, - emptyMessage = 'Noch keine Nachrichten', + emptyMessage, onFileDelete, onFileRemove, onFileView, @@ -30,7 +30,7 @@ const Messages: React.FC = ({ deletingMessages }) => { const { t } = useLanguage(); - const resolvedEmptyMessage = typeof emptyMessage === 'string' ? t(emptyMessage, emptyMessage) : emptyMessage; + const resolvedEmptyMessage = emptyMessage || t('Noch keine Nachrichten'); if (!messages || messages.length === 0) { return (
diff --git a/src/components/UnifiedDataBar/UnifiedDataBar.tsx b/src/components/UnifiedDataBar/UnifiedDataBar.tsx index 603de95..35c5e00 100644 --- a/src/components/UnifiedDataBar/UnifiedDataBar.tsx +++ b/src/components/UnifiedDataBar/UnifiedDataBar.tsx @@ -30,11 +30,14 @@ interface UnifiedDataBarProps { className?: string; } -const _TAB_KEYS: Record = { - chats: 'Chatverläufe', - files: 'Dateien', - sources: 'Quellen', -}; +function _tabLabel(tab: UdbTab, t: (k: string) => string): string { + switch (tab) { + case 'chats': return t('Chatverläufe'); + case 'files': return t('Dateien'); + case 'sources': return t('Quellen'); + default: return tab; + } +} const UnifiedDataBar: React.FC = ({ context, @@ -72,7 +75,7 @@ const UnifiedDataBar: React.FC = ({ className={`${styles.tab} ${currentTab === tab ? styles.tabActive : ''}`} onClick={() => _handleTabChange(tab)} > - {t(_TAB_KEYS[tab])} + {_tabLabel(tab, t)} ))}
diff --git a/src/core/PageManager/SidebarProvider.tsx b/src/core/PageManager/SidebarProvider.tsx index 294628f..08558e2 100644 --- a/src/core/PageManager/SidebarProvider.tsx +++ b/src/core/PageManager/SidebarProvider.tsx @@ -82,23 +82,10 @@ export const SidebarProvider: React.FC = ({ children }) => } // Helper function to resolve node name - const resolveNodeName = (pathSegment: string, fullPath: string, page?: GenericPageData): string => { + const resolveNodeName = (pathSegment: string, _fullPath: string, page?: GenericPageData): string => { if (page) { return resolveLanguageText(page.name, t); } - // Try translation key (e.g., "start.real-estate.title") - const translationKey = `${fullPath}.title`; - const translated = t(translationKey); - if (translated !== translationKey) { - return translated; - } - // Try just the segment (e.g., "real-estate.title") - const segmentKey = `${pathSegment}.title`; - const segmentTranslated = t(segmentKey); - if (segmentTranslated !== segmentKey) { - return segmentTranslated; - } - // Fallback to capitalized segment return pathSegment.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(' '); }; diff --git a/src/layouts/FeatureLayout.tsx b/src/layouts/FeatureLayout.tsx index 5771983..ae68fd9 100644 --- a/src/layouts/FeatureLayout.tsx +++ b/src/layouts/FeatureLayout.tsx @@ -82,11 +82,11 @@ export const FeatureLayout: React.FC = () => { ? navFeature.instances.find(i => i.id === instanceId) : undefined; return { - mandate: t(navMandate.uiLabel), - feature: navFeature ? t(navFeature.uiLabel) : undefined, - instance: navInstance ? t(navInstance.uiLabel) : undefined, + mandate: navMandate.uiLabel, + feature: navFeature ? navFeature.uiLabel : undefined, + instance: navInstance ? navInstance.uiLabel : undefined, }; - }, [dynamicBlock, mandateId, featureCode, instanceId, t]); + }, [dynamicBlock, mandateId, featureCode, instanceId]); // Warten bis Features geladen sind if (!initialized || loading || isLoading) { diff --git a/src/pages/AutomationsDashboardPage.tsx b/src/pages/AutomationsDashboardPage.tsx index daea727..0494122 100644 --- a/src/pages/AutomationsDashboardPage.tsx +++ b/src/pages/AutomationsDashboardPage.tsx @@ -171,7 +171,7 @@ export const AutomationsDashboardPage: React.FC = () => { filterable: true, formatter: (v: string) => ( - {t(v === 'completed' ? 'Abgeschlossen' : v === 'failed' ? 'Fehlgeschlagen' : v === 'running' ? 'Laufend' : v)} + {v === 'completed' ? t('Abgeschlossen') : v === 'failed' ? t('Fehlgeschlagen') : v === 'running' ? t('Laufend') : v} ), }, diff --git a/src/pages/Store.tsx b/src/pages/Store.tsx index dac5675..03f07ff 100644 --- a/src/pages/Store.tsx +++ b/src/pages/Store.tsx @@ -29,11 +29,9 @@ const STORE_FEATURE_DESCRIPTION_FALLBACK: Record = { commcoach: 'CommCoach: Kommunikation trainieren mit KI-gestütztem Coaching und Feedback.', }; -function _storeCardDescription(feature: StoreFeature, t: (key: string, fallback?: string) => string): string { - const raw = - (feature.description && feature.description.trim()) || - STORE_FEATURE_DESCRIPTION_FALLBACK[feature.featureCode]; - return raw ? t(raw) : ''; +function _storeCardDescription(feature: StoreFeature): string { + return (feature.description && feature.description.trim()) || + STORE_FEATURE_DESCRIPTION_FALLBACK[feature.featureCode] || ''; } interface FeatureCardProps { @@ -62,13 +60,13 @@ const FeatureCard: React.FC = ({
{icon && {icon}}

- {t(feature.label)} + {feature.label}

- {_storeCardDescription(feature, t)} + {_storeCardDescription(feature)}

diff --git a/src/pages/admin/AccessManagementHub.tsx b/src/pages/admin/AccessManagementHub.tsx index 232471c..3a8565d 100644 --- a/src/pages/admin/AccessManagementHub.tsx +++ b/src/pages/admin/AccessManagementHub.tsx @@ -29,8 +29,8 @@ function getMandateName(mandate: Mandate): string { return mandate.label || mandate.name || mandate.id; } -function getFeatureLabel(feature: Feature, t: (k: string) => string): string { - return t(feature.label || feature.code); +function getFeatureLabel(feature: Feature): string { + return feature.label || feature.code; } export interface InstanceWithStats extends FeatureInstance { @@ -165,7 +165,7 @@ export const AccessManagementHub: React.FC = () => { instance, mandateId: mandateId || '', mandateName: mandate ? getMandateName(mandate) : mandateId || '', - featureLabel: feature ? getFeatureLabel(feature, t) : instance.featureCode, + featureLabel: feature ? getFeatureLabel(feature) : instance.featureCode, }); }; @@ -294,7 +294,7 @@ export const AccessManagementHub: React.FC = () => { return { id: inst.id, label: inst.label, - featureLabel: feature ? getFeatureLabel(feature, t) : inst.featureCode, + featureLabel: feature ? getFeatureLabel(feature) : inst.featureCode, userCount: inst.userCount ?? 0, }; }), @@ -363,7 +363,7 @@ export const AccessManagementHub: React.FC = () => { {features.map((f) => ( ))} @@ -424,7 +424,7 @@ export const AccessManagementHub: React.FC = () => { instancesByMandate={instancesByMandate} instanceUsersMap={instanceUsersMap} features={features} - getFeatureLabel={(f) => getFeatureLabel(f, t)} + getFeatureLabel={getFeatureLabel} loading={hierarchyUsersLoading} onOpenDetail={handleOpenDetail} /> @@ -526,7 +526,7 @@ export const AccessManagementHub: React.FC = () => {
- {getFeatureLabel(features.find((f) => f.code === inst.featureCode) || { code: inst.featureCode, label: inst.featureCode }, t)} + {getFeatureLabel(features.find((f) => f.code === inst.featureCode) || { code: inst.featureCode, label: inst.featureCode })} {inst.userCount ?? '—'} {t('Benutzer')} diff --git a/src/pages/admin/AdminFeatureAccessPage.tsx b/src/pages/admin/AdminFeatureAccessPage.tsx index 7a0707a..81973bb 100644 --- a/src/pages/admin/AdminFeatureAccessPage.tsx +++ b/src/pages/admin/AdminFeatureAccessPage.tsx @@ -92,10 +92,7 @@ export const AdminFeatureAccessPage: React.FC = () => { { key: 'featureCode', label: t('Feature'), type: 'string' as const, sortable: true, filterable: true, width: 150, render: (value: string) => { const feature = features.find(f => f.code === value); - if (feature) { - return t(feature.label || value); - } - return value; + return feature ? (feature.label || value) : value; } }, { key: 'enabled', label: t('Aktiv'), type: 'boolean' as const, sortable: true, filterable: true, width: 80 }, @@ -323,10 +320,7 @@ export const AdminFeatureAccessPage: React.FC = () => { // Get feature label const getFeatureLabel = (code: string) => { const feature = features.find(f => f.code === code); - if (feature) { - return t(feature.label || code); - } - return code; + return feature ? (feature.label || code) : code; }; if (error && !selectedMandateId) { @@ -514,7 +508,7 @@ export const AdminFeatureAccessPage: React.FC = () => { ({ id: f.code, - label: t(f.label || f.code), + label: f.label || f.code, value: f.code }))} selectedItemId={createFeatureCode} diff --git a/src/pages/admin/AdminFeatureInstanceUsersPage.tsx b/src/pages/admin/AdminFeatureInstanceUsersPage.tsx index 76ab349..e69068d 100644 --- a/src/pages/admin/AdminFeatureInstanceUsersPage.tsx +++ b/src/pages/admin/AdminFeatureInstanceUsersPage.tsx @@ -367,10 +367,7 @@ export const AdminFeatureInstanceUsersPage: React.FC = () => { // Get feature label const getFeatureLabel = (code: string) => { const feature = features.find(f => f.code === code); - if (feature) { - return t(feature.label || code); - } - return code; + return feature ? (feature.label || code) : code; }; // Get selected instance info from combined options diff --git a/src/pages/admin/AdminFeatureRolesPage.tsx b/src/pages/admin/AdminFeatureRolesPage.tsx index 3a4069f..858b932 100644 --- a/src/pages/admin/AdminFeatureRolesPage.tsx +++ b/src/pages/admin/AdminFeatureRolesPage.tsx @@ -260,10 +260,8 @@ export const AdminFeatureRolesPage: React.FC = () => { setEditingRole(role); }; - // Get feature name - Backend uses 'label' field (German i18n key or legacy multilingual) const getFeatureName = (feature: Feature) => { - const raw = getTextValue(feature.label || feature.name); - return raw === '-' ? '-' : t(raw); + return feature.label || feature.name || '-'; }; if (error && !selectedFeatureCode) { diff --git a/src/pages/admin/wizards/AdminMandateWizardPage.tsx b/src/pages/admin/wizards/AdminMandateWizardPage.tsx index 6a20c51..ff239cc 100644 --- a/src/pages/admin/wizards/AdminMandateWizardPage.tsx +++ b/src/pages/admin/wizards/AdminMandateWizardPage.tsx @@ -109,10 +109,7 @@ export const AdminMandateWizardPage: React.FC = () => { const getFeatureLabel = (code: string): string => { const f = features.find(feat => feat.code === code); - if (f) { - return t(f.label || code); - } - return code; + return f ? (f.label || code) : code; }; const getUserDisplayName = (u: { fullName?: string; firstname?: string | null; lastname?: string | null; username: string }): string => { diff --git a/src/pages/admin/wizards/FeatureInstanceWizard.tsx b/src/pages/admin/wizards/FeatureInstanceWizard.tsx index 9e14960..ef9ab11 100644 --- a/src/pages/admin/wizards/FeatureInstanceWizard.tsx +++ b/src/pages/admin/wizards/FeatureInstanceWizard.tsx @@ -57,8 +57,8 @@ export const FeatureInstanceWizard: React.FC = ({ ma const [selectedUserRoles, setSelectedUserRoles] = useState>([]); const featureOptions = useMemo( - () => features.map((f) => ({ value: f.code, label: t(f.label || f.code) })), - [features, t] + () => features.map((f) => ({ value: f.code, label: f.label || f.code })), + [features] ); const mandateOptions = useMemo( () => mandates.map((m) => ({ value: m.id, label: getMandateName(m) })), diff --git a/src/pages/views/commcoach/CommcoachDossierView.tsx b/src/pages/views/commcoach/CommcoachDossierView.tsx index 55f97d9..b4ca96c 100644 --- a/src/pages/views/commcoach/CommcoachDossierView.tsx +++ b/src/pages/views/commcoach/CommcoachDossierView.tsx @@ -858,7 +858,7 @@ export const CommcoachDossierView: React.FC = ({ pers {_groupScoresByDimension(coach.scores).map(group => (
- {t(_dimensionLabel(group.dimension))} + {_dimensionLabel(group.dimension, t)} {Math.round(group.latest.score)}/100 {group.latest.trend === 'improving' ? 'steigend' : group.latest.trend === 'declining' ? 'sinkend' : 'stabil'} @@ -926,13 +926,15 @@ function _groupScoresByDimension(scores: any[]): ScoreGroup[] { return Object.values(groups); } -function _dimensionLabel(dim: string): string { - const labels: Record = { - empathy: 'Einfühlungsvermögen', clarity: 'Klarheit', - assertiveness: 'Durchsetzung', listening: 'Zuhören', - selfReflection: 'Selbstreflexion', - }; - return labels[dim] || dim; +function _dimensionLabel(dim: string, t: (k: string) => string): string { + switch (dim) { + case 'empathy': return t('Einfühlungsvermögen'); + case 'clarity': return t('Klarheit'); + case 'assertiveness': return t('Durchsetzung'); + case 'listening': return t('Zuhören'); + case 'selfReflection': return t('Selbstreflexion'); + default: return dim; + } } function _formatToolPayload(payload: Record): string { diff --git a/src/pages/views/graphicalEditor/GraphicalEditorWorkflowsTasksPage.tsx b/src/pages/views/graphicalEditor/GraphicalEditorWorkflowsTasksPage.tsx index 96daa7f..bbf2427 100644 --- a/src/pages/views/graphicalEditor/GraphicalEditorWorkflowsTasksPage.tsx +++ b/src/pages/views/graphicalEditor/GraphicalEditorWorkflowsTasksPage.tsx @@ -30,15 +30,18 @@ import styles from './Automation2WorkflowsTasks.module.css'; import { useLanguage } from '../../../providers/language/LanguageContext'; -const NODE_TYPE_LABELS: Record = { - 'input.form': 'Formular', - 'input.approval': 'Genehmigung', - 'input.upload': 'Upload', - 'input.comment': 'Kommentar', - 'input.review': 'Prüfung', - 'input.selection': 'Auswahl', - 'input.confirmation': 'Bestätigung', -}; +function _nodeTypeLabel(nodeType: string, t: (k: string) => string): string { + switch (nodeType) { + case 'input.form': return t('Formular'); + case 'input.approval': return t('Genehmigung'); + case 'input.upload': return t('Upload'); + case 'input.comment': return t('Kommentar'); + case 'input.review': return t('Prüfung'); + case 'input.selection': return t('Auswahl'); + case 'input.confirmation': return t('Bestätigung'); + default: return nodeType; + } +} function formatTimestamp(ts?: number): string { if (ts == null || ts <= 0) return '—'; @@ -941,7 +944,7 @@ const TaskCard: React.FC = ({
{t('Typ')} - {t(NODE_TYPE_LABELS[nodeType] ?? nodeType)} + {_nodeTypeLabel(nodeType, t)}
diff --git a/src/pages/views/trustee/TrusteeAbschlussView.tsx b/src/pages/views/trustee/TrusteeAbschlussView.tsx index 6418a87..0aa0612 100644 --- a/src/pages/views/trustee/TrusteeAbschlussView.tsx +++ b/src/pages/views/trustee/TrusteeAbschlussView.tsx @@ -30,14 +30,19 @@ const _TABS: TabDef[] = [ { id: 'year-end', templateTag: 'template:trustee-year-end-check', icon: '\u2705', color: '#795548' }, ]; -const _TAB_LABEL_KEYS: Record = { - 'year-end': 'Jahresabschluss prüfen', -}; +function _tabLabel(tabId: string, t: (k: string) => string): string { + switch (tabId) { + case 'year-end': return t('Jahresabschluss prüfen'); + default: return tabId; + } +} -const _TAB_DESCRIPTION_KEYS: Record = { - 'year-end': - 'Automatische Prüfungen für den Jahresabschluss: Saldovalidierung, Vorjahresvergleich, gesetzliche Checks.', -}; +function _tabDescription(tabId: string, t: (k: string) => string): string { + switch (tabId) { + case 'year-end': return t('Automatische Prüfungen für den Jahresabschluss: Saldovalidierung, Vorjahresvergleich, gesetzliche Checks.'); + default: return ''; + } +} // --------------------------------------------------------------------------- // Types @@ -225,7 +230,7 @@ export const TrusteeAbschlussView: React.FC = () => { }} > {tab.icon} - {t(_TAB_LABEL_KEYS[tab.id] || tab.id)} + {_tabLabel(tab.id, t)} ))}
@@ -234,7 +239,7 @@ export const TrusteeAbschlussView: React.FC = () => { {/* Tab content */}

- {_TAB_DESCRIPTION_KEYS[activeTab] ? t(_TAB_DESCRIPTION_KEYS[activeTab]) : ''} + {_tabDescription(activeTab, t)}

{workflowsLoading ? ( diff --git a/src/pages/views/trustee/TrusteeAnalyseView.tsx b/src/pages/views/trustee/TrusteeAnalyseView.tsx index cae4a3a..c32883f 100644 --- a/src/pages/views/trustee/TrusteeAnalyseView.tsx +++ b/src/pages/views/trustee/TrusteeAnalyseView.tsx @@ -33,19 +33,25 @@ const _TABS: TabDef[] = [ { id: 'forecast', templateTag: 'template:trustee-forecast', icon: '\uD83D\uDCC8', color: '#E91E63' }, ]; -const _TAB_LABEL_KEYS: Record = { - budget: 'Budget-Vergleich', - kpi: 'KPI-Dashboard', - cashflow: 'Cashflow-Rechnung', - forecast: 'Prognose', -}; +function _tabLabel(tabId: string, t: (k: string) => string): string { + switch (tabId) { + case 'budget': return t('Budget-Vergleich'); + case 'kpi': return t('KPI-Dashboard'); + case 'cashflow': return t('Cashflow-Rechnung'); + case 'forecast': return t('Prognose'); + default: return tabId; + } +} -const _TAB_DESCRIPTION_KEYS: Record = { - budget: 'Soll/Ist-Vergleich der Buchhaltung mit Budget-Excel', - kpi: 'Kennzahlen berechnen und visualisieren', - cashflow: 'Cashflow berechnen und analysieren', - forecast: 'Trend-Analyse und Prognose der nächsten Monate', -}; +function _tabDescription(tabId: string, t: (k: string) => string): string { + switch (tabId) { + case 'budget': return t('Soll/Ist-Vergleich der Buchhaltung mit Budget-Excel'); + case 'kpi': return t('Kennzahlen berechnen und visualisieren'); + case 'cashflow': return t('Cashflow berechnen und analysieren'); + case 'forecast': return t('Trend-Analyse und Prognose der nächsten Monate'); + default: return ''; + } +} // --------------------------------------------------------------------------- // Types @@ -240,7 +246,7 @@ export const TrusteeAnalyseView: React.FC = () => { }} > {tab.icon} - {t(_TAB_LABEL_KEYS[tab.id] || tab.id)} + {_tabLabel(tab.id, t)} ))}
@@ -248,7 +254,7 @@ export const TrusteeAnalyseView: React.FC = () => { {/* Tab content */}

- {_TAB_DESCRIPTION_KEYS[activeTab] ? t(_TAB_DESCRIPTION_KEYS[activeTab]) : ''} + {_tabDescription(activeTab, t)}

{workflowsLoading ? ( diff --git a/src/pages/views/workspace/ToolActivityLog.tsx b/src/pages/views/workspace/ToolActivityLog.tsx index 6e405ca..1758c87 100644 --- a/src/pages/views/workspace/ToolActivityLog.tsx +++ b/src/pages/views/workspace/ToolActivityLog.tsx @@ -7,7 +7,7 @@ * - Full details shown on error for debugging */ -import React, { useState, useCallback } from 'react'; +import React, { useState} from 'react'; import type { ToolActivity } from './useWorkspace'; import { useLanguage } from '../../../providers/language/LanguageContext'; @@ -124,7 +124,7 @@ export const ToolActivityLog: React.FC = ({ activities }) const { t } = useLanguage(); const [expandedId, setExpandedId] = useState(null); - const translate = useCallback((key, params) => t(key, params), [t]); + const translate: TranslateFn = t; if (!activities.length) { return ( diff --git a/src/pages/views/workspace/WorkspaceRagInsightsPage.tsx b/src/pages/views/workspace/WorkspaceRagInsightsPage.tsx index a411fee..0079c41 100644 --- a/src/pages/views/workspace/WorkspaceRagInsightsPage.tsx +++ b/src/pages/views/workspace/WorkspaceRagInsightsPage.tsx @@ -25,16 +25,19 @@ import { formatBinaryDataSizeBytes } from '../../../utils/formatDataSize'; import { useLanguage } from '../../../providers/language/LanguageContext'; -const MIME_LABELS: Record = { - pdf: 'PDF', - office_doc: 'Office (Text)', - office_sheet: 'Office (Tabellen)', - office_slides: 'Office (Folien)', - text: 'Text', - image: 'Bild', - html: 'HTML', - other: 'Sonstige', -}; +function _mimeLabel(key: string, t: (k: string) => string): string { + switch (key) { + case 'pdf': return t('PDF'); + case 'office_doc': return t('Office (Text)'); + case 'office_sheet': return t('Office (Tabellen)'); + case 'office_slides': return t('Office (Folien)'); + case 'text': return t('Text'); + case 'image': return t('Bild'); + case 'html': return t('HTML'); + case 'other': return t('Sonstige'); + default: return key; + } +} const CHART_COLORS = ['#1976d2', '#00897b', '#6a1b9a', '#e65100', '#5d4037', '#455a64', '#c62828']; @@ -118,7 +121,7 @@ export const WorkspaceRagInsightsPage: React.FC = () => { const kpis = stats?.kpis; const timeline = stats?.timelineIndexedDocuments ?? []; const mimeRows = Object.entries(stats?.documentsByMimeCategory ?? {}).map(([key, value]) => ({ - name: t(MIME_LABELS[key] ?? key), + name: _mimeLabel(key, t), value, })); const statusRows = Object.entries(stats?.indexedDocumentsByStatus ?? {}).map(([name, value]) => ({ diff --git a/src/providers/language/LanguageContext.tsx b/src/providers/language/LanguageContext.tsx index 8521b6d..9a51550 100644 --- a/src/providers/language/LanguageContext.tsx +++ b/src/providers/language/LanguageContext.tsx @@ -10,7 +10,7 @@ type TranslateParams = Record void; - t: (key: string, paramsOrFallback?: TranslateParams | string) => string; + t: (key: string, params?: TranslateParams) => string; isLoading: boolean; reloadLanguage: () => Promise; availableLanguages: I18nCodeInfo[]; @@ -123,18 +123,8 @@ export const LanguageProvider: React.FC = ({ children }) return out; }; - const t = (key: string, paramsOrFallback?: TranslateParams | string): string => { - let params: TranslateParams | undefined; - if (typeof paramsOrFallback === 'string') { - params = undefined; - } else { - params = paramsOrFallback; - } - - const resolved = - translations[key] ?? - (typeof paramsOrFallback === 'string' ? paramsOrFallback : undefined) ?? - `[${key}]`; + const t = (key: string, params?: TranslateParams): string => { + const resolved = translations[key] ?? `[${key}]`; return _applyParams(resolved, params); };