311 lines
15 KiB
HTML
311 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="es">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Dashboard LABS — Story Points</title>
|
||
<link rel="stylesheet" href="./css/styles.css">
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script>
|
||
<script type="module" src="./js/app.js" defer></script>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- Loading overlay -->
|
||
<div class="loading-overlay" id="loadingOverlay">
|
||
<div class="spinner"></div>
|
||
<p>Consultando Jira en tiempo real…</p>
|
||
</div>
|
||
|
||
<!-- Error banner -->
|
||
<div class="error-banner" id="errorBanner"></div>
|
||
<div class="error-banner" id="limitBanner" style="background:#fff7d6; color:#a15900; border-color:#ffab00;"></div>
|
||
|
||
<!-- Header Principal -->
|
||
<header>
|
||
<div>
|
||
<h1>📊 Dashboard LABS — Story Points</h1>
|
||
<div style="font-size:13px;opacity:.7;margin-top:4px;">
|
||
Proyecto: <strong>LABS</strong> · invera.atlassian.net
|
||
</div>
|
||
</div>
|
||
<div class="header-meta">
|
||
<span id="lastUpdatedLabel">—</span>
|
||
<span class="cache-badge" id="cacheBadge"></span>
|
||
<label style="font-size:12px;opacity:0.8;color:white;margin-right:-6px;">Rango:</label>
|
||
<select id="timeRangeFilter" style="padding:4px 8px; font-size:12px; border-radius:4px; max-width:120px;">
|
||
<option value="1d">Hoy</option>
|
||
<option value="7d">Últimos 7 días</option>
|
||
<option value="30d">Último mes</option>
|
||
<option value="90d" selected>Últimos 3 meses</option>
|
||
<option value="365d">Último año</option>
|
||
<option value="all">Histórico completo</option>
|
||
</select>
|
||
<button class="refresh-btn" id="refreshBtn">↻ Actualizar</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ── SECCIÓN 1: Carga de Trabajo (Pendientes) ── -->
|
||
<div class="section-header current">
|
||
<div class="dot" style="background:#0065ff;"></div>
|
||
<h2>Carga de Trabajo Actual</h2>
|
||
<span id="currentTicketsLabel" style="font-size:12px;color:#5e6c84;margin-left:8px;">Tickets pendientes en el tablero</span>
|
||
|
||
<div class="filter-group">
|
||
<label>Filtrar por Dev:</label>
|
||
<select id="devFilter"><option value="all">Cargando...</option></select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="main">
|
||
<div class="section-block">
|
||
<div class="kpi-row">
|
||
<div class="kpi progress" title="Suma de Story Points (SP) de todos los tickets actualmente en la columna En Progreso"><div class="kpi-value" id="kpi-ip">—</div><div class="kpi-label">SP En Progreso</div><div class="kpi-sub">Trabajo en curso</div></div>
|
||
<div class="kpi todo" title="Suma de Story Points de tickets pendientes que aún no comenzaron"><div class="kpi-value" id="kpi-todo">—</div><div class="kpi-label">SP Por Hacer</div><div class="kpi-sub">Backlog del periodo</div></div>
|
||
<div class="kpi members" title="Cantidad de personas con carga de trabajo (tickets) asignados en este momento"><div class="kpi-value" id="kpi-members">—</div><div class="kpi-label">Devs con Carga</div><div class="kpi-sub">Con tickets pendientes</div></div>
|
||
</div>
|
||
|
||
<div class="charts-grid">
|
||
<div class="chart-card">
|
||
<h3>🔵 Pendientes por Desarrollador</h3>
|
||
<div class="sub">Story Points con trabajo pendiente</div>
|
||
<div style="position:relative;height:260px"><canvas id="chartCurrentState"></canvas></div>
|
||
</div>
|
||
<div class="chart-card">
|
||
<h3>📢 Alertas de Salud</h3>
|
||
<div class="sub">Tickets estancados o sin estimación</div>
|
||
<div id="warningsSection" style="display:none; overflow-y:auto; max-height:230px; margin-top:10px;">
|
||
<ul class="warning-list" id="warningsList" style="padding:0; margin:0;"></ul>
|
||
</div>
|
||
<div id="noWarningsMsg" style="text-align:center; color:#36b37e; padding:40px 0; display:none;">
|
||
✅ No hay alertas pendientes
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-card">
|
||
<h3>Detalle de Carga de Trabajo</h3>
|
||
<table>
|
||
<thead><tr><th>Desarrollador</th><th>🔵 En Progreso</th><th>⏳ Por Hacer</th><th>Total Pendiente</th><th>Carga Visual</th></tr></thead>
|
||
<tbody id="tableCurrentState"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── SECCIÓN 2: Rendimiento & Resultados ── -->
|
||
<div class="section-header history">
|
||
<div class="dot" style="background:#36b37e;"></div>
|
||
<h2>Resultados del Período</h2>
|
||
<span style="font-size:12px;color:#5e6c84;margin-left:8px;">Story Points finalizados y velocidad</span>
|
||
<span class="badge" id="filterBadge" style="display:none;"></span>
|
||
</div>
|
||
|
||
<div class="main">
|
||
<div class="section-block">
|
||
<div class="kpi-row-3">
|
||
<div class="kpi done" title="Suma total de Story Points entregados y completados en el período de tiempo seleccionado"><div class="kpi-value" id="kpi-done-period">—</div><div class="kpi-label">SP Completados</div><div class="kpi-sub">en el período</div></div>
|
||
<div class="kpi members" title="Cantidad de desarrolladores que han cerrado al menos 1 Story Point en este período"><div class="kpi-value" id="kpi-devs-period">—</div><div class="kpi-label">Desarrolladores</div><div class="kpi-sub">que completaron SP</div></div>
|
||
<div class="kpi progress" title="Promedio simple: Total de SP completados dividido por la cantidad de desarrolladores"><div class="kpi-value" id="kpi-avg-period">—</div><div class="kpi-label">SP promedio / dev</div><div class="kpi-sub">en el período</div></div>
|
||
</div>
|
||
<div class="kpi-row-3" style="margin-top:-8px;">
|
||
<div class="kpi" style="border-color:#36b37e;" title="Lead Time: Tiempo total promedio que vive un ticket desde su creación hasta que es cerrado"><div class="kpi-value" id="kpi-lead-time">—</div><div class="kpi-label">Promedio Lead Time</div><div class="kpi-sub">Días (Creación a Fin)</div></div>
|
||
<div class="kpi" style="border-color:#00b8d9;" title="Cycle Time: Velocidad de desarrollo neto. Promedio en días desde que un developer mueve el ticket 'En Curso' hasta cerrarse"><div class="kpi-value" id="kpi-cycle-time">—</div><div class="kpi-label">Promedio Cycle Time</div><div class="kpi-sub">Días (En Curso a Fin)</div></div>
|
||
<div class="kpi warning" title="Variación entre el Story Point estimado al sprint vs el final real; un número en (+) indica Scope Creep (inflación de puntos)"><div class="kpi-value" id="kpi-sp-deviation">—</div><div class="kpi-label">Desviación SP</div><div class="kpi-sub" id="kpi-sp-deviation-sub">Original vs Final</div></div>
|
||
</div>
|
||
|
||
<div class="charts-grid">
|
||
<div class="chart-card">
|
||
<h3>✅ SP Completados — por Desarrollador</h3>
|
||
<div class="sub">Período seleccionado</div>
|
||
<div style="position:relative;height:260px"><canvas id="chartDoneDev"></canvas></div>
|
||
</div>
|
||
<div class="chart-card">
|
||
<h3>📈 Velocidad Histórica</h3>
|
||
<div class="sub">SP completados mes a mes</div>
|
||
<div style="position:relative;height:260px"><canvas id="chartVelocity"></canvas></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-card">
|
||
<h3>SP Completados — Tabla Resumen</h3>
|
||
<table>
|
||
<thead><tr><th>Desarrollador</th><th>✅ SP Completados</th><th>🎟️ Tickets</th><th>% del impacto total</th></tr></thead>
|
||
<tbody id="tableHistory"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<!-- ── SECCIÓN: Revisión de Código (Code Review) ── -->
|
||
<div class="section-header" style="border-color:#00b8d9;">
|
||
<div class="dot" style="background:#00b8d9;"></div>
|
||
<h2>Revisión de Código (Code Review)</h2>
|
||
<span style="font-size:12px;color:#5e6c84;margin-left:8px;">Métricas de revisión entre pares antes de QA</span>
|
||
</div>
|
||
|
||
<div class="main">
|
||
<div class="section-block">
|
||
<!-- Colas Actuales -->
|
||
<div class="kpi-row" style="margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #dfe1e6;">
|
||
<div class="kpi warning" style="border-color:#ff8b00;" title="Tickets que se encuentran en este preciso instante en la columna Code Review esperando o siendo revisados">
|
||
<div class="kpi-value" id="kpi-cr-queue-now">—</div>
|
||
<div class="kpi-label">En Cola Actual CR</div>
|
||
<div class="kpi-sub" id="kpi-cr-queue-sp">— SP en espera</div>
|
||
</div>
|
||
<div class="kpi warning" title="Tickets que se encuentran actualmente y desde hace más de 2 días atascados solos en la columna de revisión">
|
||
<div class="kpi-value" id="kpi-cr-stalled">—</div>
|
||
<div class="kpi-label">Tickets Atascados CR</div>
|
||
<div class="kpi-sub">Demorados actualmente (más de 2 días)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Historial del período -->
|
||
<h3 style="font-size:14px; margin-bottom:12px; color:#172b4d;">Métricas del período seleccionado</h3>
|
||
<div class="kpi-row">
|
||
<div class="kpi" style="border-color:#00b8d9;" title="Cantidad de tickets que registraron actividad en la fase de Code Review">
|
||
<div class="kpi-value" id="kpi-cr-tickets">—</div>
|
||
<div class="kpi-label">Tickets en CR</div>
|
||
<div class="kpi-sub">Procesados en el período</div>
|
||
</div>
|
||
<div class="kpi" style="border-color:#00b8d9;">
|
||
<div class="kpi-value" id="kpi-cr-p50">—</div>
|
||
<div class="kpi-label">
|
||
<div class="pop-trigger" style="border-bottom: 1px dotted #5e6c84;">Tiempo P50 CR
|
||
<div class="pop-content" style="text-transform:none; font-weight:normal; letter-spacing:normal; text-align:left;">
|
||
<div class="pop-item" style="font-size:12px;"><strong>Percentil 50 (Mediana)</strong><br>El 50% de las revisiones de código se completan en esta cantidad de horas o menos.<br><br>A diferencia del promedio tradicional, el P50 muestra un valor "habitual" sin ser distorsionado por tickets que queden atascados durante meses.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="kpi-sub">Horas (Mediana)</div>
|
||
</div>
|
||
<div class="kpi" style="border-color:#ff8b00;">
|
||
<div class="kpi-value" id="kpi-cr-p90">—</div>
|
||
<div class="kpi-label">
|
||
<div class="pop-trigger" style="border-bottom: 1px dotted #5e6c84;">Tiempos P90 y P99
|
||
<div class="pop-content" style="text-transform:none; font-weight:normal; letter-spacing:normal; text-align:left;">
|
||
<div class="pop-item" style="font-size:12px;"><strong>Métricas de Cuello de Botella</strong><br>Muestran los "peores escenarios" posibles.<br><br><strong>P90:</strong> El 90% de los tickets logra pasar en este tiempo. El 10% restante demoró aún más.<br><strong>P99:</strong> El 99% pasa en este tiempo. Ideal para medir los bloqueos máximos.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="kpi-sub" id="kpi-cr-p99-sub">P99: — hs</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="charts-grid">
|
||
<div class="chart-card full">
|
||
<h3>📈 Tiempo Promedio en Code Review — Mes a Mes</h3>
|
||
<div class="sub">Evolución de la velocidad de revisión de pares (horas)</div>
|
||
<div style="position:relative;height:240px"><canvas id="chartCrMonthly"></canvas></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<!-- ── SECCIÓN 3: Control de Calidad (QA) ── -->
|
||
<div class="section-header qa">
|
||
<div class="dot qa"></div>
|
||
<h2>Control de Calidad (QA)</h2>
|
||
<span style="font-size:12px;color:#5e6c84;margin-left:8px;">Métricas del proceso de QA · Tiempos, colas y devoluciones</span>
|
||
</div>
|
||
|
||
<div class="main">
|
||
<div class="section-block">
|
||
|
||
<!-- Colas Actuales -->
|
||
<div class="kpi-row" style="margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #dfe1e6;">
|
||
<div class="kpi qa-queue" style="border-color:#ff8b00;" title="Tickets que se encuentran en este preciso instante en la columna Ready to QA">
|
||
<div class="kpi-value" id="kpi-qa-queue-now">—</div>
|
||
<div class="kpi-label">En Cola Actual RTQA</div>
|
||
<div class="kpi-sub" id="kpi-qa-queue-now-sp">— SP esperando</div>
|
||
</div>
|
||
<div class="kpi qa" style="border-color:#0065ff;" title="Tickets que se encuentran en este preciso instante siendo probados en la columna QA">
|
||
<div class="kpi-value" id="kpi-qa-active-now">—</div>
|
||
<div class="kpi-label">En Cola Actual QA</div>
|
||
<div class="kpi-sub" id="kpi-qa-active-now-sp">— SP en prueba</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- KPIs del período -->
|
||
<h3 style="font-size:14px; margin-bottom:12px; color:#172b4d;">Métricas del período seleccionado</h3>
|
||
<div class="kpi-row">
|
||
<div class="kpi qa" title="Total de tickets que han pasado por QA">
|
||
<div class="kpi-value" id="kpi-qa-tickets">—</div>
|
||
<div class="kpi-label">Tickets QA</div>
|
||
<div class="kpi-sub">Procesados en el período</div>
|
||
</div>
|
||
<div class="kpi qa-time" title="Horas dedicadas a revisar un ticket (Tiempo neto en la columna QA)">
|
||
<div class="kpi-value" id="kpi-qa-avg">—</div>
|
||
<div class="kpi-label">Tiempo Prom. QA</div>
|
||
<div class="kpi-sub">Horas promedio por ticket</div>
|
||
</div>
|
||
<div class="kpi qa-queue" title="Tiempo pasivo promedio esperando ser tomado (Cola 'Ready to QA')">
|
||
<div class="kpi-value" id="kpi-qa-rtqa">—</div>
|
||
<div class="kpi-label">Tiempo Prom. en Cola</div>
|
||
<div class="kpi-sub">Horas esperando READY TO QA</div>
|
||
</div>
|
||
<div class="kpi returned" title="Tickets que rebotaron en QA y el desarrollador tuvo que retomar ('Reaperturas' o regresos al ciclo En Curso)">
|
||
<div class="kpi-value" id="kpi-qa-returned">—</div>
|
||
<div class="kpi-label">Tickets Devueltos</div>
|
||
<div class="kpi-sub" id="kpi-qa-returned-pct">Volvieron a En Curso</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Gráficos fila 1 -->
|
||
<div class="charts-grid">
|
||
<div class="chart-card">
|
||
<h3>📊 Distribución de Tiempos en QA</h3>
|
||
<div class="sub">Rangos: <30min · 30min–2hs · 2–8hs · >8hs</div>
|
||
<div style="position:relative;height:240px"><canvas id="chartQaDist"></canvas></div>
|
||
</div>
|
||
<div class="chart-card">
|
||
<h3>🔄 Devueltos vs. Aprobados</h3>
|
||
<div class="sub">Tickets que volvieron a En Curso al menos una vez</div>
|
||
<div style="position:relative;height:240px"><canvas id="chartQaReturned"></canvas></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Gráficos fila 2 -->
|
||
<div class="charts-grid">
|
||
<div class="chart-card">
|
||
<h3>📈 Tiempo Promedio en QA — Mes a Mes</h3>
|
||
<div class="sub">Evolución de la velocidad de revisión (horas)</div>
|
||
<div style="position:relative;height:240px"><canvas id="chartQaMonthly"></canvas></div>
|
||
</div>
|
||
<div class="chart-card">
|
||
<h3>⏳ Tiempo en Cola RTQA — Mes a Mes</h3>
|
||
<div class="sub">Horas promedio esperando ser tomado por QA</div>
|
||
<div style="position:relative;height:240px"><canvas id="chartRtqaMonthly"></canvas></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tabla de tickets QA -->
|
||
<div class="table-card">
|
||
<h3>🔍 Detalle de Tickets — QA</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Ticket</th>
|
||
<th>Resumen</th>
|
||
<th>⏱️ Tiempo en QA (hs)</th>
|
||
<th>⏳ Cola RTQA (hs)</th>
|
||
<th>🔄 Veces devuelto</th>
|
||
<th>Estado</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="tableQA"></tbody>
|
||
</table>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
<footer>
|
||
Dashboard en tiempo real · Arquitectura Modular Serverless · Realizado para Vercel & Jira
|
||
</footer>
|
||
|
||
</body>
|
||
</html>
|