@kwirthmagnify/kwirth-homepage-clusterized 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/front.js +52 -11
  2. package/package.json +1 -1
package/front.js CHANGED
@@ -70,7 +70,33 @@
70
70
  transition: "all 0.3s ease",
71
71
  cursor: "default"
72
72
  } }));
73
+ var MetricBar = ({ label, value, color }) => /* @__PURE__ */ import_react.default.createElement(import_material.Box, { sx: { minWidth: 72 } }, /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center" }, /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "caption", color: "text.secondary", sx: { fontSize: "0.65rem" } }, label), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "caption", fontWeight: "bold", sx: { fontSize: "0.65rem" } }, Math.round(value), "%")), /* @__PURE__ */ import_react.default.createElement(
74
+ import_material.LinearProgress,
75
+ {
76
+ variant: "determinate",
77
+ value: Math.min(Math.max(value, 0), 100),
78
+ sx: { height: 4, borderRadius: 2, bgcolor: "action.hover", "& .MuiLinearProgress-bar": { bgcolor: color, borderRadius: 2 } }
79
+ }
80
+ ));
73
81
  var Clusterized = (props) => {
82
+ const [metrics, setMetrics] = (0, import_react.useState)({});
83
+ const showCpu = props.config?.showCpu ?? true;
84
+ const showMem = props.config?.showMem ?? true;
85
+ const showPods = props.config?.showPods ?? true;
86
+ const needsMetrics = showCpu || showMem || showPods;
87
+ (0, import_react.useEffect)(() => {
88
+ if (!needsMetrics || !props.getClusterMetrics) return;
89
+ const fetchAll = () => {
90
+ props.clusters.forEach((cluster) => {
91
+ props.getClusterMetrics(cluster.name).then((m) => {
92
+ if (m) setMetrics((prev) => ({ ...prev, [cluster.name]: m }));
93
+ });
94
+ });
95
+ };
96
+ fetchAll();
97
+ const timer = setInterval(fetchAll, 3e4);
98
+ return () => clearInterval(timer);
99
+ }, [props.clusters, props.config, needsMetrics]);
74
100
  const launchMagnify = (clusterName) => {
75
101
  props.onHomepageSelectTab({
76
102
  name: clusterName,
@@ -86,22 +112,37 @@
86
112
  }
87
113
  });
88
114
  };
