@kwirthmagnify/kwirth-plugin-status 0.2.2 → 0.2.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 +31 -8
- package/package.json +1 -1
package/front.js
CHANGED
|
@@ -97,6 +97,10 @@
|
|
|
97
97
|
var StatusIcon = (props) => /* @__PURE__ */ import_react.default.createElement(import_material.SvgIcon, { ...props, viewBox: "0 0 24 24" }, /* @__PURE__ */ import_react.default.createElement("g", { fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("rect", { x: "2.6", y: "4.6", width: "18.8", height: "14.8", rx: "2.2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M6 12h2.6l1.5-3.4 2.6 6.8 1.5-3.4H18" })));
|
|
98
98
|
|
|
99
99
|
// src/front/StatusData.ts
|
|
100
|
+
var countUnbrokeredConsumers = (components) => components.reduce((n, c) => {
|
|
101
|
+
if (c.subscribers === void 0 || c.knownConsumers === void 0) return n;
|
|
102
|
+
return n + Math.max(0, c.subscribers - c.knownConsumers);
|
|
103
|
+
}, 0);
|
|
100
104
|
var StatusData = class {
|
|
101
105
|
constructor() {
|
|
102
106
|
this.view = "table";
|
|
@@ -168,8 +172,12 @@
|
|
|
168
172
|
return filas();
|
|
169
173
|
}
|
|
170
174
|
};
|
|
171
|
-
var
|
|
175
|
+
var VELOCIDAD_INICIAL = 20;
|
|
176
|
+
var StatusDiagram = ({ inventory, active, autoRefresh }) => {
|
|
172
177
|
const theme = (0, import_material2.useTheme)();
|
|
178
|
+
const vueltas = import_react2.default.useRef({ inventario: inventory, n: 0 });
|
|
179
|
+
if (vueltas.current.inventario !== inventory) vueltas.current = { inventario: inventory, n: vueltas.current.n + 1 };
|
|
180
|
+
const frenada = `statusFrenada${vueltas.current.n % 2}`;
|
|
173
181
|
const [posiciones, setPosiciones] = import_react2.default.useState(void 0);
|
|
174
182
|
const [seleccionado, setSeleccionado] = import_react2.default.useState(void 0);
|
|
175
183
|
const colores = {
|
|
@@ -275,17 +283,14 @@
|
|
|
275
283
|
vigente = false;
|
|
276
284
|
};
|
|
277
285
|
}, [firmaGrafo]);
|
|
286
|
+
const anonimos = countUnbrokeredConsumers(inventory.components);
|
|
278
287
|
if (inventory.edges.length === 0) {
|
|
279
|
-
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { p: 3 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "body2", color: "text.secondary" }, "Nothing is subscribed to anything right now, so there is no graph to draw."));
|
|
288
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { p: 3 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "body2", color: "text.secondary" }, anonimos > 0 ? `There is consumption right now \u2014 ${anonimos} subscriber${anonimos > 1 ? "s" : ""} \u2014 but no graph to draw: they subscribed straight to the provider instead of going through the core, so nobody knows who they are. The table still shows how much each producer is delivering.` : "Nothing is subscribed to anything right now, so there is no graph to draw."));
|
|
280
289
|
}
|
|
281
290
|
if (!posiciones) {
|
|
282
291
|
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { p: 3 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "body2", color: "text.secondary" }, "Laying out the graph\u2026"));
|
|
283
292
|
}
|
|
284
293
|
const colocados = nodos.map((n) => ({ ...n, position: posiciones[n.id] ?? { x: 0, y: 0 } }));
|
|
285
|
-
const anonimos = inventory.components.reduce((n, c) => {
|
|
286
|
-
if (c.subscribers === void 0 || c.knownConsumers === void 0) return n;
|
|
287
|
-
return n + Math.max(0, c.subscribers - c.knownConsumers);
|
|
288
|
-
}, 0);
|
|
289
294
|
return /* @__PURE__ */ import_react2.default.createElement(import_material2.Box, { sx: { height: "100%", display: "flex", flexDirection: "column", minHeight: 0 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 1, alignItems: "center", sx: { mb: 1 } }, /* @__PURE__ */ import_react2.default.createElement(import_material2.Typography, { variant: "caption", color: "text.secondary" }, "A line means ", /* @__PURE__ */ import_react2.default.createElement("b", null, "an active subscription"), ". A ", /* @__PURE__ */ import_react2.default.createElement("b", null, "moving line"), " means its producer is delivering right now \u2014 but not how much goes to each consumer: that is measured per component, not per line.", " ", "Click a node to highlight what it is connected to; click the background to clear.")), (anonimos > 0 || canalesSueltos > 0) && /* @__PURE__ */ import_react2.default.createElement(import_material2.Stack, { direction: "row", spacing: 1, sx: { mb: 1 } }, anonimos > 0 && /* @__PURE__ */ import_react2.default.createElement(
|
|
290
295
|
import_material2.Chip,
|
|
291
296
|
{
|
|
@@ -308,7 +313,25 @@
|
|
|
308
313
|
},
|
|
309
314
|
"& .react-flow__controls-button:hover": { background: theme.palette.action.hover },
|
|
310
315
|
"& .react-flow__controls-button svg": { fill: theme.palette.text.primary },
|
|
311
|
-
"& .react-flow__attribution": { display: "none" }
|
|
316
|
+
"& .react-flow__attribution": { display: "none" },
|
|
317
|
+
/*
|
|
318
|
+
Con auto-refresco, la línea viva arranca a la velocidad de serie y va FRENANDO hasta
|
|
319
|
+
pararse justo cuando llega la siguiente foto: lo que se ha visto moverse es lo que
|
|
320
|
+
pasó en ese intervalo, y la línea no sigue diciendo "ahora" cuando el dato ya es viejo.
|
|
321
|
+
En manual no hay intervalo que agotar, así que se queda la animación continua de serie.
|
|
322
|
+
|
|
323
|
+
El recorrido sale de la curva: con ease-out cuadrática la velocidad inicial es 2·D/T,
|
|
324
|
+
así que D = VELOCIDAD_INICIAL·T/2 arranca igual que la de serie, sin tirón.
|
|
325
|
+
*/
|
|
326
|
+
...autoRefresh > 0 ? {
|
|
327
|
+
[`@keyframes ${frenada}`]: {
|
|
328
|
+
from: { strokeDashoffset: VELOCIDAD_INICIAL * autoRefresh / 2 },
|
|
329
|
+
to: { strokeDashoffset: 0 }
|
|
330
|
+
},
|
|
331
|
+
"& .react-flow__edge.animated path": {
|
|
332
|
+
animation: `${frenada} ${autoRefresh}s cubic-bezier(0.5, 1, 0.89, 1) 1 forwards`
|
|
333
|
+
}
|
|
334
|
+
} : {}
|
|
312
335
|
} }, /* @__PURE__ */ import_react2.default.createElement(
|
|
313
336
|
import_react3.ReactFlow,
|
|
314
337
|
{
|
|
@@ -479,7 +502,7 @@
|
|
|
479
502
|
/* @__PURE__ */ import_react4.default.createElement(import_material3.MenuItem, { value: 15 }, "Every 15s"),
|
|
480
503
|
/* @__PURE__ */ import_react4.default.createElement(import_material3.MenuItem, { value: 30 }, "Every 30s"),
|
|
481
504
|
/* @__PURE__ */ import_react4.default.createElement(import_material3.MenuItem, { value: 60 }, "Every minute")
|
|
482
|
-
), /* @__PURE__ */ import_react4.default.createElement(import_material3.Tooltip, { title: "Take a new snapshot" }, /* @__PURE__ */ import_react4.default.createElement(import_material3.IconButton, { size: "small", onClick: refresh }, /* @__PURE__ */ import_react4.default.createElement(import_icons.Refresh, { fontSize: "small" })))), /* @__PURE__ */ import_react4.default.createElement(import_material3.Typography, { variant: "caption", color: "text.secondary", sx: { mb: 1 } }, "Snapshot taken at ", new Date(inventory.takenAt).toLocaleTimeString(), data.autoRefresh ? ` \u2014 refreshing every ${data.autoRefresh}s while this tab is open` : " \u2014 it does not refresh on its own", ".", " ", "Delivered counts since each component started; the rate is measured against your previous snapshot."), /* @__PURE__ */ import_react4.default.createElement(import_material3.Box, { ref: boxRef, sx: { display: "flex", flexDirection: "column", overflowY: vista === "table" ? "auto" : "hidden", overflowX: "hidden", width: "100%", flexGrow: 1, height: `calc(100vh - ${boxTop}px - 35px)` } }, vista === "graph" && /* @__PURE__ */ import_react4.default.createElement(StatusDiagram, { inventory, active: activos }), vista === "table" && /* @__PURE__ */ import_react4.default.createElement(import_material3.Table, { size: "small", stickyHeader: true }, /* @__PURE__ */ import_react4.default.createElement(import_material3.TableHead, null, /* @__PURE__ */ import_react4.default.createElement(import_material3.TableRow, null, /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "Kind"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "Name"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "State"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, { align: "right" }, "Consumers"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, { align: "right" }, "Delivered"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "Why"))), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableBody, null, componentes.map(fila)))), data.signals.length > 0 && /* @__PURE__ */ import_react4.default.createElement(import_material3.Box, { sx: { mt: 1 } }, data.signals.map((s, i) => /* @__PURE__ */ import_react4.default.createElement(import_material3.Typography, { key: i, variant: "caption", color: "error", display: "block" }, s))));
|
|
505
|
+
), /* @__PURE__ */ import_react4.default.createElement(import_material3.Tooltip, { title: "Take a new snapshot" }, /* @__PURE__ */ import_react4.default.createElement(import_material3.IconButton, { size: "small", onClick: refresh }, /* @__PURE__ */ import_react4.default.createElement(import_icons.Refresh, { fontSize: "small" })))), /* @__PURE__ */ import_react4.default.createElement(import_material3.Typography, { variant: "caption", color: "text.secondary", sx: { mb: 1 } }, "Snapshot taken at ", new Date(inventory.takenAt).toLocaleTimeString(), data.autoRefresh ? ` \u2014 refreshing every ${data.autoRefresh}s while this tab is open` : " \u2014 it does not refresh on its own", ".", " ", "Delivered counts since each component started; the rate is measured against your previous snapshot."), /* @__PURE__ */ import_react4.default.createElement(import_material3.Box, { ref: boxRef, sx: { display: "flex", flexDirection: "column", overflowY: vista === "table" ? "auto" : "hidden", overflowX: "hidden", width: "100%", flexGrow: 1, height: `calc(100vh - ${boxTop}px - 35px)` } }, vista === "graph" && /* @__PURE__ */ import_react4.default.createElement(StatusDiagram, { inventory, active: activos, autoRefresh: data.autoRefresh }), vista === "table" && /* @__PURE__ */ import_react4.default.createElement(import_material3.Table, { size: "small", stickyHeader: true }, /* @__PURE__ */ import_react4.default.createElement(import_material3.TableHead, null, /* @__PURE__ */ import_react4.default.createElement(import_material3.TableRow, null, /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "Kind"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "Name"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "State"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, { align: "right" }, "Consumers"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, { align: "right" }, "Delivered"), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableCell, null, "Why"))), /* @__PURE__ */ import_react4.default.createElement(import_material3.TableBody, null, componentes.map(fila)))), data.signals.length > 0 && /* @__PURE__ */ import_react4.default.createElement(import_material3.Box, { sx: { mt: 1 } }, data.signals.map((s, i) => /* @__PURE__ */ import_react4.default.createElement(import_material3.Typography, { key: i, variant: "caption", color: "error", display: "block" }, s))));
|
|
483
506
|
};
|
|
484
507
|
|
|
485
508
|
// src/front/StatusChannel.ts
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"id": "status",
|
|
5
5
|
"name": "@kwirthmagnify/kwirth-plugin-status",
|
|
6
6
|
"displayName": "Kwirth Status",
|
|
7
|
-
"version": "0.2.
|
|
7
|
+
"version": "0.2.4",
|
|
8
8
|
"description": "A look inside Kwirth: what is installed, how it is doing and who consumes what",
|
|
9
9
|
"icon": "<svg viewBox='0 0 24 24'><g fill='none' stroke='currentColor' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><rect x='2.6' y='4.6' width='18.8' height='14.8' rx='2.2'/><path d='M6 12h2.6l1.5-3.4 2.6 6.8 1.5-3.4H18'/></g></svg>",
|
|
10
10
|
"requiresRestart": false,
|