@kwirthmagnify/kwirth-homepage-clusterized 0.1.4 → 0.1.5

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 +35 -26
  2. package/package.json +1 -1
package/front.js CHANGED
@@ -57,10 +57,22 @@
57
57
  });
58
58
 
59
59
  // src/front/Clusterized.tsx
60
+ var import_react2 = __toESM(require_react(), 1);
61
+ var import_material2 = __toESM(require_material(), 1);
62
+ var import_icons_material = __toESM(require_icons_material(), 1);
63
+
64
+ // src/front/ClusterizedSetup.tsx
60
65
  var import_react = __toESM(require_react(), 1);
61
66
  var import_material = __toESM(require_material(), 1);
62
- var import_icons_material = __toESM(require_icons_material(), 1);
63
- var StatusLight = ({ color, active, label }) => /* @__PURE__ */ import_react.default.createElement(import_material.Tooltip, { title: label }, /* @__PURE__ */ import_react.default.createElement(import_material.Box, { sx: {
67
+ var ClusterizedSetup = ({ config, onSave, onClose }) => {
68
+ const [showCpu, setShowCpu] = (0, import_react.useState)(config.showCpu ?? true);
69
+ const [showMem, setShowMem] = (0, import_react.useState)(config.showMem ?? true);
70
+ const [showPods, setShowPods] = (0, import_react.useState)(config.showPods ?? true);
71
+ return /* @__PURE__ */ import_react.default.createElement(import_material.Dialog, { open: true }, /* @__PURE__ */ import_react.default.createElement(import_material.DialogTitle, null, "Clusterized setup"), /* @__PURE__ */ import_react.default.createElement(import_material.DialogContent, null, /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "column", sx: { pt: 1 } }, /* @__PURE__ */ import_react.default.createElement(import_material.FormControlLabel, { control: /* @__PURE__ */ import_react.default.createElement(import_material.Checkbox, { checked: showCpu, onChange: (e) => setShowCpu(e.target.checked) }), label: "Show CPU usage" }), /* @__PURE__ */ import_react.default.createElement(import_material.FormControlLabel, { control: /* @__PURE__ */ import_react.default.createElement(import_material.Checkbox, { checked: showMem, onChange: (e) => setShowMem(e.target.checked) }), label: "Show memory usage" }), /* @__PURE__ */ import_react.default.createElement(import_material.FormControlLabel, { control: /* @__PURE__ */ import_react.default.createElement(import_material.Checkbox, { checked: showPods, onChange: (e) => setShowPods(e.target.checked) }), label: "Show pod count" }))), /* @__PURE__ */ import_react.default.createElement(import_material.DialogActions, null, /* @__PURE__ */ import_react.default.createElement(import_material.Button, { onClick: () => onSave({ showCpu, showMem, showPods }), variant: "contained" }, "Save"), /* @__PURE__ */ import_react.default.createElement(import_material.Button, { onClick: onClose }, "Cancel")));
72
+ };
73
+
74
+ // src/front/Clusterized.tsx
75
+ var StatusLight = ({ color, active, label }) => /* @__PURE__ */ import_react2.default.createElement(import_material2.Tooltip, { title: label }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: {
64
76
  width: 14,
65
77
  height: 14,
66
78
  borderRadius: "50%",
@@ -70,22 +82,24 @@
70
82
  transition: "all 0.3s ease",
71
83
  cursor: "default"
72
84
  } }));
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,
85
+ var MetricBar = ({ label, value, color }) => /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { minWidth: 72 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center" }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "caption", color: "text.secondary", sx: { fontSize: "0.65rem" } }, label), /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "caption", fontWeight: "bold", sx: { fontSize: "0.65rem" } }, Math.round(value), "%")), /* @__PURE__ */ import_react2.default.createElement(
86
+ import_material2.LinearProgress,
75
87
  {
76
88
  variant: "determinate",
77
89
  value: Math.min(Math.max(value, 0), 100),
78
90
  sx: { height: 4, borderRadius: 2, bgcolor: "action.hover", "& .MuiLinearProgress-bar": { bgcolor: color, borderRadius: 2 } }
79
91
  }
80
92
  ));
