jan/web-app/src/routes/logs.tsx
Sam Hoang Van c32dd092d0
Enhance i18n and add missing i18n for all component (#5314)
* Refactor translation imports and update text for localization across settings and system monitor routes

- Changed translation import from 'react-i18next' to '@/i18n/react-i18next-compat' in multiple files.
- Updated various text strings to use translation keys for better localization support in:
  - Local API Server settings
  - MCP Servers settings
  - Privacy settings
  - Provider settings
  - Shortcuts settings
  - System Monitor
  - Thread details
- Ensured consistent use of translation keys for all user-facing text.

Update web-app/src/routes/settings/appearance.tsx

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

Update web-app/src/routes/settings/appearance.tsx

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

Update web-app/src/locales/vn/settings.json

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

Update web-app/src/containers/dialogs/DeleteMCPServerConfirm.tsx

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

Update web-app/src/locales/id/common.json

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* Add Chinese (Simplified and Traditional) localization files for various components

- Created `tools.json`, `updater.json`, `assistants.json`, `chat.json`, `common.json`, `hub.json`, `logs.json`, `mcp-servers.json`, `provider.json`, `providers.json`, `settings.json`, `setup.json`, `system-monitor.json`, `tool-approval.json` in both `zh-CN` and `zh-TW` locales.
- Added translations for tool approval, updater notifications, assistant management, chat interface, common UI elements, hub interactions, logging messages, MCP server configurations, provider management, settings options, setup instructions, and system monitoring.

* Refactor localization strings for improved clarity and consistency in English, Indonesian, and Vietnamese settings files

* Fix missing key and reword

* fix pr comment

---------

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2025-06-20 15:33:54 +07:00

103 lines
2.9 KiB
TypeScript

import { createFileRoute } from '@tanstack/react-router'
import { route } from '@/constants/routes'
import { useEffect, useState, useRef } from 'react'
import { readLogs } from '@/services/app'
import { useTranslation } from '@/i18n/react-i18next-compat'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const Route = createFileRoute(route.appLogs as any)({
component: LogsViewer,
})
// Define log entry type
function LogsViewer() {
const { t } = useTranslation()
const [logs, setLogs] = useState<LogEntry[]>([])
const logsContainerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
let lastLogsLength = 0
function updateLogs() {
readLogs().then((logData) => {
let needScroll = false
const filteredLogs = logData.filter(Boolean) as LogEntry[]
if (filteredLogs.length > lastLogsLength) needScroll = true
lastLogsLength = filteredLogs.length
setLogs(filteredLogs)
// Scroll to bottom after initial logs are loaded
if (needScroll) setTimeout(() => scrollToBottom(), 100)
})
}
updateLogs()
// repeat action each 3s
const intervalId = setInterval(() => updateLogs(), 3000)
return () => {
clearInterval(intervalId)
}
}, [])
// Function to scroll to the bottom of the logs container
const scrollToBottom = () => {
if (logsContainerRef.current) {
const { scrollHeight, clientHeight } = logsContainerRef.current
logsContainerRef.current.scrollTop = scrollHeight - clientHeight
}
}
// Function to get appropriate color for log level
const getLogLevelColor = (level: string) => {
switch (level) {
case 'error':
return 'text-red-500'
case 'warn':
return 'text-yellow-500'
case 'info':
return 'text-blue-500'
case 'debug':
return 'text-gray-500'
default:
return 'text-gray-500'
}
}
// Format timestamp to be more readable
const formatTimestamp = (timestamp: string | number) => {
const date = new Date(timestamp)
return date.toLocaleTimeString()
}
return (
<div className="flex flex-col h-full bg-main-view">
<div className="flex-1 overflow-auto" ref={logsContainerRef}>
<div className="font-mono p-2">
{logs.length === 0 ? (
<div className="text-center text-main-view-fg/50 py-8">
{t('logs:noLogs')}
</div>
) : (
logs.map((log, index) => (
<div key={index} className="mb-1 flex">
<span className="text-muted-foreground mr-2">
[{formatTimestamp(log.timestamp)}]
</span>
<span
className={`mr-2 font-semibold ${getLogLevelColor(log.level)}`}
>
{log.level.toUpperCase()}
</span>
<span>{log.message}</span>
</div>
))
)}
</div>
</div>
</div>
)
}