diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 8be58d4..98f6d77 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -84,9 +84,9 @@ export function Sidebar({ user, collapsed, onToggle }: t.SidebarProps) { >
- LibreChat + {localize('com_a11y_logo_alt')} - Admin Panel + {localize('com_auth_title')}
diff --git a/src/components/configuration/ConfigRow.tsx b/src/components/configuration/ConfigRow.tsx index 21b76af..c3a0b16 100644 --- a/src/components/configuration/ConfigRow.tsx +++ b/src/components/configuration/ConfigRow.tsx @@ -53,7 +53,9 @@ export function ConfigRow({ ) : null; const pendingResetHint = isPendingReset ? ( - Pending reset + + {localize('com_config_pending_reset')} + ) : null; const configuredDot = diff --git a/src/components/configuration/ImportYamlDialog.tsx b/src/components/configuration/ImportYamlDialog.tsx index 4f67130..0cdd5ae 100644 --- a/src/components/configuration/ImportYamlDialog.tsx +++ b/src/components/configuration/ImportYamlDialog.tsx @@ -410,7 +410,9 @@ export function ImportYamlDialog({ ))} {validationErrors.length > 10 && (
  • - ...and {validationErrors.length - 10} more + {localize('com_config_validation_more', { + count: String(validationErrors.length - 10), + })}
  • )} diff --git a/src/components/configuration/ScopeSelector.tsx b/src/components/configuration/ScopeSelector.tsx index 89eeb7e..b1bb4ba 100644 --- a/src/components/configuration/ScopeSelector.tsx +++ b/src/components/configuration/ScopeSelector.tsx @@ -123,10 +123,10 @@ export function ScopeSelector({ resetState(); } catch (err) { setCreating(false); - onError?.(err instanceof Error ? err.message : 'Failed to create scope'); + onError?.(err instanceof Error ? err.message : localize('com_scope_create_error')); } }, - [creating, queryClient, resetState, onError], + [creating, queryClient, resetState, onError, localize], ); const handleCreateForGroup = useCallback( @@ -146,10 +146,10 @@ export function ScopeSelector({ resetState(); } catch (err) { setCreating(false); - onError?.(err instanceof Error ? err.message : 'Failed to create scope'); + onError?.(err instanceof Error ? err.message : localize('com_scope_create_error')); } }, - [creating, queryClient, resetState, onError], + [creating, queryClient, resetState, onError, localize], ); const handleDelete = useCallback(async () => { @@ -174,9 +174,9 @@ export function ScopeSelector({ setDeleting(false); } catch (err) { setDeleting(false); - onError?.(err instanceof Error ? err.message : 'Failed to delete scope'); + onError?.(err instanceof Error ? err.message : localize('com_scope_delete_error')); } - }, [deleteTarget, deleting, queryClient, currentSelection, onSelect, onError]); + }, [deleteTarget, deleting, queryClient, currentSelection, onSelect, onError, localize]); const roleScopes = useMemo( () => scopes.filter((s) => s.principalType === PrincipalType.ROLE), diff --git a/src/components/configuration/fields/ArrayObjectField.tsx b/src/components/configuration/fields/ArrayObjectField.tsx index 1bc6007..ea8a0e9 100644 --- a/src/components/configuration/fields/ArrayObjectField.tsx +++ b/src/components/configuration/fields/ArrayObjectField.tsx @@ -4,14 +4,14 @@ import { ObjectEntryCard } from './ObjectEntryCard'; import { AddItemButton } from '@/components/shared'; import { useLocalize } from '@/hooks'; -function getEntryLabel(item: t.ConfigValue, index: number): string { +function getEntryLabel(item: t.ConfigValue): string | null { if (item && typeof item === 'object' && !Array.isArray(item)) { const obj = item as Record; if (typeof obj.name === 'string' && obj.name) return obj.name; if (typeof obj.label === 'string' && obj.label) return obj.label; if (typeof obj.group === 'string' && obj.group) return obj.group; } - return `Entry ${index + 1}`; + return null; } export function ArrayObjectField({ @@ -107,7 +107,7 @@ export function ArrayObjectField({ handleEntryChange(index, v)} diff --git a/src/components/configuration/fields/KeyValueField.tsx b/src/components/configuration/fields/KeyValueField.tsx index a27ea35..965aaea 100644 --- a/src/components/configuration/fields/KeyValueField.tsx +++ b/src/components/configuration/fields/KeyValueField.tsx @@ -6,11 +6,11 @@ import { AddItemButton, TrashButton } from '@/components/shared'; import { useLocalize } from '@/hooks'; const DEFAULT_TYPES: t.KVValueType[] = ['string', 'number', 'boolean']; -const TYPE_LABELS: Record = { - string: 'abc', - number: '123', - boolean: 'T/F', - json: '{ }', +const TYPE_LABEL_KEYS: Record = { + string: 'com_kv_type_string', + number: 'com_kv_type_number', + boolean: 'com_kv_type_boolean', + json: 'com_kv_type_json', }; function LocalInput({ @@ -171,8 +171,8 @@ export function KeyValueField({ disabled={disabled} aria-label={valueLabel} > - true - false + {localize('com_ui_true')} + {localize('com_ui_false')} ) : ( @@ -195,7 +195,7 @@ export function KeyValueField({ > {availableTypes.map((vt) => ( - {TYPE_LABELS[vt]} + {localize(TYPE_LABEL_KEYS[vt])} ))} @@ -231,7 +231,7 @@ export function KeyValueField({ > {availableTypes.map((vt) => ( - {TYPE_LABELS[vt]} + {localize(TYPE_LABEL_KEYS[vt])} ))} diff --git a/src/components/shared/PermissionsUnavailable.tsx b/src/components/shared/PermissionsUnavailable.tsx index 46df0ff..ee92351 100644 --- a/src/components/shared/PermissionsUnavailable.tsx +++ b/src/components/shared/PermissionsUnavailable.tsx @@ -1,18 +1,21 @@ +import { useLocalize } from '@/hooks'; + export function PermissionsUnavailable() { + const localize = useLocalize(); return (

    - Could not verify permissions + {localize('com_perm_unavailable_title')}

    - The permissions service is temporarily unavailable. Please reload the page to try again. + {localize('com_perm_unavailable_desc')}

    ); diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index c58fe46..9719e25 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -1016,5 +1016,16 @@ "com_grants_assign_hint": "Roles and groups can be edited directly from the table above.", "com_grants_assign_no_users": "No eligible users found", "com_error_load_groups": "Failed to load groups. Please try again.", - "com_error_load_members": "Failed to load members. Please try again." + "com_error_load_members": "Failed to load members. Please try again.", + "com_perm_unavailable_title": "Could not verify permissions", + "com_perm_unavailable_desc": "The permissions service is temporarily unavailable. Please reload the page to try again.", + "com_ui_reload": "Reload", + "com_config_pending_reset": "Pending reset", + "com_config_validation_more": "...and {{count}} more", + "com_scope_delete_error": "Failed to delete configuration", + "com_kv_type_string": "abc", + "com_kv_type_number": "123", + "com_kv_type_boolean": "T/F", + "com_kv_type_json": "{ }", + "com_a11y_logo_alt": "LibreChat logo" }