Skip to main content

Overview

The Dashboard is the central command center of P.FLEX, providing real-time visibility into plant operations, active production orders, quality incidents, and system health metrics.

Live KPI Monitoring

Track OEE, active orders, incidents, and production volume in real-time

Operations Feed

Consolidated activity stream from production, quality, and inventory

Quick Actions

One-click access to create orders, import data, and report incidents

System Health

Monitor machine status, sync queue, and energy efficiency

Key Performance Indicators (KPIs)

The dashboard displays six primary KPIs in real-time:

OEE Global (Overall Equipment Effectiveness)

Calculated metric showing plant-wide equipment performance with trending indicators.
// Dashboard KPI Display (dashboard.component.ts:110-135)
<div class="glassmorphism-card p-4 rounded-2xl">
  <div class="flex justify-between items-start text-slate-500 mb-2">
    <span class="text-[10px] font-bold uppercase tracking-widest">OEE Global</span>
    <span class="material-symbols-outlined text-sm">memory</span>
  </div>
  <div class="flex items-end justify-between">
    <div>
      <span class="text-2xl font-bold text-white">82.4%</span>
      <div class="text-[10px] text-emerald-400 font-medium flex items-center">
        <span class="material-symbols-outlined text-sm">trending_up</span> +1.2%
      </div>
    </div>
  </div>
</div>

Active Production Orders (OTs Activas)

Shows currently running production orders with operator avatars.
// Active Production Getter (dashboard.component.ts:589-593)
get activeProduction() {
  return this.ordersService.ots
    .filter(ot => ot.Estado_pedido === 'EN PROCESO')
    .slice(0, 5);
}

Quality Incidents

Real-time count of active incidents with priority classification.
// Incidents Counter (dashboard.component.ts:595-601)
get activeIncidentsCount() {
  return this.qualityService.activeIncidents.length;
}

get highPriorityCount() {
  return this.qualityService.activeIncidents
    .filter(i => i.priority === 'Alta').length;
}
The Dashboard auto-refreshes KPIs every second using interval timers to ensure data accuracy.

Operations Feed

The live operations feed consolidates activities from multiple modules into a unified timeline.

Feed Types

Production events show active work orders with progress bars, machine assignments, and operator information.
// Production Feed Item (dashboard.component.ts:633-646)
this.ordersService.ots.forEach(ot => {
  if (ot.Estado_pedido === 'EN PROCESO') {
    items.push({
      id: ot.OT,
      type: 'PRODUCTION',
      title: `OT #${ot.OT} - Producción en Curso`,
      description: ot.descripcion,
      machine: ot.maquina,
      time: new Date(),
      displayTime: 'En curso',
      icon: 'conveyor_belt',
      data: ot
    });
  }
});

Feed Filtering

Users can filter the feed by category: All, Alerts, Production, or Stock.
// Feed Filter Logic (dashboard.component.ts:704-707)
get filteredFeed() {
  if (this.activeFeedTab === 'ALL') return this.feedItems;
  return this.feedItems.filter(i => i.type === this.activeFeedTab);
}

Quick Actions Panel

The right sidebar provides instant access to common operations.

Nueva OT

Opens the OT creation modal for manual work order entry

Importar

Launches Excel/CSV import wizard for bulk OT updates

Reportar Falla

Quick-access to quality incident reporting

Escanear

QR/Barcode scanner for material tracking
// Quick Actions UI (dashboard.component.ts:354-371)
<div class="grid grid-cols-2 gap-3">
  <button (click)="showOtFormModal = true" 
    class="flex flex-col items-center justify-center p-4">
    <span class="material-symbols-outlined text-blue-400">add_task</span>
    <span class="text-[10px] font-bold">Nueva OT</span>
  </button>
  
  <button (click)="showImportModal = true">
    <span class="material-symbols-outlined text-emerald-400">upload_file</span>
    <span class="text-[10px] font-bold">Importar</span>
  </button>
  
  <button (click)="router.navigate(['/incidents'])">
    <span class="material-symbols-outlined text-red-400">report_problem</span>
    <span class="text-[10px] font-bold">Falla</span>
  </button>
</div>

Machine Status Monitoring

Real-time workstation status is displayed in the sidebar with color-coded indicators.
// Workstation Status (dashboard.component.ts:618-626)
get workstationStatus() {
  return [
    { name: 'Flexo-03', status: 'Carga 100%', color: 'bg-green-500' },
    { name: 'Offset-02', status: 'Inactivo (Rep)', color: 'bg-amber-500' },
    { name: 'Digital-V2', status: 'Carga 45%', color: 'bg-green-500' },
    { name: 'Troquel-01', status: 'Operando', color: 'bg-green-500' },
    { name: 'Rebob-04', status: 'Desconectado', color: 'bg-slate-500' }
  ];
}
Machine status is updated in real-time via WebSocket connections. Offline machines show “Desconectado” status.

Data Export

The dashboard supports exporting comprehensive reports in multiple formats.

PDF Export (Visual Report)

