Merge branch 'main' into improve-property-tooltip

This commit is contained in:
yangdx
2025-03-12 13:25:02 +08:00
34 changed files with 1226 additions and 198 deletions

View File

@@ -1,4 +1,5 @@
import { useState, useEffect, useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/components/ui/Button'
import {
Table,
@@ -22,6 +23,7 @@ import { useBackendState } from '@/stores/state'
import { RefreshCwIcon } from 'lucide-react'
export default function DocumentManager() {
const { t } = useTranslation()
const health = useBackendState.use.health()
const [docs, setDocs] = useState<DocsStatusesResponse | null>(null)
@@ -44,7 +46,7 @@ export default function DocumentManager() {
setDocs(null)
}
} catch (err) {
toast.error('Failed to load documents\n' + errorMessage(err))
toast.error(t('documentPanel.documentManager.errors.loadFailed', { error: errorMessage(err) }))
}
}, [setDocs])
@@ -57,7 +59,7 @@ export default function DocumentManager() {
const { status } = await scanNewDocuments()
toast.message(status)
} catch (err) {
toast.error('Failed to load documents\n' + errorMessage(err))
toast.error(t('documentPanel.documentManager.errors.scanFailed', { error: errorMessage(err) }))
}
}, [])
@@ -69,7 +71,7 @@ export default function DocumentManager() {
try {
await fetchDocuments()
} catch (err) {
toast.error('Failed to get scan progress\n' + errorMessage(err))
toast.error(t('documentPanel.documentManager.errors.scanProgressFailed', { error: errorMessage(err) }))
}
}, 5000)
return () => clearInterval(interval)
@@ -78,7 +80,7 @@ export default function DocumentManager() {
return (
<Card className="!size-full !rounded-none !border-none">
<CardHeader>
<CardTitle className="text-lg">Document Management</CardTitle>
<CardTitle className="text-lg">{t('documentPanel.documentManager.title')}</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex gap-2">
@@ -86,10 +88,10 @@ export default function DocumentManager() {
variant="outline"
onClick={scanDocuments}
side="bottom"
tooltip="Scan documents"
tooltip={t('documentPanel.documentManager.scanTooltip')}
size="sm"
>
<RefreshCwIcon /> Scan
<RefreshCwIcon /> {t('documentPanel.documentManager.scanButton')}
</Button>
<div className="flex-1" />
<ClearDocumentsDialog />
@@ -98,29 +100,29 @@ export default function DocumentManager() {
<Card>
<CardHeader>
<CardTitle>Uploaded documents</CardTitle>
<CardDescription>view the uploaded documents here</CardDescription>
<CardTitle>{t('documentPanel.documentManager.uploadedTitle')}</CardTitle>
<CardDescription>{t('documentPanel.documentManager.uploadedDescription')}</CardDescription>
</CardHeader>
<CardContent>
{!docs && (
<EmptyCard
title="No documents uploaded"
description="upload documents to see them here"
title={t('documentPanel.documentManager.emptyTitle')}
description={t('documentPanel.documentManager.emptyDescription')}
/>
)}
{docs && (
<Table>
<TableHeader>
<TableRow>
<TableHead>ID</TableHead>
<TableHead>Summary</TableHead>
<TableHead>Status</TableHead>
<TableHead>Length</TableHead>
<TableHead>Chunks</TableHead>
<TableHead>Created</TableHead>
<TableHead>Updated</TableHead>
<TableHead>Metadata</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.id')}</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.summary')}</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.status')}</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.length')}</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.chunks')}</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.created')}</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.updated')}</TableHead>
<TableHead>{t('documentPanel.documentManager.columns.metadata')}</TableHead>
</TableRow>
</TableHeader>
<TableBody className="text-sm">
@@ -137,13 +139,13 @@ export default function DocumentManager() {
</TableCell>
<TableCell>
{status === 'processed' && (
<span className="text-green-600">Completed</span>
<span className="text-green-600">{t('documentPanel.documentManager.status.completed')}</span>
)}
{status === 'processing' && (
<span className="text-blue-600">Processing</span>
<span className="text-blue-600">{t('documentPanel.documentManager.status.processing')}</span>
)}
{status === 'pending' && <span className="text-yellow-600">Pending</span>}
{status === 'failed' && <span className="text-red-600">Failed</span>}
{status === 'pending' && <span className="text-yellow-600">{t('documentPanel.documentManager.status.pending')}</span>}
{status === 'failed' && <span className="text-red-600">{t('documentPanel.documentManager.status.failed')}</span>}
{doc.error && (
<span className="ml-2 text-red-500" title={doc.error}>

View File

@@ -8,8 +8,10 @@ import { useDebounce } from '@/hooks/useDebounce'
import QuerySettings from '@/components/retrieval/QuerySettings'
import { ChatMessage, MessageWithError } from '@/components/retrieval/ChatMessage'
import { EraserIcon, SendIcon } from 'lucide-react'
import { useTranslation } from 'react-i18next'
export default function RetrievalTesting() {
const { t } = useTranslation()
const [messages, setMessages] = useState<MessageWithError[]>(
() => useSettingsStore.getState().retrievalHistory || []
)
@@ -89,7 +91,7 @@ export default function RetrievalTesting() {
}
} catch (err) {
// Handle error
updateAssistantMessage(`Error: Failed to get response\n${errorMessage(err)}`, true)
updateAssistantMessage(`${t('retrievePanel.retrieval.error')}\n${errorMessage(err)}`, true)
} finally {
// Clear loading and add messages to state
setIsLoading(false)
@@ -98,7 +100,7 @@ export default function RetrievalTesting() {
.setRetrievalHistory([...prevMessages, userMessage, assistantMessage])
}
},
[inputValue, isLoading, messages, setMessages]
[inputValue, isLoading, messages, setMessages, t]
)
const debouncedMessages = useDebounce(messages, 100)
@@ -117,7 +119,7 @@ export default function RetrievalTesting() {
<div className="flex min-h-0 flex-1 flex-col gap-2">
{messages.length === 0 ? (
<div className="text-muted-foreground flex h-full items-center justify-center text-lg">
Start a retrieval by typing your query below
{t('retrievePanel.retrieval.startPrompt')}
</div>
) : (
messages.map((message, idx) => (
@@ -143,18 +145,18 @@ export default function RetrievalTesting() {
size="sm"
>
<EraserIcon />
Clear
{t('retrievePanel.retrieval.clear')}
</Button>
<Input
className="flex-1"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="Type your query..."
placeholder={t('retrievePanel.retrieval.placeholder')}
disabled={isLoading}
/>
<Button type="submit" variant="default" disabled={isLoading} size="sm">
<SendIcon />
Send
{t('retrievePanel.retrieval.send')}
</Button>
</form>
</div>

View File

@@ -4,6 +4,7 @@ import ThemeToggle from '@/components/ThemeToggle'
import { TabsList, TabsTrigger } from '@/components/ui/Tabs'
import { useSettingsStore } from '@/stores/settings'
import { cn } from '@/lib/utils'
import { useTranslation } from 'react-i18next'
import { ZapIcon, GithubIcon } from 'lucide-react'
@@ -29,21 +30,22 @@ function NavigationTab({ value, currentTab, children }: NavigationTabProps) {
function TabsNavigation() {
const currentTab = useSettingsStore.use.currentTab()
const { t } = useTranslation()
return (
<div className="flex h-8 self-center">
<TabsList className="h-full gap-2">
<NavigationTab value="documents" currentTab={currentTab}>
Documents
{t('header.documents')}
</NavigationTab>
<NavigationTab value="knowledge-graph" currentTab={currentTab}>
Knowledge Graph
{t('header.knowledgeGraph')}
</NavigationTab>
<NavigationTab value="retrieval" currentTab={currentTab}>
Retrieval
{t('header.retrieval')}
</NavigationTab>
<NavigationTab value="api" currentTab={currentTab}>
API
{t('header.api')}
</NavigationTab>
</TabsList>
</div>
@@ -51,6 +53,7 @@ function TabsNavigation() {
}
export default function SiteHeader() {
const { t } = useTranslation()
return (
<header className="border-border/40 bg-background/95 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 flex h-10 w-full border-b px-4 backdrop-blur">
<a href="/" className="mr-6 flex items-center gap-2">
@@ -64,7 +67,7 @@ export default function SiteHeader() {
</div>
<nav className="flex items-center">
<Button variant="ghost" size="icon" side="bottom" tooltip="Project Repository">
<Button variant="ghost" size="icon" side="bottom" tooltip={t('header.projectRepository')}>
<a href={SiteInfo.github} target="_blank" rel="noopener noreferrer">
<GithubIcon className="size-4" aria-hidden="true" />
</a>