81
- var MetricPlaceholder = ({ label }) => /* @__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.disabled", sx: { fontSize: "0.65rem" } }, label), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { variant: "caption", sx: { fontSize: "0.65rem" } }, "\xA0")), /* @__PURE__ */ import_react.default.createElement(import_material.Box, { sx: { height: 4, borderRadius: 2, bgcolor: "action.hover" } }));
93
+ var MetricPlaceholder = ({ label }) => /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { minWidth: 72 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center" }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "caption", color: "text.disabled", sx: { fontSize: "0.65rem" } }, label), /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "caption", sx: { fontSize: "0.65rem" } }, "\xA0")), /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { height: 4, borderRadius: 2, bgcolor: "action.hover" } }));
82
94
  var Clusterized = (props) => {
83
- const [metrics, setMetrics] = (0, import_react.useState)({});
84
- const showCpu = props.config?.showCpu ?? true;
85
- const showMem = props.config?.showMem ?? true;
86
- const showPods = props.config?.showPods ?? true;
95
+ const [localConfig, setLocalConfig] = (0, import_react2.useState)(props.config ?? {});
96
+ const [showSetup, setShowSetup] = (0, import_react2.useState)(false);
97
+ const [metrics, setMetrics] = (0, import_react2.useState)({});
98
+ const showCpu = localConfig.showCpu ?? true;
99
+ const showMem = localConfig.showMem ?? true;
100
+ const showPods = localConfig.showPods ?? true;
87
101
  const needsMetrics = showCpu || showMem || showPods;
88
- (0, import_react.useEffect)(() => {
102
+ (0, import_react2.useEffect)(() => {
89
103
  if (!needsMetrics || !props.getClusterMetrics) return;
90
104
  const fetchAll = () => {
91
105
  props.clusters.forEach((cluster) => {
@@ -97,7 +111,12 @@
97
111
  fetchAll();
98
112
  const timer = setInterval(fetchAll, 3e4);
99
113
  return () => clearInterval(timer);
100
- }, [props.clusters, props.config, needsMetrics]);
114
+ }, [props.clusters, localConfig, needsMetrics]);
115
+ const saveConfig = (cfg) => {
116
+ localStorage.setItem("kwirth.homepage.config.clusterized", JSON.stringify(cfg));
117
+ setLocalConfig(cfg);
118
+ setShowSetup(false);
119
+ };
101
120
  const launchMagnify = (clusterName) => {
102
121
  props.onHomepageSelectTab({
103
122
  name: clusterName,
@@ -113,29 +132,19 @@
113
132
  }
114
133
  });
115
134
  };
116
- 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) => {
135
+ return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { display: "flex", flexDirection: "column", height: "100%" } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { display: "flex", justifyContent: "flex-end", px: 1.5, py: 0.5, borderBottom: "1px solid", borderColor: "divider" } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.IconButton, { size: "small", onClick: () => setShowSetup(true) }, /* @__PURE__ */ import_react2.default.createElement(import_icons_material.Settings, { fontSize: "small" }))), /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { p: 2, display: "flex", flexDirection: "column", gap: 2, overflowY: "auto", flexGrow: 1 } }, props.clusters.map((cluster) => {
117
136
  const m = metrics[cluster.name];
118
- 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 && /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", spacing: 1.5, alignItems: "center" }, showCpu && (m ? /* @__PURE__ */ import_react.default.createElement(MetricBar, { label: "CPU", value: m.cpu, color: "#2196f3" }) : /* @__PURE__ */ import_react.default.createElement(MetricPlaceholder, { label: "CPU" })), showMem && (m ? /* @__PURE__ */ import_react.default.createElement(MetricBar, { label: "MEM", value: m.memory, color: "#9c27b0" }) : /* @__PURE__ */ import_react.default.createElement(MetricPlaceholder, { label: "MEM" })), showPods && (m && m.maxPods > 0 ? /* @__PURE__ */ import_react.default.createElement(MetricBar, { label: "Pods", value: m.pods / m.maxPods * 100, color: "#ff9800" }) : /* @__PURE__ */ import_react.default.createElement(MetricPlaceholder, { label: "Pods" }))), /* @__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(
119
- import_material.Button,
137
+ return /* @__PURE__ */ import_react2.default.createElement(import_material2.Card, { key: cluster.name, variant: "outlined" }, /* @__PURE__ */ import_react2.default.createElement(import_material2.CardContent, { sx: { py: 1.5, "&:last-child": { pb: 1.5 } } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", alignItems: "center", spacing: 2 }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "h6", sx: { lineHeight: 1.3 } }, cluster.name), /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "caption", color: "text.secondary", sx: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", display: "block" } }, cluster.url)), needsMetrics && /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 1.5, alignItems: "center" }, showCpu && (m ? /* @__PURE__ */ import_react2.default.createElement(MetricBar, { label: "CPU", value: m.cpu, color: "#2196f3" }) : /* @__PURE__ */ import_react2.default.createElement(MetricPlaceholder, { label: "CPU" })), showMem && (m ? /* @__PURE__ */ import_react2.default.createElement(MetricBar, { label: "MEM", value: m.memory, color: "#9c27b0" }) : /* @__PURE__ */ import_react2.default.createElement(MetricPlaceholder, { label: "MEM" })), showPods && (m && m.maxPods > 0 ? /* @__PURE__ */ import_react2.default.createElement(MetricBar, { label: "Pods", value: m.pods / m.maxPods * 100, color: "#ff9800" }) : /* @__PURE__ */ import_react2.default.createElement(MetricPlaceholder, { label: "Pods" }))), /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 0.75, alignItems: "center" }, /* @__PURE__ */ import_react2.default.createElement(StatusLight, { color: "#4caf50", label: "Healthy" }), /* @__PURE__ */ import_react2.default.createElement(StatusLight, { color: "#ff9800", label: "Warning" }), /* @__PURE__ */ import_react2.default.createElement(StatusLight, { color: "#f44336", label: "Critical" })), /* @__PURE__ */ import_react2.default.createElement(
138
+ import_material2.Button,
120
139
  {
121
140
  variant: "outlined",
122
141
  size: "small",
123
- startIcon: /* @__PURE__ */ import_react.default.createElement(import_icons_material.OpenInBrowser, null),
142
+ startIcon: /* @__PURE__ */ import_react2.default.createElement(import_icons_material.OpenInBrowser, null),
124
143
  onClick: () => launchMagnify(cluster.name)
125
144
  },
126
145
  "Magnify"
127
146
  ))));
128
- }), 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."));
129
- };
130
-
131
- // src/front/ClusterizedSetup.tsx
132
- var import_react2 = __toESM(require_react(), 1);
133
- var import_material2 = __toESM(require_material(), 1);
134
- var ClusterizedSetup = ({ config, onSave, onClose }) => {
135
- const [showCpu, setShowCpu] = (0, import_react2.useState)(config.showCpu ?? true);
136
- const [showMem, setShowMem] = (0, import_react2.useState)(config.showMem ?? true);
137
- const [showPods, setShowPods] = (0, import_react2.useState)(config.showPods ?? true);
138
- 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")));
147
+ }), props.clusters.length === 0 && /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "body2", color: "text.secondary", sx: { p: 2 } }, "No clusters defined. Add a cluster to get started.")), showSetup && /* @__PURE__ */ import_react2.default.createElement(ClusterizedSetup, { config: localConfig, onSave: saveConfig, onClose: () => setShowSetup(false) }));
139
148
  };
140
149
 
141
150
  // src/front/index.ts
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.4",
5
+ "version": "0.1.5",
6
6
  "description": "Cluster-centric homepage for Kwirth — one card per cluster with status indicator and quick Magnify access"
7
7
  }