Generates a visual snapshot of the entire dashboard using html2canvas and jsPDF.
// PDF Export Function (dashboard.component.ts:491-531)
async exportToPdf() {
  this.showExportMenu = false;
  const element = this.dashboardContent.nativeElement;
  
  try {
    const canvas = await html2canvas(element, {
      scale: 2,
      backgroundColor: '#0B0E14',
      logging: false,
      useCORS: true
    });

    const imgData = canvas.toDataURL('image/png');
    const pdf = new jsPDF('l', 'mm', 'a4');
    
    const imgWidth = 297;
    const imgHeight = (canvas.height * imgWidth) / canvas.width;
    
    pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
    
    const dateStr = new Date().toISOString().slice(0, 10);
    pdf.save(`Dashboard_Report_${dateStr}.pdf`);
    
    this.audit.log(this.state.userName(), this.state.userRole(), 
      'DASHBOARD', 'Export PDF', 'Exportación visual del tablero completada.');
  } catch (err) {
    console.error('PDF Export Error', err);
  }
}

Excel Export (Data Report)

Exports structured data including KPIs, active OTs, and activity feed to Excel using xlsx.
// Excel Export Function (dashboard.component.ts:533-581)
exportToExcel() {
  const wb = XLSX.utils.book_new();
  const dateStr = new Date().toISOString().split('T')[0];

  // Sheet 1: General Stats
  const statsData = [
    ['REPORTE GENERAL DE PLANTA', dateStr],
    [''],
    ['METRICAS PRINCIPALES'],
    ['OEE Global', '82.4%'],
    ['OTs Activas', this.activeProduction.length],
    ['Metros Totales (Volumen)', '45.2k'],
    ['Incidencias Activas', this.activeIncidentsCount]
  ];
  const wsStats = XLSX.utils.aoa_to_sheet(statsData);
  XLSX.utils.book_append_sheet(wb, wsStats, "KPIs");

  // Sheet 2: Active OTs
  const activeOTsData = this.activeProduction.map(ot => ({
    OT: ot.OT,
    Cliente: ot['Razon Social'],
    Producto: ot.descripcion,
    Maquina: ot.maquina,
    Metros: ot.total_mtl
  }));
  const wsOTs = XLSX.utils.json_to_sheet(activeOTsData);
  XLSX.utils.book_append_sheet(wb, wsOTs, "Producción en Curso");

  XLSX.writeFile(wb, `Dashboard_Data_${dateStr}.xlsx`);
}

System Logs

The dashboard displays the most recent system audit events in a terminal-style panel.
// System Logs Display (dashboard.component.ts:393-410)
<div class="font-mono text-[9px] text-slate-400 space-y-2">
  @for (log of systemLogs; track log.timestamp) {
    <p class="flex gap-2">
      <span class="font-bold text-blue-500">{{ log.timestamp | date:'HH:mm:ss' }}</span> 
      <span class="text-slate-300">{{ log.action }} - {{ log.details | slice:0:30 }}</span>
    </p>
  }
</div>

// Logs Getter (dashboard.component.ts:584-587)
get systemLogs() {
  return this.audit.logs().slice(0, 6);
}
Audit logs are stored locally and synchronized to the server periodically. The sync queue count is displayed in the header.

Import Workflow

The dashboard provides a streamlined import process for bulk OT updates.
1

Select Import File

Click “Importar” button and select Excel/CSV file containing OT data.
2

Data Processing

System automatically maps columns and validates required fields.
3

Merge Strategy

Existing OTs are updated while preserving their current status. New OTs are created with PENDIENTE status.
4

Confirmation

Review summary and confirm import. All changes are logged to audit trail.
// Import Handler (dashboard.component.ts:713-740)
handleImport(data: any[]) {
  const currentData = this.ordersService.ots;
  let updatedData = [...currentData];

  data.forEach((row: any) => {
    if (!row.OT) return;
    const rowOtStr = String(row.OT).trim();
    const index = updatedData.findIndex(
      item => String(item.OT).trim() === rowOtStr
    );
    
    if (index !== -1) {
      // Update existing, preserve status
      const currentStatus = updatedData[index].Estado_pedido;
      updatedData[index] = { ...updatedData[index], ...row };
      if (currentStatus) {
        updatedData[index].Estado_pedido = currentStatus;
      }
    } else {
      // Insert new with PENDIENTE status
      updatedData.push({
        ...row,
        Estado_pedido: 'PENDIENTE'
      });
    }
  });
  
  this.ordersService.updateOts(updatedData);
  alert(`Importación completada. Se procesaron ${data.length} registros.`);
}

The dashboard provides quick navigation to all major modules:

OT Management

Navigate to full order management interface

Incidents

View and manage quality incidents

Sync Queue

Review pending offline sync operations
// Navigation Examples (dashboard.component.ts)
<button (click)="router.navigate(['/incidents'])">
  Incidencias
</button>

<button (click)="router.navigate(['/ots'])">
  Ver Historial Completo
</button>

<button (click)="router.navigate(['/sync'])">
  Cola Sync
</button>

Order Management

Full OT lifecycle management and tracking

Quality Control

Incident management and CAPA workflows

Production Tracking

Real-time production monitoring and reporting

Inventory

Tooling and finished goods inventory

Build docs developers (and LLMs) love