89
- return /* @__PURE__ */ import_react.default.createElement(import_material.Box, { sx: { p: 2, display: "flex", flexDirection: "column", gap: 2, overflowY: "auto", height: "100%" } }, props.clusters.map((cluster) => /* @__PURE__ */ import_react.default.createElement(import_material.Card, { key: cluster.name, variant: "outlined" }, /* @__PURE__ */ import_react.default.createElement(import_material.CardContent, { sx: { py: 1.5, "&:last-child": { pb: 1.5 } } }, /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", alignItems: "center", spacing: 2 }, /* @__PURE__ */ import_react.default.createElement(import_material.Box, { sx: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "h6", sx: { lineHeight: 1.3 } }, cluster.name), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "caption", color: "text.secondary", sx: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", display: "block" } }, cluster.url)), /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", spacing: 0.75, alignItems: "center" }, /* @__PURE__ */ import_react.default.createElement(StatusLight, { color: "#4caf50", label: "Healthy" }), /* @__PURE__ */ import_react.default.createElement(StatusLight, { color: "#ff9800", label: "Warning" }), /* @__PURE__ */ import_react.default.createElement(StatusLight, { color: "#f44336", label: "Critical" })), /* @__PURE__ */ import_react.default.createElement(
90
- import_material.Button,
91
- {
92
- variant: "outlined",
93
- size: "small",
94
- startIcon: /* @__PURE__ */ import_react.default.createElement(import_icons_material.OpenInBrowser, null),
95
- onClick: () => launchMagnify(cluster.name)
96
- },
97
- "Magnify"
98
- ))))), props.clusters.length === 0 && /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "body2", color: "text.secondary", sx: { p: 2 } }, "No clusters defined. Add a cluster to get started."));
115
+ return /* @__PURE__ */ import_react.default.createElement(import_material.Box, { sx: { p: 2, display: "flex", flexDirection: "column", gap: 2, overflowY: "auto", height: "100%" } }, props.clusters.map((cluster) => {
116
+ const m = metrics[cluster.name];
117
+ return /* @__PURE__ */ import_react.default.createElement(import_material.Card, { key: cluster.name, variant: "outlined" }, /* @__PURE__ */ import_react.default.createElement(import_material.CardContent, { sx: { py: 1.5, "&:last-child": { pb: 1.5 } } }, /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", alignItems: "center", spacing: 2 }, /* @__PURE__ */ import_react.default.createElement(import_material.Box, { sx: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "h6", sx: { lineHeight: 1.3 } }, cluster.name), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "caption", color: "text.secondary", sx: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", display: "block" } }, cluster.url)), needsMetrics && m && /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", spacing: 1.5, alignItems: "center" }, showCpu && /* @__PURE__ */ import_react.default.createElement(MetricBar, { label: "CPU", value: m.cpu, color: "#2196f3" }), showMem && /* @__PURE__ */ import_react.default.createElement(MetricBar, { label: "MEM", value: m.memory, color: "#9c27b0" }), showPods && m.maxPods > 0 && /* @__PURE__ */ import_react.default.createElement(MetricBar, { label: "Pods", value: m.pods / m.maxPods * 100, color: "#ff9800" })), /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", spacing: 0.75, alignItems: "center" }, /* @__PURE__ */ import_react.default.createElement(StatusLight, { color: "#4caf50", label: "Healthy" }), /* @__PURE__ */ import_react.default.createElement(StatusLight, { color: "#ff9800", label: "Warning" }), /* @__PURE__ */ import_react.default.createElement(StatusLight, { color: "#f44336", label: "Critical" })), /* @__PURE__ */ import_react.default.createElement(
118
+ import_material.Button,
119
+ {
120
+ variant: "outlined",
121
+ size: "small",
122
+ startIcon: /* @__PURE__ */ import_react.default.createElement(import_icons_material.OpenInBrowser, null),
123
+ onClick: () => launchMagnify(cluster.name)
124
+ },
125
+ "Magnify"
126
+ ))));
127
+ }), props.clusters.length === 0 && /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "body2", color: "text.secondary", sx: { p: 2 } }, "No clusters defined. Add a cluster to get started."));
128
+ };
129
+
130
+ // src/front/ClusterizedSetup.tsx
131
+ var import_react2 = __toESM(require_react(), 1);
132
+ var import_material2 = __toESM(require_material(), 1);
133
+ var ClusterizedSetup = ({ config, onSave, onClose }) => {
134
+ const [showCpu, setShowCpu] = (0, import_react2.useState)(config.showCpu ?? true);
135
+ const [showMem, setShowMem] = (0, import_react2.useState)(config.showMem ?? true);
136
+ const [showPods, setShowPods] = (0, import_react2.useState)(config.showPods ?? true);
137
+ return /* @__PURE__ */ import_react2.default.createElement(import_material2.Dialog, { open: true }, /* @__PURE__ */ import_react2.default.createElement(import_material2.DialogTitle, null, "Clusterized setup"), /* @__PURE__ */ import_react2.default.createElement(import_material2.DialogContent, null, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "column", sx: { pt: 1 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.FormControlLabel, { control: /* @__PURE__ */ import_react2.default.createElement(import_material2.Checkbox, { checked: showCpu, onChange: (e) => setShowCpu(e.target.checked) }), label: "Show CPU usage" }), /* @__PURE__ */ import_react2.default.createElement(import_material2.FormControlLabel, { control: /* @__PURE__ */ import_react2.default.createElement(import_material2.Checkbox, { checked: showMem, onChange: (e) => setShowMem(e.target.checked) }), label: "Show memory usage" }), /* @__PURE__ */ import_react2.default.createElement(import_material2.FormControlLabel, { control: /* @__PURE__ */ import_react2.default.createElement(import_material2.Checkbox, { checked: showPods, onChange: (e) => setShowPods(e.target.checked) }), label: "Show pod count" }))), /* @__PURE__ */ import_react2.default.createElement(import_material2.DialogActions, null, /* @__PURE__ */ import_react2.default.createElement(import_material2.Button, { onClick: () => onSave({ showCpu, showMem, showPods }), variant: "contained" }, "Save"), /* @__PURE__ */ import_react2.default.createElement(import_material2.Button, { onClick: onClose }, "Cancel")));
99
138
  };
100
139
 
101
140
  // src/front/index.ts
102
141
  window.__kwirth_homepages__["clusterized"] = {
103
142
  homepageId: "clusterized",
104
143
  displayName: "Clusterized",
105
- Component: Clusterized
144
+ Component: Clusterized,
145
+ SetupDialog: ClusterizedSetup,
146
+ defaultConfig: { showCpu: true, showMem: true, showPods: true }
106
147
  };
107
148
  })();
package/package.json CHANGED
@@ -2,6 +2,6 @@
2
2
  "id": "clusterized",
3
3
  "name": "@kwirthmagnify/kwirth-homepage-clusterized",
4
4
  "displayName": "Clusterized",
5
- "version": "0.1.1",
5
+ "version": "0.1.2",
6
6
  "description": "Cluster-centric homepage for Kwirth — one card per cluster with status indicator and quick Magnify access"
7
7
  }