Skip to content

Commit 78f137b

Browse files
committed
feat: release version 4.0.1 with UI fixes and conversion tests
1 parent 9c6bc10 commit 78f137b

12 files changed

Lines changed: 175 additions & 76 deletions

File tree

Bitacora.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ Todos los cambios notables en este proyecto serán documentados en este archivo.
55
El formato está basado en [Keep a Changelog](https://keepachangelog.com/es-ES/1.0.0/),
66
y este proyecto adhiere a [Semantic Versioning](https://semver.org/lang/es/).
77

8+
## [4.0.1] - 2026-05-21
9+
10+
### Añadido ✨
11+
12+
-**Suite de Tests de Conversión**: Creado `tests/converters.test.js` para probar la lógica de `src/core/convert.js`.
13+
-**Soporte de Refresh de IP**: Vinculado el botón de actualización `#refresh-ip` en el widget de IP pública para re-consultar la dirección IP.
14+
15+
### Corregido 🐛
16+
17+
- 🐛 **Navegación y Estructura HTML (`index.html`)**: Se restableció el contenedor `<div id="view-vlsm">` que rodea la calculadora VLSM y el widget de IP, corrigiendo el error donde la calculadora se mostraba de manera persistente al navegar hacia otras herramientas.
18+
- 🐛 **Widget de IP en Arranque (`main.js`)**: Se modificó la inicialización para importar e iniciar el widget de IP pública en segundo plano sin alterar la vista activa inicial.
19+
- 🐛 **Widgets de Herramientas (`bandwidth.js`, `base-converter.js`, `ip_reference.js`)**: Corregidos para renderizar e inicializar su HTML de manera dinámica dentro del contenedor que les provee el gestor de vistas, resolviendo fallos donde las herramientas se cargaban vacías por buscar elementos estáticos ausentes.
20+
- 🐛 **Manifest de Agentes (`docs/agent.md`)**: Corregidas las referencias obsoletas a rutas antiguas de archivos (`src/js/`) remanentes de la refactorización v4.0.0.
21+
822
## [4.0.0] - 2026-02-25
923

1024
### Refactorización: "Lean Architecture" 💎

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# 🛡️ NetOps Toolkit v4.0.0 — Lean Architecture Edition
1+
# 🛡️ NetOps Toolkit v4.0.1 — Lean Architecture Edition
22

33
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44
[![Status](https://img.shields.io/badge/Status-Stable-green)](https://github.com/Medalcode/NetOpsToolkit)
55
[![Deploy](https://img.shields.io/badge/Deploy-Netlify-00C7B7)](https://netops-toolkit.netlify.app)
6-
[![Tests](https://img.shields.io/badge/Tests-32%20passing-success)](https://github.com/Medalcode/NetOpsToolkit)
6+
[![Tests](https://img.shields.io/badge/Tests-34%20passing-success)](https://github.com/Medalcode/NetOpsToolkit)
77
[![CI](https://github.com/Medalcode/NetOpsToolkit/actions/workflows/ci.yml/badge.svg)](https://github.com/Medalcode/NetOpsToolkit/actions)
88

99
> **"La Navaja Suiza para Ingenieros de Red"**
@@ -20,7 +20,7 @@
2020
-**PWA Ready** - Instalable como aplicación
2121
-**Internationalization** - Soporte nativo Español 🇪🇸 / Inglés 🇺🇸
2222
-**Secure** - CSP headers, XSS prevention
23-
-**Tested** - 32 tests unitarios pasando (Validators + VLSM Logic)
23+
-**Tested** - 34 tests unitarios pasando (Validators + VLSM Logic + Converters + DNS Core)
2424
-**Open Source** - MIT License
2525

2626
## 🎯 Herramientas Disponibles
@@ -112,7 +112,12 @@ npm run test:watch
112112
npm run test:coverage
113113
```
114114

115-
**Estado actual**: 3 test suites, 32 tests pasando (añadidos tests para `dns-core` el 2026-01-27)
115+
**Estado actual**: 4 test suites, 34 tests pasando (añadidos tests de conversión el 2026-05-21)
116+
117+
### Cambios Recientes (v4.0.1 - 2026-05-21)
118+
- **Widgets de UI Auto-Contenidos**: Corregidos fallos de carga en `bandwidth.js`, `base-converter.js`, y `ip_reference.js` que impedían su renderizado al buscar elementos estáticos ausentes.
119+
- **Estructura e HTML de Navegación**: Corregido el bug de visibilidad persistente de la calculadora al restablecer el contenedor `#view-vlsm`.
120+
- **Testing**: Añadido soporte de pruebas unitarias para el módulo de conversiones `src/core/convert.js` (34 tests pasando en total).
116121

117122
### Cambios Recientes (v4.0.0 - 2026-05-17)
118123
- **3 herramientas rescatadas**: Base Converter, Bandwidth Calculator e IP Reference estaban huérfanas (registradas en JS pero sin HTML). Se inyecta su HTML al contenedor dinámicamente.

docs/agent.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ descubrir, validar e invocar las capacidades (`skills`) del proyecto.
1818

1919
## Arquitectura (resumen)
2020

21-
- Frontend SPA construido con Vite, Tailwind y módulos ES (entry: `src/js/main.js`).
22-
- Herramientas organizadas en `src/js/tools/` y wrappers de plataforma en `src/js/platform/`.
21+
- Frontend SPA construido con Vite, Tailwind y módulos ES (entry: `src/ui/main.js`).
22+
- Herramientas organizadas en `src/ui/components/` y wrappers de plataforma en `src/platform/`.
2323
- Serverless: Netlify Functions en `netlify/functions/` (ej. `geo-ip.js`).
2424
- Tests: Jest (`tests/`).
2525

@@ -34,7 +34,7 @@ implementación adecuada (módulo lazy-loaded o función serverless).
3434
1) Invocar skill en cliente (módulo JS):
3535

3636
```js
37-
import('./src/js/tools/ip-lookup.js').then(({run})=>{
37+
import('./src/ui/components/public_ip.js').then(({run})=>{
3838
return run({clientIp: '1.2.3.4'})
3939
})
4040
```
@@ -65,7 +65,7 @@ Response esperado (estándar):
6565
## Observabilidad y errores
6666

6767
- Integrar Sentry/Roweball para errores client-side si se decide.
68-
- Enviar métricas vitales y eventos de uso desde `src/js/analytics.js`.
68+
- Enviar métricas vitales y eventos de uso desde `src/ui/shared/analytics.js`.
6969

7070
## Seguridad
7171

@@ -81,5 +81,5 @@ Response esperado (estándar):
8181

8282
## Onboarding para contributors
8383

84-
- Añadir nueva herramienta: crear module en `src/js/tools/`, tests en `tests/`, y entry en `docs/skills.md`.
84+
- Añadir nueva herramienta: crear module en `src/ui/components/`, tests en `tests/`, y entry en `docs/skills.md`.
8585
- Seguir Conv. Commits y abrir PR con descripción y screenshots si aplica.

index.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ <h3 class="text-xl font-bold text-white uppercase tracking-wider" id="dynamic-to
220220
<!-- Tool logic will inject content here -->
221221
</div>
222222
</div>
223-
223+
224+
<div id="view-vlsm" class="grid grid-cols-12 gap-6">
224225
<!-- Public IP Widget -->
225226
<div class="col-span-12 lg:col-span-4 flex flex-col gap-4">
226227
<div class="bg-surface-dark cyber-border rounded p-4 terminal-glow flex flex-col h-full min-h-[220px]">
@@ -311,7 +312,7 @@ <h3 class="text-xs font-bold tracking-[0.2em] uppercase text-white" data-i18n="v
311312
<div class="flex items-center gap-4">
312313
<div class="flex items-center gap-1.5">
313314
<div class="size-2 bg-signal-green rounded-full animate-pulse"></div>
314-
<span class="text-[10px] text-slate-500 uppercase font-bold tracking-tighter" data-i18n="footer.ready">System Ready — v3.0.0-cyber</span>
315+
<span class="text-[10px] text-slate-500 uppercase font-bold tracking-tighter" data-i18n="footer.ready">System Ready — v4.0.1-cyber</span>
315316
</div>
316317
</div>
317318
<div class="flex items-center gap-4 mono-data text-[10px] text-slate-500">

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "netops-toolkit",
33
"private": true,
4-
"version": "3.0.1",
4+
"version": "4.0.1",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src/ui/components/bandwidth.js

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,56 @@
11
export function initBandwidthTool(container) {
2+
if (!container) return;
3+
24
container.innerHTML = `
3-
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
4-
<div class="space-y-4">
5-
<div>
6-
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">File Size</label>
7-
<div class="flex gap-2">
8-
<input id="bw-size" type="number" placeholder="100" class="flex-1 bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white placeholder-slate-700 focus:border-primary transition-colors">
9-
<select id="bw-size-unit" class="bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white cursor-pointer">
10-
<option value="1">Bytes</option>
11-
<option value="1024" selected>KB</option>
12-
<option value="1048576">MB</option>
13-
<option value="1073741824">GB</option>
14-
</select>
15-
</div>
16-
</div>
17-
<div>
18-
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Transfer Speed</label>
19-
<div class="flex gap-2">
20-
<input id="bw-speed" type="number" placeholder="50" class="flex-1 bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white placeholder-slate-700 focus:border-primary transition-colors">
21-
<select id="bw-speed-unit" class="bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white cursor-pointer">
22-
<option value="1">bps</option>
23-
<option value="1000">Kbps</option>
24-
<option value="1000000" selected>Mbps</option>
25-
<option value="1000000000">Gbps</option>
26-
</select>
27-
</div>
5+
<div class="max-w-xl mx-auto space-y-6">
6+
<div class="bg-surface-dark cyber-border rounded p-6">
7+
<h4 class="text-xs font-bold text-slate-500 uppercase tracking-widest mb-4">Bandwidth Calculator</h4>
8+
<div class="space-y-4">
9+
<div class="grid grid-cols-3 gap-2">
10+
<div class="col-span-2">
11+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">File Size</label>
12+
<input id="bw-size" type="number" step="any" placeholder="100" class="w-full bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white focus:border-primary transition-colors">
13+
</div>
14+
<div>
15+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Unit</label>
16+
<select id="bw-size-unit" class="w-full bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white cursor-pointer focus:border-primary transition-colors">
17+
<option value="KB">KB</option>
18+
<option value="MB" selected>MB</option>
19+
<option value="GB">GB</option>
20+
<option value="TB">TB</option>
21+
</select>
22+
</div>
23+
</div>
24+
<div class="grid grid-cols-3 gap-2">
25+
<div class="col-span-2">
26+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Network Speed</label>
27+
<input id="bw-speed" type="number" step="any" placeholder="10" class="w-full bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white focus:border-primary transition-colors">
28+
</div>
29+
<div>
30+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Unit</label>
31+
<select id="bw-speed-unit" class="w-full bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white cursor-pointer focus:border-primary transition-colors">
32+
<option value="Kbps">Kbps</option>
33+
<option value="Mbps" selected>Mbps</option>
34+
<option value="Gbps">Gbps</option>
35+
</select>
36+
</div>
37+
</div>
38+
<button id="btn-bw-calc" class="w-full bg-primary hover:bg-primary/80 text-white text-xs font-bold uppercase tracking-widest py-3 rounded transition-colors shadow-lg shadow-primary/20 mt-2">
39+
Calculate Time
40+
</button>
41+
</div>
2842
</div>
29-
<button id="btn-bw-calc" class="bg-primary hover:bg-primary/80 text-white text-xs font-bold uppercase tracking-widest px-4 py-2 rounded transition-colors">Calculate</button>
30-
</div>
31-
<div id="bw-results" class="bg-surface-dark cyber-border rounded p-4 text-slate-400 text-sm">
32-
Enter a file size and speed to calculate transfer time.
33-
</div>
43+
44+
<div id="bw-results"></div>
3445
</div>
3546
`;
3647

37-
const sizeInput = document.getElementById("bw-size");
38-
const sizeUnit = document.getElementById("bw-size-unit");
39-
const speedInput = document.getElementById("bw-speed");
40-
const speedUnit = document.getElementById("bw-speed-unit");
41-
const btnCalc = document.getElementById("btn-bw-calc");
42-
const resultContainer = document.getElementById("bw-results");
48+
const sizeInput = container.querySelector("#bw-size");
49+
const sizeUnit = container.querySelector("#bw-size-unit");
50+
const speedInput = container.querySelector("#bw-speed");
51+
const speedUnit = container.querySelector("#bw-speed-unit");
52+
const btnCalc = container.querySelector("#btn-bw-calc");
53+
const resultContainer = container.querySelector("#bw-results");
4354

4455
if (!sizeInput || !resultContainer) return;
4556

src/ui/components/base-converter.js

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,47 @@
44
*/
55

66
export function initConverter(container) {
7+
if (!container) return;
8+
79
container.innerHTML = `
8-
<div class="space-y-4">
9-
<div>
10-
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Enter a number (with or without prefix):</label>
11-
<input id="converter-input" type="text" placeholder="e.g. 255, 0xFF, 0b11111111" class="w-full bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white placeholder-slate-700 focus:border-primary transition-colors">
12-
</div>
13-
<div class="grid grid-cols-3 gap-4">
14-
<div class="bg-surface-dark cyber-border rounded p-4">
15-
<div class="text-[10px] text-slate-500 uppercase font-bold mb-1">Decimal</div>
16-
<div id="res-dec" class="text-2xl font-bold text-white mono-data">—</div>
17-
</div>
18-
<div class="bg-surface-dark cyber-border rounded p-4">
19-
<div class="text-[10px] text-slate-500 uppercase font-bold mb-1">Binary</div>
20-
<div id="res-bin" class="text-2xl font-bold text-white mono-data break-all">—</div>
10+
<div class="max-w-xl mx-auto space-y-6">
11+
<div class="bg-surface-dark cyber-border rounded p-6">
12+
<h4 class="text-xs font-bold text-slate-500 uppercase tracking-widest mb-4">Hex / Dec / Bin Converter</h4>
13+
<div class="space-y-4">
14+
<div>
15+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Input Value</label>
16+
<input id="converter-input" type="text" placeholder="e.g. 255, 0xFF, or 0b11111111" class="w-full bg-black border border-border-dark rounded px-3 py-2 text-sm mono-data text-white focus:border-primary transition-colors">
17+
<span class="text-[9px] text-slate-500 mt-1 block">Supports decimal, hexadecimal (0x prefix), or binary (0b prefix)</span>
18+
</div>
19+
</div>
2120
</div>
22-
<div class="bg-surface-dark cyber-border rounded p-4">
23-
<div class="text-[10px] text-slate-500 uppercase font-bold mb-1">Hexadecimal</div>
24-
<div id="res-hex" class="text-2xl font-bold text-white mono-data">—</div>
21+
22+
<div class="bg-surface-dark cyber-border rounded p-6 space-y-4">
23+
<h4 class="text-xs font-bold text-slate-500 uppercase tracking-widest mb-2 border-b border-border-dark pb-2">Results</h4>
24+
<div class="grid grid-cols-1 gap-4">
25+
<div>
26+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Decimal</label>
27+
<input id="res-dec" type="text" readonly class="w-full bg-slate-900 border border-border-dark rounded px-3 py-2 text-sm mono-data text-white">
28+
</div>
29+
<div>
30+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Binary</label>
31+
<input id="res-bin" type="text" readonly class="w-full bg-slate-900 border border-border-dark rounded px-3 py-2 text-sm mono-data text-white">
32+
</div>
33+
<div>
34+
<label class="block text-[10px] font-bold text-slate-500 uppercase mb-1">Hexadecimal</label>
35+
<input id="res-hex" type="text" readonly class="w-full bg-slate-900 border border-border-dark rounded px-3 py-2 text-sm mono-data text-white">
36+
</div>
37+
</div>
2538
</div>
26-
</div>
2739
</div>
2840
`;
2941

30-
const input = document.getElementById("converter-input");
31-
if (!input) return;
42+
const input = container.querySelector("#converter-input");
43+
const resDec = container.querySelector("#res-dec");
44+
const resBin = container.querySelector("#res-bin");
45+
const resHex = container.querySelector("#res-hex");
3246

33-
const resDec = document.getElementById("res-dec");
34-
const resBin = document.getElementById("res-bin");
35-
const resHex = document.getElementById("res-hex");
47+
if (!input) return;
3648

3749
input.addEventListener("input", () => {
3850
const rawVal = input.value.trim();

src/ui/components/ip_reference.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export function initIpRefTool(container) {
2+
if (!container) return;
23
container.innerHTML = '<div id="ip-ref-content"></div>';
3-
const content = document.getElementById("ip-ref-content");
4+
const content = container.querySelector("#ip-ref-content");
45
if (!content) return;
56

67
// Function to generate HTML for a table

src/ui/components/public_ip.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ export function initPublicIpWidget() {
3838
`;
3939
}
4040

41+
// Wire refresh button if it exists
42+
const refreshBtn = document.getElementById("refresh-ip");
43+
if (refreshBtn) {
44+
refreshBtn.addEventListener("click", fetchIp);
45+
}
46+
4147
// Initial load
4248
fetchIp();
4349
}

src/ui/main.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ async function init() {
9191
console.log("✅ VLSM Core Logic");
9292

9393
// 6. Initialize Public IP Widget (Always on dashboard)
94-
loadToolLogic("tool-public-ip");
94+
import("./components/public_ip.js").then(module => {
95+
module.initPublicIpWidget();
96+
});
9597

9698
console.log("🏁 Initialization Complete");
9799
} catch (e) {

0 commit comments

Comments
 (0)