import React, { useEffect, useState } from "react";
|
import { useTranslate } from "react-admin";
|
import { Alert, Box, Card, CardContent, Chip, CircularProgress, Grid, Stack, Typography } from "@mui/material";
|
import { getAiConfigSummary } from "@/api/ai/configCenter";
|
|
const AiRuntimeSummary = ({ promptCode = "home.default" }) => {
|
const translate = useTranslate();
|
const [summary, setSummary] = useState(null);
|
const [loading, setLoading] = useState(true);
|
const [error, setError] = useState("");
|
|
useEffect(() => {
|
let active = true;
|
setLoading(true);
|
setError("");
|
getAiConfigSummary(promptCode)
|
.then((data) => {
|
if (!active) {
|
return;
|
}
|
setSummary(data);
|
})
|
.catch((err) => {
|
if (!active) {
|
return;
|
}
|
setError(err?.message || translate("ai.runtimeSummary.fetchFailed"));
|
})
|
.finally(() => {
|
if (active) {
|
setLoading(false);
|
}
|
});
|
return () => {
|
active = false;
|
};
|
}, [promptCode]);
|
|
return (
|
<Box px={2} pt={2}>
|
<Card
|
variant="outlined"
|
sx={{
|
borderRadius: 3,
|
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.06)",
|
}}
|
>
|
<CardContent>
|
<Stack direction="row" justifyContent="space-between" alignItems="center" mb={2}>
|
<Box>
|
<Typography variant="h6">{translate("ai.runtimeSummary.title")}</Typography>
|
<Typography variant="body2" color="text.secondary">
|
{translate("ai.runtimeSummary.description")}
|
</Typography>
|
</Box>
|
{loading && <CircularProgress size={24} />}
|
</Stack>
|
{error && <Alert severity="error">{error}</Alert>}
|
{!loading && !error && summary && (
|
<Grid container spacing={2}>
|
<Grid item xs={12} md={4}>
|
<Typography variant="caption" color="text.secondary">{translate("ai.runtimeSummary.currentModel")}</Typography>
|
<Typography variant="body1">{summary.activeModel || "--"}</Typography>
|
<Typography variant="body2" color="text.secondary">
|
{summary.activeParamName || "--"}
|
</Typography>
|
<Stack direction="row" spacing={1} mt={1} flexWrap="wrap" useFlexGap>
|
<Chip size="small" label={translate("ai.runtimeSummary.validateStatus", { status: summary.activeParamValidateStatus || "--" })} />
|
<Chip size="small" variant="outlined" label={summary.activeParamValidatedAt || translate("ai.common.notValidated")} />
|
</Stack>
|
</Grid>
|
<Grid item xs={12} md={4}>
|
<Typography variant="caption" color="text.secondary">{translate("ai.runtimeSummary.currentPrompt")}</Typography>
|
<Typography variant="body1">{summary.promptName || "--"}</Typography>
|
<Typography variant="body2" color="text.secondary">
|
{summary.promptCode || "--"} / {summary.promptScene || "--"}
|
</Typography>
|
<Typography variant="body2" color="text.secondary" mt={1}>
|
{translate("ai.runtimeSummary.lastUpdated", {
|
time: summary.activePromptUpdatedAt || "--",
|
user: summary.activePromptUpdatedBy || "--",
|
})}
|
</Typography>
|
</Grid>
|
<Grid item xs={12} md={4}>
|
<Typography variant="caption" color="text.secondary">{translate("ai.runtimeSummary.enabledMcp")}</Typography>
|
<Typography variant="body1">{translate("ai.runtimeSummary.enabledMcpCount", { count: summary.enabledMcpCount ?? 0 })}</Typography>
|
<Stack direction="row" spacing={1} mt={1} flexWrap="wrap" useFlexGap>
|
{(summary.enabledMcpNames || []).map((name) => (
|
<Chip key={name} size="small" variant="outlined" label={name} />
|
))}
|
</Stack>
|
</Grid>
|
{summary.activeParamValidateMessage && (
|
<Grid item xs={12}>
|
<Alert severity={summary.activeParamValidateStatus === "VALID" ? "success" : "warning"}>
|
{summary.activeParamValidateMessage}
|
</Alert>
|
</Grid>
|
)}
|
</Grid>
|
)}
|
</CardContent>
|
</Card>
|
</Box>
|
);
|
};
|
|
export default AiRuntimeSummary;
|