Add easy & DBA mode
This commit is contained in:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user