Optimize server setting dialogue

This commit is contained in:
yangdx
2025-04-04 04:35:57 +08:00
parent 394a6063ba
commit 9c81963908
7 changed files with 76 additions and 30 deletions

View File

@@ -4,14 +4,14 @@ import { useTranslation } from 'react-i18next'
const StatusCard = ({ status }: { status: LightragStatus | null }) => { const StatusCard = ({ status }: { status: LightragStatus | null }) => {
const { t } = useTranslation() const { t } = useTranslation()
if (!status) { if (!status) {
return <div className="text-muted-foreground text-sm">{t('graphPanel.statusCard.unavailable')}</div> return <div className="text-foreground text-xs">{t('graphPanel.statusCard.unavailable')}</div>
} }
return ( return (
<div className="min-w-[300px] space-y-3 text-sm"> <div className="min-w-[300px] space-y-2 text-xs">
<div className="space-y-1"> <div className="space-y-1">
<h4 className="font-medium">{t('graphPanel.statusCard.storageInfo')}</h4> <h4 className="font-medium">{t('graphPanel.statusCard.storageInfo')}</h4>
<div className="text-muted-foreground grid grid-cols-2 gap-1"> <div className="text-foreground grid grid-cols-[120px_1fr] gap-1">
<span>{t('graphPanel.statusCard.workingDirectory')}:</span> <span>{t('graphPanel.statusCard.workingDirectory')}:</span>
<span className="truncate">{status.working_directory}</span> <span className="truncate">{status.working_directory}</span>
<span>{t('graphPanel.statusCard.inputDirectory')}:</span> <span>{t('graphPanel.statusCard.inputDirectory')}:</span>
@@ -21,7 +21,7 @@ const StatusCard = ({ status }: { status: LightragStatus | null }) => {
<div className="space-y-1"> <div className="space-y-1">
<h4 className="font-medium">{t('graphPanel.statusCard.llmConfig')}</h4> <h4 className="font-medium">{t('graphPanel.statusCard.llmConfig')}</h4>
<div className="text-muted-foreground grid grid-cols-2 gap-1"> <div className="text-foreground grid grid-cols-[120px_1fr] gap-1">
<span>{t('graphPanel.statusCard.llmBinding')}:</span> <span>{t('graphPanel.statusCard.llmBinding')}:</span>
<span>{status.configuration.llm_binding}</span> <span>{status.configuration.llm_binding}</span>
<span>{t('graphPanel.statusCard.llmBindingHost')}:</span> <span>{t('graphPanel.statusCard.llmBindingHost')}:</span>
@@ -35,7 +35,7 @@ const StatusCard = ({ status }: { status: LightragStatus | null }) => {
<div className="space-y-1"> <div className="space-y-1">
<h4 className="font-medium">{t('graphPanel.statusCard.embeddingConfig')}</h4> <h4 className="font-medium">{t('graphPanel.statusCard.embeddingConfig')}</h4>
<div className="text-muted-foreground grid grid-cols-2 gap-1"> <div className="text-foreground grid grid-cols-[120px_1fr] gap-1">
<span>{t('graphPanel.statusCard.embeddingBinding')}:</span> <span>{t('graphPanel.statusCard.embeddingBinding')}:</span>
<span>{status.configuration.embedding_binding}</span> <span>{status.configuration.embedding_binding}</span>
<span>{t('graphPanel.statusCard.embeddingBindingHost')}:</span> <span>{t('graphPanel.statusCard.embeddingBindingHost')}:</span>
@@ -47,7 +47,7 @@ const StatusCard = ({ status }: { status: LightragStatus | null }) => {
<div className="space-y-1"> <div className="space-y-1">
<h4 className="font-medium">{t('graphPanel.statusCard.storageConfig')}</h4> <h4 className="font-medium">{t('graphPanel.statusCard.storageConfig')}</h4>
<div className="text-muted-foreground grid grid-cols-2 gap-1"> <div className="text-foreground grid grid-cols-[120px_1fr] gap-1">
<span>{t('graphPanel.statusCard.kvStorage')}:</span> <span>{t('graphPanel.statusCard.kvStorage')}:</span>
<span>{status.configuration.kv_storage}</span> <span>{status.configuration.kv_storage}</span>
<span>{t('graphPanel.statusCard.docStatusStorage')}:</span> <span>{t('graphPanel.statusCard.docStatusStorage')}:</span>

View File

@@ -0,0 +1,32 @@
import { LightragStatus } from '@/api/lightrag'
import { useTranslation } from 'react-i18next'
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/Dialog'
import StatusCard from './StatusCard'
interface StatusDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
status: LightragStatus | null
}
const StatusDialog = ({ open, onOpenChange, status }: StatusDialogProps) => {
const { t } = useTranslation()
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle>{t('graphPanel.statusDialog.title')}</DialogTitle>
</DialogHeader>
<StatusCard status={status} />
</DialogContent>
</Dialog>
)
}
export default StatusDialog

View File

@@ -1,8 +1,7 @@
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { useBackendState } from '@/stores/state' import { useBackendState } from '@/stores/state'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/Popover' import StatusDialog from './StatusDialog'
import StatusCard from '@/components/status/StatusCard'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
const StatusIndicator = () => { const StatusIndicator = () => {
@@ -11,6 +10,7 @@ const StatusIndicator = () => {
const lastCheckTime = useBackendState.use.lastCheckTime() const lastCheckTime = useBackendState.use.lastCheckTime()
const status = useBackendState.use.status() const status = useBackendState.use.status()
const [animate, setAnimate] = useState(false) const [animate, setAnimate] = useState(false)
const [dialogOpen, setDialogOpen] = useState(false)
// listen to health change // listen to health change
useEffect(() => { useEffect(() => {
@@ -21,28 +21,30 @@ const StatusIndicator = () => {
return ( return (
<div className="fixed right-4 bottom-4 flex items-center gap-2 opacity-80 select-none"> <div className="fixed right-4 bottom-4 flex items-center gap-2 opacity-80 select-none">
<Popover> <div
<PopoverTrigger asChild> className="flex cursor-pointer items-center gap-2"
<div className="flex cursor-help items-center gap-2"> onClick={() => setDialogOpen(true)}
<div >
className={cn( <div
'h-3 w-3 rounded-full transition-all duration-300', className={cn(
'shadow-[0_0_8px_rgba(0,0,0,0.2)]', 'h-3 w-3 rounded-full transition-all duration-300',
health ? 'bg-green-500' : 'bg-red-500', 'shadow-[0_0_8px_rgba(0,0,0,0.2)]',
animate && 'scale-125', health ? 'bg-green-500' : 'bg-red-500',
animate && health && 'shadow-[0_0_12px_rgba(34,197,94,0.4)]', animate && 'scale-125',
animate && !health && 'shadow-[0_0_12px_rgba(239,68,68,0.4)]' animate && health && 'shadow-[0_0_12px_rgba(34,197,94,0.4)]',
)} animate && !health && 'shadow-[0_0_12px_rgba(239,68,68,0.4)]'
/> )}
<span className="text-muted-foreground text-xs"> />
{health ? t('graphPanel.statusIndicator.connected') : t('graphPanel.statusIndicator.disconnected')} <span className="text-muted-foreground text-xs">
</span> {health ? t('graphPanel.statusIndicator.connected') : t('graphPanel.statusIndicator.disconnected')}
</div> </span>
</PopoverTrigger> </div>
<PopoverContent className="w-auto" side="top" align="end">
<StatusCard status={status} /> <StatusDialog
</PopoverContent> open={dialogOpen}
</Popover> onOpenChange={setDialogOpen}
status={status}
/>
</div> </div>
) )
} }

View File

@@ -137,6 +137,9 @@
}, },
"graphPanel": { "graphPanel": {
"dataIsTruncated": "تم اقتصار بيانات الرسم البياني على الحد الأقصى للعقد", "dataIsTruncated": "تم اقتصار بيانات الرسم البياني على الحد الأقصى للعقد",
"statusDialog": {
"title": "إعدادات خادم LightRAG"
},
"sideBar": { "sideBar": {
"settings": { "settings": {
"settings": "الإعدادات", "settings": "الإعدادات",

View File

@@ -137,6 +137,9 @@
}, },
"graphPanel": { "graphPanel": {
"dataIsTruncated": "Graph data is truncated to Max Nodes", "dataIsTruncated": "Graph data is truncated to Max Nodes",
"statusDialog": {
"title": "LightRAG Server Settings"
},
"sideBar": { "sideBar": {
"settings": { "settings": {
"settings": "Settings", "settings": "Settings",

View File

@@ -137,6 +137,9 @@
}, },
"graphPanel": { "graphPanel": {
"dataIsTruncated": "Les données du graphe sont tronquées au nombre maximum de nœuds", "dataIsTruncated": "Les données du graphe sont tronquées au nombre maximum de nœuds",
"statusDialog": {
"title": "Paramètres du Serveur LightRAG"
},
"sideBar": { "sideBar": {
"settings": { "settings": {
"settings": "Paramètres", "settings": "Paramètres",

View File

@@ -137,6 +137,9 @@
}, },
"graphPanel": { "graphPanel": {
"dataIsTruncated": "图数据已截断至最大返回节点数", "dataIsTruncated": "图数据已截断至最大返回节点数",
"statusDialog": {
"title": "LightRAG 服务器设置"
},
"sideBar": { "sideBar": {
"settings": { "settings": {
"settings": "设置", "settings": "设置",