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,9 +21,10 @@ 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 <div
className={cn( className={cn(
'h-3 w-3 rounded-full transition-all duration-300', 'h-3 w-3 rounded-full transition-all duration-300',
@@ -38,11 +39,12 @@ const StatusIndicator = () => {
{health ? t('graphPanel.statusIndicator.connected') : t('graphPanel.statusIndicator.disconnected')} {health ? t('graphPanel.statusIndicator.connected') : t('graphPanel.statusIndicator.disconnected')}
</span> </span>
</div> </div>
</PopoverTrigger>
<PopoverContent className="w-auto" side="top" align="end"> <StatusDialog
<StatusCard status={status} /> open={dialogOpen}
</PopoverContent> onOpenChange={setDialogOpen}
</Popover> 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": "设置",