Add easy & DBA mode

This commit is contained in:
2026-02-12 11:37:25 +01:00
parent d1af2bf4c6
commit 64b4c3dfa4
4 changed files with 238 additions and 4 deletions

View File

@@ -66,7 +66,7 @@ async function loadMetric(targetId, metric, range, tokens, refresh) {
export function TargetDetailPage() {
const { id } = useParams();
const { tokens, refresh } = useAuth();
const { tokens, refresh, uiMode } = useAuth();
const [range, setRange] = useState("1h");
const [series, setSeries] = useState({});
const [locks, setLocks] = useState([]);
@@ -135,6 +135,38 @@ export function TargetDetailPage() {
[series]
);
const easySummary = useMemo(() => {
if (!overview) return null;
const latest = chartData[chartData.length - 1];
const issues = [];
const warnings = [];
if (overview.partial_failures?.length > 0) warnings.push("Some advanced metrics are currently unavailable.");
if ((overview.performance?.deadlocks || 0) > 0) issues.push("Deadlocks were detected.");
if ((overview.replication?.mode === "standby") && (overview.replication?.replay_lag_seconds || 0) > 5) {
issues.push("Replication lag is above 5 seconds.");
}
if ((latest?.cache || 0) > 0 && latest.cache < 90) warnings.push("Cache hit ratio is below 90%.");
if ((latest?.connections || 0) > 120) warnings.push("Connection count is relatively high.");
if ((locks?.length || 0) > 150) warnings.push("High number of active locks.");
const health = issues.length > 0 ? "problem" : warnings.length > 0 ? "warning" : "ok";
const message =
health === "ok"
? "Everything looks healthy. No major risks detected right now."
: health === "warning"
? "System is operational, but there are signals you should watch."
: "Attention required. Critical signals need investigation.";
return {
health,
message,
issues,
warnings,
latest,
};
}, [overview, chartData, locks]);
if (loading) return <div className="card">Loading target detail...</div>;
if (error) return <div className="card error">{error}</div>;
@@ -148,7 +180,82 @@ export function TargetDetailPage() {
Target Detail {targetMeta?.name || `#${id}`}
{targetMeta?.dbname ? ` (${targetMeta.dbname})` : ""}
</h2>
{overview && (
{uiMode === "easy" && overview && easySummary && (
<>
<div className={`card easy-status ${easySummary.health}`}>
<h3>System Health</h3>
<p>{easySummary.message}</p>
<div className="easy-badge-row">
<span className={`easy-badge ${easySummary.health}`}>
{easySummary.health === "ok" ? "OK" : easySummary.health === "warning" ? "Warning" : "Problem"}
</span>
</div>
</div>
<div className="grid three">
<div className="card stat">
<strong>{formatNumber(easySummary.latest?.connections, 0)}</strong>
<span>Current Connections</span>
</div>
<div className="card stat">
<strong>{formatNumber(easySummary.latest?.tps, 2)}</strong>
<span>Transactions/sec (approx)</span>
</div>
<div className="card stat">
<strong>{formatNumber(easySummary.latest?.cache, 2)}%</strong>
<span>Cache Hit Ratio</span>
</div>
</div>
<div className="card">
<h3>Quick Explanation</h3>
{easySummary.issues.length === 0 && easySummary.warnings.length === 0 && (
<p>No immediate problems were detected. Keep monitoring over time.</p>
)}
{easySummary.issues.length > 0 && (
<>
<strong>Problems</strong>
<ul className="easy-list">
{easySummary.issues.map((item, idx) => <li key={`i-${idx}`}>{item}</li>)}
</ul>
</>
)}
{easySummary.warnings.length > 0 && (
<>
<strong>Things to watch</strong>
<ul className="easy-list">
{easySummary.warnings.map((item, idx) => <li key={`w-${idx}`}>{item}</li>)}
</ul>
</>
)}
</div>
<div className="grid two">
<div className="card">
<h3>Instance Summary</h3>
<div className="overview-metrics">
<div><span>Role</span><strong>{overview.instance.role}</strong></div>
<div><span>Uptime</span><strong>{formatSeconds(overview.instance.uptime_seconds)}</strong></div>
<div><span>Target Port</span><strong>{targetMeta?.port ?? "-"}</strong></div>
<div><span>Current DB Size</span><strong>{formatBytes(overview.storage.current_database_size_bytes)}</strong></div>
<div><span>Replication Clients</span><strong>{overview.replication.active_replication_clients ?? "-"}</strong></div>
<div><span>Autovacuum Workers</span><strong>{overview.performance.autovacuum_workers ?? "-"}</strong></div>
</div>
</div>
<div className="card">
<h3>Activity Snapshot</h3>
<div className="overview-metrics">
<div><span>Running Sessions</span><strong>{activity.filter((a) => a.state === "active").length}</strong></div>
<div><span>Total Sessions</span><strong>{activity.length}</strong></div>
<div><span>Current Locks</span><strong>{locks.length}</strong></div>
<div><span>Deadlocks</span><strong>{overview.performance.deadlocks ?? 0}</strong></div>
</div>
</div>
</div>
</>
)}
{uiMode === "dba" && overview && (
<div className="card">
<h3>Database Overview</h3>
<div className="grid three overview-kv">