diff --git a/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx b/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx index bb3d9e71..4ac23386 100644 --- a/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx +++ b/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx @@ -6,16 +6,23 @@ import { CircleCheck, CircleX, Loader2, - ChevronDown, + Info, Container, Clock, + Cpu, + HardDrive, + Network, + Image, + FolderOpen, } from 'lucide-react'; import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; +import { Button } from '@/components/ui/button'; import { - Popover, - PopoverContent, - PopoverTrigger, -} from '@/components/ui/popover'; + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; import { ApiRespPluginSystemStatus, ApiRespBoxStatus, @@ -46,6 +53,7 @@ export default function SystemStatusCard({ const [boxStatus, setBoxStatus] = useState(null); const [boxSessions, setBoxSessions] = useState([]); const [loading, setLoading] = useState(true); + const [dialogOpen, setDialogOpen] = useState(false); const fetchStatus = useCallback(async () => { try { @@ -74,6 +82,12 @@ export default function SystemStatusCard({ : null; const boxOk = boxStatus ? boxStatus.available : null; + const handleOpenDialog = (e: React.MouseEvent) => { + e.stopPropagation(); + fetchStatus(); + setDialogOpen(true); + }; + if (loading) { return ( @@ -92,164 +106,232 @@ export default function SystemStatusCard({ } return ( - { - if (open) fetchStatus(); - }} - > - - - - - {t('monitoring.systemStatus')} - - - - -
- - - {t('monitoring.pluginRuntime')} -
-
- - - {t('monitoring.boxRuntime')} -
-
-
-
- -
- {/* Plugin Runtime */} -
-
- - - {t('monitoring.pluginRuntime')} - -
-
-
- {pluginOk ? ( - - ) : ( - + <> + + + + {t('monitoring.systemStatus')} + + + + +
+ + + {t('monitoring.pluginRuntime')} +
+
+ + + {t('monitoring.boxRuntime')} +
+
+
+ + + + + {t('monitoring.systemStatus')} + + +
+ {/* Plugin Runtime */} +
+
+ + + {t('monitoring.pluginRuntime')} + +
+
+
+ {pluginOk ? ( + + ) : ( + + )} + + {pluginOk + ? t('monitoring.connected') + : pluginStatus && !pluginStatus.is_enable + ? t('monitoring.disabled') + : t('monitoring.disconnected')} + +
+ {pluginStatus && !pluginStatus.is_enable && ( +

+ {t('monitoring.pluginDisabled')} +

)} - - {pluginOk - ? t('monitoring.connected') - : pluginStatus && !pluginStatus.is_enable - ? t('monitoring.disabled') + {pluginStatus && + !pluginOk && + pluginStatus.is_enable && + pluginStatus.plugin_connector_error && + pluginStatus.plugin_connector_error !== 'ok' && ( +

+ {pluginStatus.plugin_connector_error} +

+ )} +
+
+ +
+ + {/* Box Runtime */} +
+
+ + + {t('monitoring.boxRuntime')} + +
+
+
+ {boxOk ? ( + + ) : ( + + )} + + {boxOk + ? t('monitoring.connected') : t('monitoring.disconnected')} - -
- {pluginStatus && !pluginStatus.is_enable && ( -

- {t('monitoring.pluginDisabled')} -

- )} - {pluginStatus && - !pluginOk && - pluginStatus.is_enable && - pluginStatus.plugin_connector_error && - pluginStatus.plugin_connector_error !== 'ok' && ( -

- {pluginStatus.plugin_connector_error} + +

+ {boxStatus && !boxOk && boxStatus.connector_error && ( +

+ {boxStatus.connector_error}

)} -
-
- -
- - {/* Box Runtime */} -
-
- - - {t('monitoring.boxRuntime')} - -
-
-
- {boxOk ? ( - - ) : ( - + {boxStatus && ( +
+ {boxStatus.backend && ( +

+ {t('monitoring.boxBackend')}:{' '} + + {boxStatus.backend.name} + +

+ )} +

+ {t('monitoring.boxProfile')}:{' '} + + {boxStatus.profile} + +

+ {boxOk && boxStatus.active_sessions !== undefined && ( +

+ {t('monitoring.boxSandboxes')}:{' '} + + {boxStatus.active_sessions} + +

+ )} +
+ )} + + {/* Active Sandboxes */} + {boxSessions.length > 0 && ( +
+ {boxSessions.map((session) => ( +
+
+ + + {session.session_id} + +
+
+
+ + + {session.image} + +
+
+ + + {session.backend_name} + +
+
+ + + {session.cpus} CPU / {session.memory_mb} MB + +
+
+ + + {session.network} + +
+ {session.host_path && ( +
+ + + {session.mount_path}{' '} + + ({session.host_path_mode}) + + +
+ )} +
+ + + {t('monitoring.boxSessionCreated')}:{' '} + + {new Date(session.created_at).toLocaleString()} + + +
+
+ + + {t('monitoring.boxSessionLastUsed')}:{' '} + + {new Date( + session.last_used_at, + ).toLocaleString()} + + +
+
+
+ ))} +
)} - - {boxOk - ? t('monitoring.connected') - : t('monitoring.disconnected')} -
- {boxStatus && !boxOk && boxStatus.connector_error && ( -

- {boxStatus.connector_error} -

- )} - {boxStatus && ( -
- {boxStatus.backend && ( -

- {t('monitoring.boxBackend')}:{' '} - - {boxStatus.backend.name} - -

- )} -

- {t('monitoring.boxProfile')}:{' '} - - {boxStatus.profile} - -

- {boxOk && boxStatus.active_sessions !== undefined && ( -

- {t('monitoring.boxSandboxes')}:{' '} - - {boxStatus.active_sessions} - -

- )} -
- )} - {boxSessions.length > 0 && ( -
- {boxSessions.map((session) => ( -
-
- - - {session.session_id} - -
-
- - {session.image.split(':').pop() || session.image} - - - {session.cpus} CPU / {session.memory_mb}MB - -
-
- - - {new Date(session.last_used_at).toLocaleString()} - -
-
- ))} -
- )}
-
- - + +
+ ); } diff --git a/web/src/i18n/locales/en-US.ts b/web/src/i18n/locales/en-US.ts index 9d121677..8be10369 100644 --- a/web/src/i18n/locales/en-US.ts +++ b/web/src/i18n/locales/en-US.ts @@ -1264,6 +1264,8 @@ const enUS = { boxBackend: 'Backend', boxProfile: 'Profile', boxSandboxes: 'Sandboxes', + boxSessionCreated: 'Created', + boxSessionLastUsed: 'Last used', }, limitation: { maxBotsReached: diff --git a/web/src/i18n/locales/es-ES.ts b/web/src/i18n/locales/es-ES.ts index d209feed..2bece5f4 100644 --- a/web/src/i18n/locales/es-ES.ts +++ b/web/src/i18n/locales/es-ES.ts @@ -1290,6 +1290,8 @@ const esES = { boxBackend: 'Backend', boxProfile: 'Perfil', boxSandboxes: 'Sandboxes', + boxSessionCreated: 'Creado', + boxSessionLastUsed: 'Último uso', }, limitation: { maxBotsReached: diff --git a/web/src/i18n/locales/ja-JP.ts b/web/src/i18n/locales/ja-JP.ts index 9f2b8ee0..27d5b116 100644 --- a/web/src/i18n/locales/ja-JP.ts +++ b/web/src/i18n/locales/ja-JP.ts @@ -1262,6 +1262,8 @@ const jaJP = { boxBackend: 'バックエンド', boxProfile: 'プロファイル', boxSandboxes: 'サンドボックス', + boxSessionCreated: '作成日時', + boxSessionLastUsed: '最終使用', }, limitation: { maxBotsReached: diff --git a/web/src/i18n/locales/ru-RU.ts b/web/src/i18n/locales/ru-RU.ts index 9f18961c..71db55f4 100644 --- a/web/src/i18n/locales/ru-RU.ts +++ b/web/src/i18n/locales/ru-RU.ts @@ -1264,6 +1264,8 @@ const ruRU = { boxBackend: 'Бэкенд', boxProfile: 'Профиль', boxSandboxes: 'Песочницы', + boxSessionCreated: 'Создано', + boxSessionLastUsed: 'Последнее использование', }, limitation: { maxBotsReached: diff --git a/web/src/i18n/locales/th-TH.ts b/web/src/i18n/locales/th-TH.ts index 715413c0..ec99f517 100644 --- a/web/src/i18n/locales/th-TH.ts +++ b/web/src/i18n/locales/th-TH.ts @@ -1237,6 +1237,8 @@ const thTH = { boxBackend: 'แบ็กเอนด์', boxProfile: 'โปรไฟล์', boxSandboxes: 'แซนด์บ็อกซ์', + boxSessionCreated: 'สร้างเมื่อ', + boxSessionLastUsed: 'ใช้ล่าสุด', }, limitation: { maxBotsReached: diff --git a/web/src/i18n/locales/vi-VN.ts b/web/src/i18n/locales/vi-VN.ts index c2cfb7a4..94cdde2c 100644 --- a/web/src/i18n/locales/vi-VN.ts +++ b/web/src/i18n/locales/vi-VN.ts @@ -1258,6 +1258,8 @@ const viVN = { boxBackend: 'Backend', boxProfile: 'Hồ sơ', boxSandboxes: 'Sandbox', + boxSessionCreated: 'Đã tạo', + boxSessionLastUsed: 'Lần cuối sử dụng', }, limitation: { maxBotsReached: diff --git a/web/src/i18n/locales/zh-Hans.ts b/web/src/i18n/locales/zh-Hans.ts index b0770131..f2a99b88 100644 --- a/web/src/i18n/locales/zh-Hans.ts +++ b/web/src/i18n/locales/zh-Hans.ts @@ -1210,6 +1210,8 @@ const zhHans = { boxBackend: '后端', boxProfile: '配置', boxSandboxes: '沙箱数', + boxSessionCreated: '创建时间', + boxSessionLastUsed: '最后使用', }, limitation: { maxBotsReached: diff --git a/web/src/i18n/locales/zh-Hant.ts b/web/src/i18n/locales/zh-Hant.ts index f945db5b..f45e5f2f 100644 --- a/web/src/i18n/locales/zh-Hant.ts +++ b/web/src/i18n/locales/zh-Hant.ts @@ -1203,6 +1203,8 @@ const zhHant = { boxBackend: '後端', boxProfile: '設定檔', boxSandboxes: '沙箱數', + boxSessionCreated: '建立時間', + boxSessionLastUsed: '最後使用', }, limitation: { maxBotsReached: