Skip to main content

Dashboard Overview

The MLM CMMS reporting dashboards provide an intuitive, highly customizable interface for monitoring maintenance operations. Each dashboard tab features drag-and-drop KPI tiles and report cards that adapt to your workflow.

Dashboard Structure

Global Controls

Date Presets

Quick filters: Last 30 days, Last 90 days, Year-to-Date (YTD), or Custom ranges

Location Filter

Filter all reports by specific facilities or view organization-wide metrics

Refresh Controls

Manual refresh for active tab or reset layouts to default configurations

Layout Persistence

Automatic saving of KPI and card arrangements per user account

Filter Application

Filters are applied globally across all report tabs:
src/services/reportService.ts:279-289
function buildFilters(args: {
  locationId: number | '';
  fromDate: string;
  toDate: string;
}): DashboardReportFilters {
  return {
    locationId: typeof args.locationId === 'number' ? args.locationId : undefined,
    from: args.fromDate ? `${args.fromDate}T00:00:00` : undefined,
    to: args.toDate ? `${args.toDate}T23:59:59` : undefined,
  };
}
Date filters include start of day (00:00:00) for from and end of day (23:59:59) for to timestamps, ensuring complete date coverage.

Executive Summary Dashboard

KPI Tiles

The Executive Summary provides seven critical indicators:
  • Open Work Orders: Active maintenance tasks requiring attention (⚠️ Warning tone)
  • Overdue Work Orders: Past-deadline items needing immediate action (🔴 Danger tone)
  • Urgent Open: High-priority emergency tickets (🔴 Danger tone)

Report Cards

Three detailed analysis cards:
  1. Demand by Location - Horizontal bar chart showing ticket volume per facility
  2. Special Incidents - Impact breakdown by incident type (natural disasters, equipment failures, etc.)
  3. Top Consumed Parts - Inventory items with highest usage in date range
const executiveKpis = [
  { id: 'openWorkOrders', label: 'OT abiertas', value: data.kpis.openWorkOrders, tone: 'warn' },
  { id: 'overdueWorkOrders', label: 'OT vencidas', value: data.kpis.overdueWorkOrders, tone: 'danger' },
  { id: 'urgentOpen', label: 'Urgentes abiertas', value: data.kpis.urgentOpen, tone: 'danger' },
  { id: 'assetsOutOfService', label: 'Activos fuera de servicio', value: data.kpis.assetsOutOfService, tone: 'warn' },
  { id: 'needsReorder', label: 'Repuestos por reponer', value: data.kpis.needsReorder, tone: 'warn' },
  { id: 'activeAnnouncements', label: 'Anuncios activos', value: data.kpis.activeAnnouncements },
  { id: 'inventoryValuation', label: 'Valorización inventario', value: formatCurrency(data.kpis.inventoryValuation), tone: 'good' }
];

Work Management Dashboard

KPI Tiles

Eight operational metrics for maintenance teams:
  • Request Backlog: Unapproved work requests awaiting review
  • Work Order Backlog: Approved but incomplete tasks
  • OT Urgentes: Urgent work orders requiring immediate attention
  • OT Vencidas: Overdue work orders past deadline
  • OT Sin Asignación: Unassigned work orders needing technician allocation
  • Tickets Archivados: Historical archived tickets
  • Tiempo de Resolución Promedio: Average hours from creation to completion
  • SLA a Tiempo: Percentage of work orders completed within deadline
SLA rate displays in green (✅ good tone) when ≥ 80%, otherwise amber (⚠️ warning tone).

Report Cards

Seven analytical views:
1

Tickets por Estado

Distribution across Pendiente, En Ejecución, and Finalizadas statuses
2

Tickets por Prioridad

Breakdown by Crítica, Alta, Media, Baja priority levels
3

Antigüedad del Pendiente

Age buckets: 0-2 days, 3-7 days, 8-15 days, 16-30 days, 30+ days
4

Cumplimiento de Plazos

Categories: A tiempo, Tarde, Abierta vencida, Sin deadline, Abierta dentro de plazo
5

Carga por Técnico

Table showing open count, closed count, and average resolution time per technician
6

Demanda por Ubicación

Location-based ticket volume analysis
7

Incidentes Especiales

Special incident categorization and impact

Technician Performance Table

Detailed productivity metrics:
src/components/reports/ReportsDashboard.tsx:691-718
const techColumns: ReportTableColumn[] = [
  {
    key: 'technician',
    label: 'Técnico',
    render: (row) => <span className="font-medium">{row.technician}</span>,
  },
  {
    key: 'openCount',
    label: 'OT abiertas',
    align: 'right',
    render: (row) => formatNumber(row.openCount),
  },
  {
    key: 'closedCount',
    label: 'OT cerradas',
    align: 'right',
    render: (row) => formatNumber(row.closedCount),
  },
  {
    key: 'avgResolutionHours',
    label: 'Prom. resolución',
    align: 'right',
    render: (row) => formatHours(row.avgResolutionHours),
  },
];

Assets Dashboard

Requires assets:read or assets:full_access permission.

KPI Tiles

Ten asset health indicators:
  • Total Assets: Complete asset count
  • Active Assets: Operational equipment (✅ Good tone)
  • In Maintenance: Assets under service (⚠️ Warning)
  • Out of Service: Non-operational equipment (🔴 Danger)
  • Retired: Decommissioned assets

Report Cards

Six asset analysis views:
  1. Estado de Activos - Status distribution (EN_SERVICIO, EN_MANTENIMIENTO, FUERA_DE_SERVICIO, RETIRADO)
  2. Criticidad de Activos - Criticality levels 1 (Very Low) to 5 (Critical)
  3. Tipo de Mantenimiento - Maintenance type breakdown (PREVENTIVO, CORRECTIVO, PREDICTIVO)
  4. Activos con Más Tickets - Top 10 assets by work order volume
  5. Mayor Costo de Mantenimiento - Top 10 assets by maintenance spend
  6. Mayor Inactividad - Top 10 assets by downtime minutes
Maintenance costs aggregate labor_cost + parts_cost + other_cost from the asset_maintenance_log table. Ensure accurate cost entry for reliable reporting.

Inventory Parts Dashboard

Requires inventory:read or inventory:full_access permission.

KPI Tiles

Ten inventory metrics:
  • Total Parts: Unique part count
  • Critical Parts: High/Critical priority items
  • On Hand Qty: Current stock levels
  • Reserved Qty: Parts allocated to work orders
  • Available Qty: Stock available for new requests
  • Needs Reorder: Parts below minimum threshold
  • Docs Draft: Incomplete inventory documents
  • Docs Cancelled: Canceled transactions
  • Inventory Valuation: Total stock value
  • Consumption Cost: Period consumption value

Report Cards

Documents by Status

Inventory document status distribution (DRAFT, POSTED, CANCELLED)

Documents by Type

Transaction types: ENTRADA, SALIDA, AJUSTE, TRANSFERENCIA

Top Consumed Parts

Highest usage parts with consumption quantities

Reorder Suggestions

Parts needing replenishment with suggested quantities

Pending Delivery by WO

Reserved parts awaiting issuance to work orders

Administration Dashboard

Requires admin permissions: users:read, rbac:manage_permissions, rbac:manage_roles, or announcements:read.

KPI Tiles

  • Roles: Total role definitions
  • Permissions: Total permission codes
  • Active Users: Currently enabled accounts
  • Inactive Users: Disabled accounts
  • Active Technicians: Assignable technicians
  • Technicians Without User: Unlinked technician records
  • Active Announcements: Current system notifications
  • Expiring Announcements: Announcements ending within 7 days
  • Active Locations: Enabled facilities
  • Active Societies: Enabled organizational entities

Report Cards

  1. Users by Role - User distribution across defined roles
  2. Technicians by Section - Assignment breakdown by department
  3. Announcements by Level - Notification severity distribution (info, warning, critical)
  4. Demand by Location - Ticket volume per facility (filtered by date range)
  5. Role Permission Matrix - Table showing role name, user count, and permission count

Customization Features

Drag-and-Drop Layout

1

Enable Sorting

Click and hold any KPI tile or report card to activate drag mode
2

Reposition

Drag the item to your desired position within the grid
3

Drop

Release to lock the new arrangement
4

Auto-Save

Layout preferences save automatically to your user profile

Layout Persistence

Implemented via reportLayoutService.ts:
src/services/reportLayoutService.ts:58-87
export async function getReportLayoutPreferences(): Promise<Record<string, string[]>> {
  const userId = await getCurrentUserId();
  if (!userId) return {};
  
  const localLayouts = readFromLocalStorage(userId);
  
  if (!ENABLE_REMOTE_LAYOUT_SYNC) {
    return localLayouts;
  }
  
  // Fetch from report_layout_preferences table
  const { data, error } = await supabase
    .from('report_layout_preferences')
    .select('tab_id, widget_order')
    .eq('user_id', userId);
  
  // Merge local and remote layouts
  const result = { ...localLayouts };
  for (const row of rows) {
    result[row.tab_id] = sanitizeWidgetOrder(row.widget_order);
  }
  
  return result;
}
Layout preferences use a two-tier strategy: localStorage for offline resilience and optional Supabase sync (controlled by VITE_ENABLE_REMOTE_REPORT_LAYOUT=true).

Reset Options

Orden por defecto button restores default arrangement for the active tab only

Animation and UX

Motion Design

The dashboard uses Framer Motion for smooth transitions:
src/components/reports/ReportsDashboard.tsx:678-689
const revealProps = (delay: number) =>
  prefersReducedMotion
    ? {}
    : {
        initial: { opacity: 0, y: 14, scale: 0.996 },
        animate: { opacity: 1, y: 0, scale: 1 },
        transition: {
          duration: 0.42,
          delay,
          ease: [0.22, 1, 0.36, 1] as const,
        },
      };
Animations automatically disable when prefers-reduced-motion is detected, ensuring accessibility compliance.

Best Practices

Place critical metrics (overdue tickets, urgent work orders) in top-left positions for immediate visibility.
When investigating site-specific issues, isolate location data to identify local patterns and anomalies.
Run reports for current period (30d), then switch to same period last quarter/year for trend comparison.
Periodically reassess your dashboard layout as priorities shift (e.g., move inventory KPIs up during supply chain disruptions).
Use Year-to-Date filters when preparing budget proposals or annual maintenance strategy reviews.

Troubleshooting

Report Not Loading

1

Check Permissions

Verify your account has required permissions for the report tab (Assets, Inventory, Admin)
2

Verify Date Range

Ensure from date is before to date; invalid ranges return empty results
3

Clear Cache

Use “Refrescar” button to force data reload; stale cache may show outdated metrics
4

Inspect Network

Open browser DevTools > Network tab; look for failed API calls to Supabase

Layout Not Saving

If VITE_ENABLE_REMOTE_REPORT_LAYOUT=false, layouts only persist in browser localStorage. Clearing browser data will reset all layouts.

Next: Custom Reports

Learn how to generate specialized reports and export data for external analysis