@kwirthmagnify/kwirth-homepage-matrix 0.1.2 → 0.1.4
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.
- package/front.js +163 -68
- package/package.json +1 -1
package/front.js
CHANGED
|
@@ -57,17 +57,73 @@
|
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
// src/front/Matrix.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/MatrixSetup.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
67
|
var MATRIX_GREEN = "#00ff41";
|
|
64
68
|
var MATRIX_DIM = "#006620";
|
|
69
|
+
var MatrixSetup = ({ config, onSave, onClose }) => {
|
|
70
|
+
const [showQuickAccess, setShowQuickAccess] = (0, import_react.useState)(config.showQuickAccess ?? true);
|
|
71
|
+
const [showRain, setShowRain] = (0, import_react.useState)(config.showRain ?? true);
|
|
72
|
+
const [rainSpeed, setRainSpeed] = (0, import_react.useState)(config.rainSpeed ?? 12);
|
|
73
|
+
const [rainActiveLines, setRainActiveLines] = (0, import_react.useState)(config.rainActiveLines ?? 50);
|
|
74
|
+
const checkSx = { color: MATRIX_DIM, "&.Mui-checked": { color: MATRIX_GREEN } };
|
|
75
|
+
const labelSx = { fontFamily: "monospace", fontSize: "0.85rem", color: MATRIX_GREEN };
|
|
76
|
+
const sliderSx = { color: MATRIX_GREEN, "& .MuiSlider-thumb": { bgcolor: MATRIX_GREEN }, "& .MuiSlider-rail": { bgcolor: MATRIX_DIM } };
|
|
77
|
+
return /* @__PURE__ */ import_react.default.createElement(import_material.Dialog, { open: true, PaperProps: { sx: { bgcolor: "#000", border: `1px solid ${MATRIX_GREEN}`, boxShadow: `0 0 20px rgba(0,255,65,0.3)`, color: MATRIX_GREEN, minWidth: 360 } } }, /* @__PURE__ */ import_react.default.createElement(import_material.DialogTitle, { sx: { fontFamily: "monospace", fontSize: "1rem", color: MATRIX_GREEN, borderBottom: `1px solid ${MATRIX_DIM}`, pb: 1 } }, "// matrix setup"), /* @__PURE__ */ import_react.default.createElement(import_material.DialogContent, null, /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "column", spacing: 2.5, sx: { pt: 2 } }, /* @__PURE__ */ import_react.default.createElement(
|
|
78
|
+
import_material.FormControlLabel,
|
|
79
|
+
{
|
|
80
|
+
control: /* @__PURE__ */ import_react.default.createElement(import_material.Checkbox, { checked: showQuickAccess, onChange: (e) => setShowQuickAccess(e.target.checked), sx: checkSx }),
|
|
81
|
+
label: /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: labelSx }, "Show tabs / workspaces card")
|
|
82
|
+
}
|
|
83
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
84
|
+
import_material.FormControlLabel,
|
|
85
|
+
{
|
|
86
|
+
control: /* @__PURE__ */ import_react.default.createElement(import_material.Checkbox, { checked: showRain, onChange: (e) => setShowRain(e.target.checked), sx: checkSx }),
|
|
87
|
+
label: /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: labelSx }, "Falling code")
|
|
88
|
+
}
|
|
89
|
+
), /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "column", spacing: 0.5, sx: { opacity: showRain ? 1 : 0.3, pointerEvents: showRain ? "auto" : "none" } }, /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", justifyContent: "space-between" }, /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.75rem", color: MATRIX_DIM } }, "Speed"), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.75rem", color: MATRIX_GREEN } }, rainSpeed <= 5 ? "fast" : rainSpeed <= 12 ? "normal" : "slow")), /* @__PURE__ */ import_react.default.createElement(
|
|
90
|
+
import_material.Slider,
|
|
91
|
+
{
|
|
92
|
+
value: 21 - rainSpeed,
|
|
93
|
+
min: 1,
|
|
94
|
+
max: 20,
|
|
95
|
+
onChange: (_, v) => setRainSpeed(21 - v),
|
|
96
|
+
sx: sliderSx
|
|
97
|
+
}
|
|
98
|
+
), /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", justifyContent: "space-between" }, /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.6rem", color: MATRIX_DIM } }, "slow"), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.6rem", color: MATRIX_DIM } }, "fast"))), /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "column", spacing: 0.5, sx: { opacity: showRain ? 1 : 0.3, pointerEvents: showRain ? "auto" : "none" } }, /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", justifyContent: "space-between" }, /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.75rem", color: MATRIX_DIM } }, "Active lines"), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.75rem", color: MATRIX_GREEN } }, rainActiveLines)), /* @__PURE__ */ import_react.default.createElement(
|
|
99
|
+
import_material.Slider,
|
|
100
|
+
{
|
|
101
|
+
value: rainActiveLines,
|
|
102
|
+
min: 5,
|
|
103
|
+
max: 100,
|
|
104
|
+
onChange: (_, v) => setRainActiveLines(v),
|
|
105
|
+
sx: sliderSx
|
|
106
|
+
}
|
|
107
|
+
), /* @__PURE__ */ import_react.default.createElement(import_material.Stack, { direction: "row", justifyContent: "space-between" }, /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.6rem", color: MATRIX_DIM } }, "5"), /* @__PURE__ */ import_react.default.createElement(import_material.Typography, { sx: { fontFamily: "monospace", fontSize: "0.6rem", color: MATRIX_DIM } }, "100"))))), /* @__PURE__ */ import_react.default.createElement(import_material.DialogActions, { sx: { borderTop: `1px solid ${MATRIX_DIM}`, pt: 1 } }, /* @__PURE__ */ import_react.default.createElement(
|
|
108
|
+
import_material.Button,
|
|
109
|
+
{
|
|
110
|
+
onClick: () => onSave({ showQuickAccess, showRain, rainSpeed, rainActiveLines }),
|
|
111
|
+
variant: "contained",
|
|
112
|
+
sx: { bgcolor: MATRIX_GREEN, color: "#000", fontFamily: "monospace", fontWeight: "bold", "&:hover": { bgcolor: "#00cc33" } }
|
|
113
|
+
},
|
|
114
|
+
"Save"
|
|
115
|
+
), /* @__PURE__ */ import_react.default.createElement(import_material.Button, { onClick: onClose, sx: { color: MATRIX_DIM, fontFamily: "monospace" } }, "Cancel")));
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// src/front/Matrix.tsx
|
|
119
|
+
var MATRIX_GREEN2 = "#00ff41";
|
|
120
|
+
var MATRIX_DIM2 = "#006620";
|
|
65
121
|
var MATRIX_GLOW = "rgba(0,255,65,0.3)";
|
|
66
122
|
var EVENTS_LIMIT = 25;
|
|
67
123
|
var POLL_INTERVAL_MS = 1e4;
|
|
68
|
-
var MatrixRain = () => {
|
|
69
|
-
const canvasRef = (0,
|
|
70
|
-
(0,
|
|
124
|
+
var MatrixRain = ({ speed, activeLines }) => {
|
|
125
|
+
const canvasRef = (0, import_react2.useRef)(null);
|
|
126
|
+
(0, import_react2.useEffect)(() => {
|
|
71
127
|
const canvas = canvasRef.current;
|
|
72
128
|
if (!canvas) return;
|
|
73
129
|
const ctx = canvas.getContext("2d");
|
|
@@ -75,25 +131,44 @@
|
|
|
75
131
|
const fontSize = 22;
|
|
76
132
|
const chars = "\u30A2\u30A4\u30A6\u30A8\u30AA\u30AB\u30AD\u30AF\u30B1\u30B3\u30B5\u30B7\u30B9\u30BB\u30BD\u30BF\u30C1\u30C4\u30C6\u30C8\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D2\u30D5\u30D8\u30DB\u30DE\u30DF\u30E0\u30E1\u30E2\u30E4\u30E6\u30E8\u30E9\u30EA\u30EB\u30EC\u30ED\u30EF\u30F2\u30F30123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
77
133
|
let drops = [];
|
|
134
|
+
let active = [];
|
|
78
135
|
let animId;
|
|
79
136
|
let frame = 0;
|
|
80
|
-
const
|
|
137
|
+
const activateDrops = (cols, h, count) => {
|
|
138
|
+
const indices = Array.from({ length: cols }, (_, i) => i);
|
|
139
|
+
for (let i = indices.length - 1; i > 0; i--) {
|
|
140
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
141
|
+
[indices[i], indices[j]] = [indices[j], indices[i]];
|
|
142
|
+
}
|
|
143
|
+
const n = Math.min(count, cols);
|
|
144
|
+
indices.slice(0, n).forEach((i) => {
|
|
145
|
+
active[i] = true;
|
|
146
|
+
drops[i] = -Math.floor(Math.random() * (h / fontSize) * 2);
|
|
147
|
+
});
|
|
148
|
+
indices.slice(n).forEach((i) => {
|
|
149
|
+
active[i] = false;
|
|
150
|
+
drops[i] = -99999;
|
|
151
|
+
});
|
|
152
|
+
};
|
|
81
153
|
const resize = (w, h) => {
|
|
82
154
|
canvas.width = w;
|
|
83
155
|
canvas.height = h;
|
|
84
156
|
const cols = Math.floor(w / fontSize);
|
|
85
|
-
drops = Array
|
|
157
|
+
drops = new Array(cols).fill(0);
|
|
158
|
+
active = new Array(cols).fill(false);
|
|
159
|
+
activateDrops(cols, h, activeLines);
|
|
86
160
|
};
|
|
87
161
|
const draw = () => {
|
|
88
162
|
frame++;
|
|
89
163
|
ctx.fillStyle = "rgba(0,0,0,0.02)";
|
|
90
164
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
91
165
|
ctx.font = `${fontSize}px monospace`;
|
|
92
|
-
if (frame %
|
|
166
|
+
if (frame % speed === 0) {
|
|
93
167
|
for (let i = 0; i < drops.length; i++) {
|
|
168
|
+
if (!active[i]) continue;
|
|
94
169
|
if (drops[i] > 0) {
|
|
95
170
|
const bright = Math.random() > 0.97;
|
|
96
|
-
ctx.fillStyle = bright ? "#ccffcc" :
|
|
171
|
+
ctx.fillStyle = bright ? "#ccffcc" : MATRIX_GREEN2;
|
|
97
172
|
ctx.fillText(chars[Math.floor(Math.random() * chars.length)], i * fontSize, drops[i] * fontSize);
|
|
98
173
|
}
|
|
99
174
|
if (drops[i] * fontSize > canvas.height) {
|
|
@@ -114,8 +189,8 @@
|
|
|
114
189
|
cancelAnimationFrame(animId);
|
|
115
190
|
observer.disconnect();
|
|
116
191
|
};
|
|
117
|
-
}, []);
|
|
118
|
-
return /* @__PURE__ */
|
|
192
|
+
}, [speed, activeLines]);
|
|
193
|
+
return /* @__PURE__ */ import_react2.default.createElement(
|
|
119
194
|
"canvas",
|
|
120
195
|
{
|
|
121
196
|
ref: canvasRef,
|
|
@@ -126,9 +201,9 @@
|
|
|
126
201
|
var StatusLight = ({ online, events, animationDelay }) => {
|
|
127
202
|
const hasError = online && (events ?? []).some((e) => e.type !== "Normal" && e.type !== "Warning");
|
|
128
203
|
const hasWarning = online && !hasError && (events ?? []).some((e) => e.type === "Warning");
|
|
129
|
-
const color = !online ? "#ff3333" : hasError ? "#ff3333" : hasWarning ? "#ff9800" :
|
|
204
|
+
const color = !online ? "#ff3333" : hasError ? "#ff3333" : hasWarning ? "#ff9800" : MATRIX_GREEN2;
|
|
130
205
|
const label = !online ? "Offline" : hasError ? "Errors detected" : hasWarning ? "Warnings detected" : "Online";
|
|
131
|
-
return /* @__PURE__ */
|
|
206
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Tooltip, { title: label }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: {
|
|
132
207
|
width: 12,
|
|
133
208
|
height: 12,
|
|
134
209
|
borderRadius: "50%",
|
|
@@ -141,9 +216,9 @@
|
|
|
141
216
|
} }));
|
|
142
217
|
};
|
|
143
218
|
var MetricBar = ({ label, value }) => {
|
|
144
|
-
const barRef = (0,
|
|
145
|
-
const [cols, setCols] = (0,
|
|
146
|
-
(0,
|
|
219
|
+
const barRef = (0, import_react2.useRef)(null);
|
|
220
|
+
const [cols, setCols] = (0, import_react2.useState)(10);
|
|
221
|
+
(0, import_react2.useEffect)(() => {
|
|
147
222
|
if (!barRef.current) return;
|
|
148
223
|
const obs = new ResizeObserver(() => {
|
|
149
224
|
if (barRef.current) setCols(Math.max(5, Math.floor(barRef.current.offsetWidth / 6)));
|
|
@@ -153,11 +228,11 @@
|
|
|
153
228
|
}, []);
|
|
154
229
|
const filled = Math.round(value * cols / 100);
|
|
155
230
|
const bar = "\u2588".repeat(filled) + "\u2591".repeat(cols - filled);
|
|
156
|
-
const color = value > 90 ? "#ff3333" : value > 80 ? "#b36200" :
|
|
157
|
-
return /* @__PURE__ */
|
|
231
|
+
const color = value > 90 ? "#ff3333" : value > 80 ? "#b36200" : MATRIX_GREEN2;
|
|
232
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", alignItems: "center", spacing: 0 }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", fontSize: "0.65rem", color: MATRIX_DIM2, width: 28, flexShrink: 0 } }, label), /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { ref: barRef, sx: { fontFamily: "monospace", fontSize: "0.65rem", color, letterSpacing: "-0.5px", flex: 1, overflow: "hidden", whiteSpace: "nowrap" } }, bar), /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", fontSize: "0.65rem", color, flexShrink: 0, pl: 0.5, width: 32, textAlign: "right" } }, Math.round(value), "%"));
|
|
158
233
|
};
|
|
159
|
-
var MiniInfoCard = ({ label, value, stretch }) => /* @__PURE__ */
|
|
160
|
-
border: `1px solid ${
|
|
234
|
+
var MiniInfoCard = ({ label, value, stretch }) => /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: {
|
|
235
|
+
border: `1px solid ${MATRIX_DIM2}`,
|
|
161
236
|
borderRadius: 1,
|
|
162
237
|
px: 1,
|
|
163
238
|
display: "flex",
|
|
@@ -166,51 +241,51 @@
|
|
|
166
241
|
justifyContent: "center",
|
|
167
242
|
minWidth: 70,
|
|
168
243
|
...stretch ? { height: "100%" } : { py: 0.75 }
|
|
169
|
-
} }, /* @__PURE__ */
|
|
244
|
+
} }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", fontSize: "1rem", color: MATRIX_GREEN2, lineHeight: 1.2 } }, value), /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", fontSize: "0.78rem", color: MATRIX_DIM2, lineHeight: 1.2 } }, label));
|
|
170
245
|
var EventLog = ({ events }) => {
|
|
171
|
-
const boxRef = (0,
|
|
172
|
-
(0,
|
|
246
|
+
const boxRef = (0, import_react2.useRef)(null);
|
|
247
|
+
(0, import_react2.useEffect)(() => {
|
|
173
248
|
if (boxRef.current) boxRef.current.scrollTop = boxRef.current.scrollHeight;
|
|
174
249
|
}, [events]);
|
|
175
|
-
return /* @__PURE__ */
|
|
250
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { ref: boxRef, sx: {
|
|
176
251
|
flex: 1,
|
|
177
252
|
overflowY: "auto",
|
|
178
253
|
overflowX: "auto",
|
|
179
254
|
fontFamily: "monospace",
|
|
180
255
|
fontSize: "0.55rem",
|
|
181
256
|
lineHeight: 1.9,
|
|
182
|
-
color:
|
|
257
|
+
color: MATRIX_DIM2,
|
|
183
258
|
bgcolor: "rgba(0,18,6,0.92)",
|
|
184
|
-
border: `1px solid ${
|
|
259
|
+
border: `1px solid ${MATRIX_DIM2}`,
|
|
185
260
|
borderRadius: 1,
|
|
186
261
|
p: 1,
|
|
187
262
|
whiteSpace: "nowrap",
|
|
188
263
|
"&::-webkit-scrollbar": { width: 4, height: 4 },
|
|
189
|
-
"&::-webkit-scrollbar-thumb": { bgcolor:
|
|
190
|
-
} }, events.length === 0 ? /* @__PURE__ */
|
|
264
|
+
"&::-webkit-scrollbar-thumb": { bgcolor: MATRIX_DIM2, borderRadius: 2 }
|
|
265
|
+
} }, events.length === 0 ? /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { color: MATRIX_GREEN2, opacity: 0.4 } }, "// follow the white rabbit") : [...events].reverse().map((e, i) => {
|
|
191
266
|
const d = new Date(e.time);
|
|
192
267
|
const t = [d.getHours(), d.getMinutes(), d.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
|
|
193
|
-
return /* @__PURE__ */
|
|
268
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { key: i, sx: { color: e.type === "Warning" ? "#ff9800" : MATRIX_GREEN2, mb: 0.2 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { component: "span", sx: { color: MATRIX_DIM2, mr: 0.5 } }, t), /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { component: "span", sx: { mr: 0.5 } }, "[", e.reason, "]"), /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { component: "span", sx: { color: MATRIX_DIM2, mr: 0.5 } }, e.object), e.message);
|
|
194
269
|
}));
|
|
195
270
|
};
|
|
196
271
|
var matrixCardSx = {
|
|
197
272
|
bgcolor: "rgba(0,0,0,0.80)",
|
|
198
|
-
border: `1px solid ${
|
|
273
|
+
border: `1px solid ${MATRIX_GREEN2}`,
|
|
199
274
|
boxShadow: `0 0 10px ${MATRIX_GLOW}, inset 0 0 10px rgba(0,255,65,0.05)`,
|
|
200
|
-
color:
|
|
275
|
+
color: MATRIX_GREEN2,
|
|
201
276
|
backdropFilter: "blur(2px)"
|
|
202
277
|
};
|
|
203
278
|
var matrixIconBtnSx = {
|
|
204
|
-
color:
|
|
279
|
+
color: MATRIX_DIM2,
|
|
205
280
|
p: 0.25,
|
|
206
281
|
borderRadius: 0.5,
|
|
207
282
|
fontSize: "0.6rem",
|
|
208
283
|
fontFamily: "monospace",
|
|
209
284
|
lineHeight: 1,
|
|
210
|
-
"&:hover": { color:
|
|
285
|
+
"&:hover": { color: MATRIX_GREEN2, bgcolor: "rgba(0,255,65,0.1)" }
|
|
211
286
|
};
|
|
212
287
|
function QuickColumn({ label, items, getKey, getName, getSub, onLaunch, onDelete }) {
|
|
213
|
-
return /* @__PURE__ */
|
|
288
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: 0.5, alignSelf: "stretch" } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", fontSize: "0.75rem", color: MATRIX_DIM2, letterSpacing: 1, mb: 0.25 } }, "// ", label), /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { borderTop: `1px solid ${MATRIX_DIM2}`, mb: 0.5 } }), items.length === 0 ? /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", fontSize: "0.7rem", color: MATRIX_DIM2, opacity: 0.5 } }, "// empty") : items.map((item) => /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { key: getKey(item), direction: "row", alignItems: "center", sx: { minWidth: 0, gap: 0.5 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", fontSize: "0.75rem", flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ import_react2.default.createElement("span", { style: { color: MATRIX_GREEN2 } }, getName(item)), getSub(item) && /* @__PURE__ */ import_react2.default.createElement("span", { style: { color: MATRIX_DIM2, paddingLeft: "20px" } }, getSub(item))), /* @__PURE__ */ import_react2.default.createElement(import_material2.Tooltip, { title: "Launch" }, /* @__PURE__ */ import_react2.default.createElement(import_material2.IconButton, { size: "small", sx: matrixIconBtnSx, onClick: () => onLaunch(item) }, "\u25B6")), /* @__PURE__ */ import_react2.default.createElement(import_material2.Tooltip, { title: "Remove" }, /* @__PURE__ */ import_react2.default.createElement(import_material2.IconButton, { size: "small", sx: matrixIconBtnSx, onClick: () => onDelete(item) }, "\u2715")))));
|
|
214
289
|
}
|
|
215
290
|
var QuickAccessCard = (props) => {
|
|
216
291
|
const delLastTab = (tab) => props.onUpdateTabs(props.lastTabs.filter((t) => t.name !== tab.name || t.channel !== tab.channel), props.favTabs);
|
|
@@ -219,7 +294,7 @@
|
|
|
219
294
|
const delFavWs = (ws) => props.onUpdateWorkspaces(props.lastWorkspaces, props.favWorkspaces.filter((w) => w.name !== ws.name));
|
|
220
295
|
const allEmpty = props.lastTabs.length === 0 && props.favTabs.length === 0 && props.lastWorkspaces.length === 0 && props.favWorkspaces.length === 0;
|
|
221
296
|
if (allEmpty) return null;
|
|
222
|
-
return /* @__PURE__ */
|
|
297
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Card, { variant: "outlined", sx: { ...matrixCardSx, gridColumn: "1 / -1", minHeight: 160 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.CardContent, { sx: { py: 1.5, px: 2, height: "100%", boxSizing: "border-box", "&:last-child": { pb: 1.5 } } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 2, alignItems: "flex-start", sx: { minWidth: 0 } }, /* @__PURE__ */ import_react2.default.createElement(
|
|
223
298
|
QuickColumn,
|
|
224
299
|
{
|
|
225
300
|
label: "LAST TABS",
|
|
@@ -230,7 +305,7 @@
|
|
|
230
305
|
onLaunch: (t) => props.onHomepageSelectTab(t),
|
|
231
306
|
onDelete: delLastTab
|
|
232
307
|
}
|
|
233
|
-
), /* @__PURE__ */
|
|
308
|
+
), /* @__PURE__ */ import_react2.default.createElement(import_material2.Divider, { orientation: "vertical", flexItem: true, sx: { borderColor: MATRIX_DIM2, opacity: 0.4 } }), /* @__PURE__ */ import_react2.default.createElement(
|
|
234
309
|
QuickColumn,
|
|
235
310
|
{
|
|
236
311
|
label: "FAV TABS",
|
|
@@ -241,7 +316,7 @@
|
|
|
241
316
|
onLaunch: (t) => props.onHomepageSelectTab(t),
|
|
242
317
|
onDelete: delFavTab
|
|
243
318
|
}
|
|
244
|
-
), /* @__PURE__ */
|
|
319
|
+
), /* @__PURE__ */ import_react2.default.createElement(import_material2.Divider, { orientation: "vertical", flexItem: true, sx: { borderColor: MATRIX_DIM2, opacity: 0.4 } }), /* @__PURE__ */ import_react2.default.createElement(
|
|
245
320
|
QuickColumn,
|
|
246
321
|
{
|
|
247
322
|
label: "LAST WORKSPACES",
|
|
@@ -252,7 +327,7 @@
|
|
|
252
327
|
onLaunch: (w) => props.onSelectWorkspace(w),
|
|
253
328
|
onDelete: delLastWs
|
|
254
329
|
}
|
|
255
|
-
), /* @__PURE__ */
|
|
330
|
+
), /* @__PURE__ */ import_react2.default.createElement(import_material2.Divider, { orientation: "vertical", flexItem: true, sx: { borderColor: MATRIX_DIM2, opacity: 0.4 } }), /* @__PURE__ */ import_react2.default.createElement(
|
|
256
331
|
QuickColumn,
|
|
257
332
|
{
|
|
258
333
|
label: "FAV WORKSPACES",
|
|
@@ -266,14 +341,14 @@
|
|
|
266
341
|
))));
|
|
267
342
|
};
|
|
268
343
|
var Matrix = (props) => {
|
|
269
|
-
(0,
|
|
344
|
+
(0, import_react2.useEffect)(() => {
|
|
270
345
|
const id = "matrix-keyframes";
|
|
271
346
|
if (!document.getElementById(id)) {
|
|
272
347
|
const style = document.createElement("style");
|
|
273
348
|
style.id = id;
|
|
274
349
|
style.textContent = `@keyframes matrix-status-pulse {
|
|
275
350
|
0%, 100% { opacity: 0.25; box-shadow: none; }
|
|
276
|
-
50% { opacity: 0.85; box-shadow: 0 0 7px 2px ${
|
|
351
|
+
50% { opacity: 0.85; box-shadow: 0 0 7px 2px ${MATRIX_GREEN2}; }
|
|
277
352
|
}`;
|
|
278
353
|
document.head.appendChild(style);
|
|
279
354
|
}
|
|
@@ -281,9 +356,9 @@
|
|
|
281
356
|
document.getElementById("matrix-keyframes")?.remove();
|
|
282
357
|
};
|
|
283
358
|
}, []);
|
|
284
|
-
const containerRef = (0,
|
|
285
|
-
const [containerHeight, setContainerHeight] =
|
|
286
|
-
(0,
|
|
359
|
+
const containerRef = (0, import_react2.useRef)(null);
|
|
360
|
+
const [containerHeight, setContainerHeight] = import_react2.default.useState(0);
|
|
361
|
+
(0, import_react2.useEffect)(() => {
|
|
287
362
|
const observer = new ResizeObserver(() => {
|
|
288
363
|
if (!containerRef.current) return;
|
|
289
364
|
const { top } = containerRef.current.getBoundingClientRect();
|
|
@@ -292,8 +367,8 @@
|
|
|
292
367
|
observer.observe(document.body);
|
|
293
368
|
return () => observer.disconnect();
|
|
294
369
|
}, [containerRef.current]);
|
|
295
|
-
const [clusterMetrics, setClusterMetrics] = (0,
|
|
296
|
-
(0,
|
|
370
|
+
const [clusterMetrics, setClusterMetrics] = (0, import_react2.useState)({});
|
|
371
|
+
(0, import_react2.useEffect)(() => {
|
|
297
372
|
if (!props.getClusterMetrics) return;
|
|
298
373
|
const fetchAll = () => {
|
|
299
374
|
props.clusters.forEach((cluster) => {
|
|
@@ -306,8 +381,8 @@
|
|
|
306
381
|
const timer = setInterval(fetchAll, POLL_INTERVAL_MS);
|
|
307
382
|
return () => clearInterval(timer);
|
|
308
383
|
}, [props.clusters, props.getClusterMetrics]);
|
|
309
|
-
const [clusterEvents, setClusterEvents] = (0,
|
|
310
|
-
(0,
|
|
384
|
+
const [clusterEvents, setClusterEvents] = (0, import_react2.useState)({});
|
|
385
|
+
(0, import_react2.useEffect)(() => {
|
|
311
386
|
if (!props.getClusterEvents) return;
|
|
312
387
|
const fetchAll = () => {
|
|
313
388
|
props.clusters.forEach((cluster) => {
|
|
@@ -336,22 +411,40 @@
|
|
|
336
411
|
channelObject: { clusterName, view: "cluster", namespace: "", group: "", pod: "", container: "" }
|
|
337
412
|
});
|
|
338
413
|
};
|
|
414
|
+
const [localConfig, setLocalConfig] = (0, import_react2.useState)(props.config ?? {});
|
|
415
|
+
const [showSetup, setShowSetup] = (0, import_react2.useState)(false);
|
|
416
|
+
const showQuickAccess = localConfig.showQuickAccess ?? true;
|
|
417
|
+
const showRain = localConfig.showRain ?? true;
|
|
418
|
+
const rainSpeed = localConfig.rainSpeed ?? 12;
|
|
419
|
+
const rainActiveLines = localConfig.rainActiveLines ?? 50;
|
|
420
|
+
const saveConfig = (cfg) => {
|
|
421
|
+
localStorage.setItem("kwirth.homepage.config.matrix", JSON.stringify(cfg));
|
|
422
|
+
setLocalConfig(cfg);
|
|
423
|
+
setShowSetup(false);
|
|
424
|
+
};
|
|
339
425
|
const hasMagnify = props.frontChannels.has("magnify");
|
|
340
426
|
const hasTopology = props.frontChannels.has("topology");
|
|
341
427
|
const magnifyClass = props.frontChannels.get("magnify");
|
|
342
428
|
const magnifyIcon = magnifyClass ? new magnifyClass().getChannelIcon() : null;
|
|
343
429
|
const topologyClass = props.frontChannels.get("topology");
|
|
344
|
-
const topologyIcon = topologyClass ? new topologyClass().getChannelIcon() : /* @__PURE__ */
|
|
430
|
+
const topologyIcon = topologyClass ? new topologyClass().getChannelIcon() : /* @__PURE__ */ import_react2.default.createElement(import_icons_material.AccountTree, null);
|
|
345
431
|
const matrixButtonSx = {
|
|
346
432
|
fontFamily: "monospace",
|
|
347
|
-
"&:not(.Mui-disabled)": { color:
|
|
433
|
+
"&:not(.Mui-disabled)": { color: MATRIX_GREEN2, borderColor: MATRIX_GREEN2 },
|
|
348
434
|
"&:hover:not(.Mui-disabled)": {
|
|
349
|
-
borderColor:
|
|
435
|
+
borderColor: MATRIX_GREEN2,
|
|
350
436
|
bgcolor: "rgba(0,255,65,0.1)",
|
|
351
437
|
boxShadow: `0 0 8px ${MATRIX_GLOW}`
|
|
352
438
|
}
|
|
353
439
|
};
|
|
354
|
-
return /* @__PURE__ */
|
|
440
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { ref: containerRef, sx: { position: "relative", width: "100%", height: `${containerHeight}px`, overflow: "hidden", bgcolor: "#000" } }, showRain && /* @__PURE__ */ import_react2.default.createElement(MatrixRain, { speed: rainSpeed, activeLines: rainActiveLines }), /* @__PURE__ */ import_react2.default.createElement(import_material2.IconButton, { onClick: () => setShowSetup(true), size: "small", sx: {
|
|
441
|
+
position: "absolute",
|
|
442
|
+
top: 8,
|
|
443
|
+
right: 8,
|
|
444
|
+
zIndex: 3,
|
|
445
|
+
color: MATRIX_DIM2,
|
|
446
|
+
"&:hover": { color: MATRIX_GREEN2, bgcolor: "rgba(0,255,65,0.1)" }
|
|
447
|
+
} }, /* @__PURE__ */ import_react2.default.createElement(import_icons_material.Settings, { fontSize: "small" })), /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: {
|
|
355
448
|
position: "relative",
|
|
356
449
|
zIndex: 1,
|
|
357
450
|
p: 3,
|
|
@@ -361,40 +454,40 @@
|
|
|
361
454
|
gridTemplateColumns: "repeat(2, 1fr)",
|
|
362
455
|
gap: 4,
|
|
363
456
|
alignContent: "start"
|
|
364
|
-
} }, /* @__PURE__ */
|
|
457
|
+
} }, showQuickAccess && /* @__PURE__ */ import_react2.default.createElement(QuickAccessCard, { ...props }), props.clusters.map((cluster, idx) => {
|
|
365
458
|
const clusterChannelIds = new Set((cluster.kwirthData?.channels ?? []).map((ch) => ch.id));
|
|
366
459
|
const clusterHasMagnify = hasMagnify && clusterChannelIds.has("magnify");
|
|
367
460
|
const clusterHasTopology = hasTopology && clusterChannelIds.has("topology");
|
|
368
|
-
return /* @__PURE__ */
|
|
461
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Card, { key: cluster.name, variant: "outlined", sx: {
|
|
369
462
|
bgcolor: "rgba(0,0,0,0.80)",
|
|
370
|
-
border: `1px solid ${
|
|
463
|
+
border: `1px solid ${MATRIX_GREEN2}`,
|
|
371
464
|
boxShadow: `0 0 10px ${MATRIX_GLOW}, inset 0 0 10px rgba(0,255,65,0.05)`,
|
|
372
|
-
color:
|
|
465
|
+
color: MATRIX_GREEN2,
|
|
373
466
|
backdropFilter: "blur(2px)",
|
|
374
467
|
height: `${Math.floor((containerHeight - 24 * 2 - 24) / 2) - 4}px`,
|
|
375
468
|
overflow: "hidden"
|
|
376
|
-
} }, /* @__PURE__ */
|
|
469
|
+
} }, /* @__PURE__ */ import_react2.default.createElement(import_material2.CardContent, { sx: { height: "100%", display: "flex", flexDirection: "row", gap: 2, py: 2, "&:last-child": { pb: 2 } } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "column", justifyContent: "space-between", sx: { flex: "0 0 40%", minWidth: 0 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "column", spacing: 1 }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", alignItems: "center", spacing: 1 }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "h6", sx: {
|
|
377
470
|
fontFamily: "monospace",
|
|
378
|
-
color:
|
|
471
|
+
color: MATRIX_GREEN2,
|
|
379
472
|
lineHeight: 1.3,
|
|
380
|
-
textShadow: `0 0 8px ${
|
|
473
|
+
textShadow: `0 0 8px ${MATRIX_GREEN2}`,
|
|
381
474
|
overflow: "hidden",
|
|
382
475
|
textOverflow: "ellipsis",
|
|
383
476
|
whiteSpace: "nowrap",
|
|
384
477
|
m: 0
|
|
385
|
-
} }, cluster.name), /* @__PURE__ */
|
|
478
|
+
} }, cluster.name), /* @__PURE__ */ import_react2.default.createElement(StatusLight, { online: !!clusterMetrics[cluster.name], events: clusterEvents[cluster.name], animationDelay: `${idx * 0.7 % 2.5}s` })), /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "body2", sx: {
|
|
386
479
|
fontFamily: "monospace",
|
|
387
|
-
color:
|
|
480
|
+
color: MATRIX_DIM2,
|
|
388
481
|
overflow: "hidden",
|
|
389
482
|
textOverflow: "ellipsis",
|
|
390
483
|
whiteSpace: "nowrap"
|
|
391
|
-
} }, cluster.url), clusterMetrics[cluster.name] && /* @__PURE__ */
|
|
484
|
+
} }, cluster.url), clusterMetrics[cluster.name] && /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "column", spacing: 0.25 }, /* @__PURE__ */ import_react2.default.createElement(MetricBar, { label: "CPU", value: clusterMetrics[cluster.name].cpu }), /* @__PURE__ */ import_react2.default.createElement(MetricBar, { label: "MEM", value: clusterMetrics[cluster.name].memory }), /* @__PURE__ */ import_react2.default.createElement(MetricBar, { label: "POD", value: clusterMetrics[cluster.name].maxPods > 0 ? clusterMetrics[cluster.name].pods / clusterMetrics[cluster.name].maxPods * 100 : 0 }))), clusterMetrics[cluster.name] && /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 1.5, sx: { justifyContent: "center" } }, /* @__PURE__ */ import_react2.default.createElement(MiniInfoCard, { label: "vCPUs", value: clusterMetrics[cluster.name].vcpus != null ? String(clusterMetrics[cluster.name].vcpus) : "--" }), /* @__PURE__ */ import_react2.default.createElement(MiniInfoCard, { label: "RAM", value: clusterMetrics[cluster.name].totalMemoryBytes != null ? `${(clusterMetrics[cluster.name].totalMemoryBytes / 1073741824).toFixed(0)}G` : "--" }), /* @__PURE__ */ import_react2.default.createElement(MiniInfoCard, { label: "Pods", value: clusterMetrics[cluster.name].pods ? String(clusterMetrics[cluster.name].pods) : "--" }), /* @__PURE__ */ import_react2.default.createElement(MiniInfoCard, { label: "Nodes", value: cluster.clusterInfo?.nodes?.length != null ? String(cluster.clusterInfo.nodes.length) : "--" })), /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "column", spacing: 0.75 }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 0.5, alignItems: "center" }, (cluster.kwirthData?.channels ?? []).map((ch) => {
|
|
392
485
|
const channelClass = props.frontChannels.get(ch.id);
|
|
393
486
|
if (!channelClass) return null;
|
|
394
487
|
const icon = new channelClass().getChannelIcon();
|
|
395
|
-
return /* @__PURE__ */
|
|
396
|
-
})), /* @__PURE__ */
|
|
397
|
-
|
|
488
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Tooltip, { key: ch.id, title: ch.id }, import_react2.default.cloneElement(icon, { fontSize: "small", sx: { color: MATRIX_GREEN2, opacity: 0.6 } }));
|
|
489
|
+
})), /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 1, justifyContent: "flex-start" }, /* @__PURE__ */ import_react2.default.createElement(
|
|
490
|
+
import_material2.Button,
|
|
398
491
|
{
|
|
399
492
|
variant: "outlined",
|
|
400
493
|
size: "small",
|
|
@@ -404,8 +497,8 @@
|
|
|
404
497
|
sx: matrixButtonSx
|
|
405
498
|
},
|
|
406
499
|
"Topology"
|
|
407
|
-
), /* @__PURE__ */
|
|
408
|
-
|
|
500
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
|
501
|
+
import_material2.Button,
|
|
409
502
|
{
|
|
410
503
|
variant: "outlined",
|
|
411
504
|
size: "small",
|
|
@@ -415,14 +508,16 @@
|
|
|
415
508
|
sx: matrixButtonSx
|
|
416
509
|
},
|
|
417
510
|
"Magnify"
|
|
418
|
-
)))), /* @__PURE__ */
|
|
419
|
-
}), props.clusters.length === 0 && /* @__PURE__ */
|
|
511
|
+
)))), /* @__PURE__ */ import_react2.default.createElement(EventLog, { events: clusterEvents[cluster.name] ?? [] })));
|
|
512
|
+
}), props.clusters.length === 0 && /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { sx: { fontFamily: "monospace", color: MATRIX_GREEN2, p: 2, textShadow: `0 0 8px ${MATRIX_GREEN2}` } }, "// Entering the matrix...")), showSetup && /* @__PURE__ */ import_react2.default.createElement(MatrixSetup, { config: localConfig, onSave: saveConfig, onClose: () => setShowSetup(false) }));
|
|
420
513
|
};
|
|
421
514
|
|
|
422
515
|
// src/front/index.ts
|
|
423
516
|
window.__kwirth_homepages__["matrix"] = {
|
|
424
517
|
homepageId: "matrix",
|
|
425
518
|
displayName: "Matrix",
|
|
426
|
-
Component: Matrix
|
|
519
|
+
Component: Matrix,
|
|
520
|
+
SetupDialog: MatrixSetup,
|
|
521
|
+
defaultConfig: { showQuickAccess: true, showRain: true, rainSpeed: 12, rainActiveLines: 50 }
|
|
427
522
|
};
|
|
428
523
|
})();
|