-
Container
-
Image
-
State
-
CPU
-
Memory
-
Ports
-
+ {containers === null && (
+
Loading…
+ )}
+ {containers !== null && containers.length === 0 && (
+
+
🐳
+
No container data available
+
Container metrics endpoint not yet wired
- {CONTAINERS.map(c => (
-
-
-
{c.name}
-
up {c.uptime}
-
-
{c.image}
-
- RUNNING
- {c.healthy && healthy}
-
-
-
-
-
+ )}
+ {containers !== null && containers.length > 0 && (
+
+
+
Container
+
Image
+
State
+
CPU
+
Memory
+
Ports
+
+
+ {containers.map(c => (
+
+
+
{c.name}
+
up {c.uptime}
+
+
{c.image}
+
+ RUNNING
+ {c.healthy && healthy}
+
+
+
+
+
{(c.cpu || 0).toFixed(1)}%
-
{c.cpu.toFixed(1)}%
+
+
{c.mem} MB
+
{c.ports}
+
+
+
-
{c.mem} MB
-
{c.ports}
-
-
-
-
-
- ))}
-
+ ))}
+
+ )}
);
}
function Cluster() {
+ const rawNodes = window.ZAMPP_DATA.NODES;
+ const nodesArr = Array.isArray(rawNodes) ? rawNodes : (rawNodes?.nodes || []);
+
+ const NODES = React.useMemo(() => {
+ if (!nodesArr.length) return [];
+ const primaryRaw = nodesArr.find(n => n.role === 'primary') || nodesArr[0];
+ const others = nodesArr.filter(n => n !== primaryRaw);
+ const primary = _normalizeNode(primaryRaw, 0.5, 0.46);
+ const positioned = others.map((n, i) => {
+ const angle = others.length <= 1
+ ? Math.PI / 2
+ : (i / others.length) * 2 * Math.PI - Math.PI / 2;
+ return _normalizeNode(n, 0.5 + 0.32 * Math.cos(angle), 0.46 + 0.35 * Math.sin(angle));
+ });
+ return [primary, ...positioned];
+ }, []);
+
const [hovered, setHovered] = React.useState(null);
- const [selected, setSelected] = React.useState(NODES[0]);
+ const [selected, setSelected] = React.useState(NODES[0] || null);
const W = 720, H = 460;
- const primary = NODES.find(n => n.role === "primary");
+ if (!NODES.length) {
+ return (
+
+
+
+
No cluster nodes available
+
+
+ );
+ }
+
+ const primary = NODES.find(n => n.role === 'primary') || NODES[0];
const edges = NODES.filter(n => n.id !== primary.id).map(n => ({
from: primary,
to: n,
- alive: n.status === "online",
+ alive: n.status === 'online',
}));
+ const sel = selected || NODES[0];
return (
@@ -378,22 +457,18 @@ function Cluster() {
Nodes
{NODES.length}
-
across 2 regions
-
Total CPU
-
320 cores
-
14% utilized
+
Avg CPU
+
{Math.round(NODES.reduce((a, n) => a + (n.cpu || 0), 0) / NODES.length)} %
GPUs
-
5
-
3 idle · 2 transcoding
+
{NODES.reduce((a, n) => a + n.gpus.length, 0)}
-
Memory
-
243 GB
-
15% utilized
+
Avg Memory
+
{Math.round(NODES.reduce((a, n) => a + (n.mem || 0), 0) / NODES.length)} GB
@@ -403,7 +478,6 @@ function Cluster() {
Topology
-
@@ -440,8 +514,7 @@ function Cluster() {
})}
{NODES.map(n => {
const cx = n.x * W, cy = n.y * H;
- const isHovered = hovered === n.id;
- const isSelected = selected.id === n.id;
+ const isSelected = sel && sel.id === n.id;
const color = n.status === "online" ? "var(--success)" : "var(--text-4)";
return (