sapenlinea-components 0.10.84 → 0.10.86

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/README.md CHANGED
@@ -1226,209 +1226,531 @@ Toggle (interruptor on/off) estilizado con label integrado. Implementa `ControlV
1226
1226
 
1227
1227
  > Los campos `toggle` siempre ocupan la fila completa del formulario y nunca comparten fila con otros tipos de campo. Hasta 4 toggles consecutivos se distribuyen automáticamente en la misma fila (cada uno ocupa 1/4 del ancho).
1228
1228
 
1229
- ---
1230
- ### 33. `lib-option-card` (OptionCard)
1231
-
1232
- **Qué hace**
1233
- Tarjeta interactiva estilizada con ícono para presentar opciones seleccionables, utilizada típicamente en menús o modales. Permite personalizar el estado visual y colores.
1234
-
1235
- **Selector:** `lib-option-card`
1236
-
1237
- **Inputs:**
1238
- - `label: string` (requerido) – Título principal de la opción.
1239
- - `description: string` – Texto de acompañamiento secundario.
1240
- - `buttonBg: string` – Color de fondo CSS del cuerpo general de la tarjeta.
1241
- - `iconBg: string` – Color de fondo **sólido** del contenedor de ícono interno.
1242
-
1243
- **Outputs:**
1244
- - `clickAction: EventEmitter<void>` – Invocado al presionar la tarjeta completa.
1245
-
1246
- **Proyección:**
1247
- Usa `<svg icon ...></svg>` (selector `[icon]`) para insertar un gráfico que adoptará de forma automática el color surface contrastante para una correcta legibilidad frente a `iconBg`.
1248
-
1249
- ---
1250
-
1251
- ### 34. `lib-kpi-card` (KpiCard)
1252
-
1253
- **Qué hace**
1254
- Tarjeta informativa destinada a exponer Indicadores de Rendimiento (KPI) con el título, descripción, icono y valor métrico destacado.
1255
-
1256
- **Selector:** `lib-kpi-card`
1257
-
1258
- **Inputs principales:**
1259
- - `title: string` – Cabecera del KPI.
1260
- - `description: string` – Metadato o guía visual inferior.
1261
- - `value: string | number` – Indicador numérico/texto del KPI.
1262
- - `iconColor: "primary" | "secondary" | "tertiary" | "quaternary"` – Asigna el esquema de colores/tonos automáticamente al ícono.
1263
-
1264
- **Proyección:**
1265
- Usa el contenedor de `<svg icon ...></svg>` para alojar el identificador visual genérico del KPI.
1266
-
1267
- ---
1268
-
1269
- ### 35. `lib-load-image` (LoadImage)
1270
-
1271
- **Qué hace**
1272
- Zona de arrastrar y soltar (Drag & Drop) para la **recepción de imágenes** de los usuarios, la cual permite la visualización in-place, borrado, carga manual y explorador interactivo modal en pantalla completa (lightbox estilo zoom).
1273
-
1274
- **Selector:** `lib-load-image`
1275
-
1276
- **Inputs principales:**
1277
- - `title: string = "Cargar firma"` – Encabezado superior.
1278
- - `description: string = "Formatos admitidos..."` – Helper text inferior.
1279
- - `titleIcon: string = ""` – Renderiza una clase CSS particular de ícono sobre el título.
1280
- - `iconUpload: boolean = false` – Ajuste de la gráfica in-caja que induce a la subida de un archivo.
1281
- - `imageUrl: string = ""` – Permite inyectar y visualizar nativamente una imagen preexistente obtenida desde una URL externa (ideal para editar la entidad de un bucket).
1282
-
1283
- **Outputs:**
1284
- - `imageLoaded: EventEmitter<File | null>` – Entrega el archivo File procesado para subidas directas del usuario o `null` si lo borró.
1285
-
1286
- ---
1287
-
1288
- ### 36. Gráficas y Visualización: ECharts (Charts)
1289
-
1290
- **Qué hacen**
1291
- Subsistema de envolturas especializadas (wrappers) cimentado sobre `apache/echarts` para habilitar representaciones informativas sólidas a tamaño responsivo y dinámico. Incluye soporte para interactividad, visualizaciones jerárquicas, tablas expandibles y una paleta de 20 colores.
1292
-
1293
- **Componentes disponibles:**
1294
-
1295
- #### `lib-bar-chart`
1296
- Gráfica de barras estandarizada con soporte para una o múltiples series.
1297
- - **Inputs:**
1298
- - `data: ChartItem[]` – Datos para gráfica de barra simple.
1299
- - `multiSeries: BarSeries[]` – (Opcional) Permite mostrar grupos de barras por cada sección.
1300
- - **Interfaces:**
1301
- ```ts
1302
- export interface BarSeries {
1303
- name: string; // Nombre de la serie (aparece en la leyenda)
1304
- data: number[]; // Valores numéricos
1305
- color?: string; // Color personalizado opcional
1306
- }
1307
- ```
1308
-
1309
- #### `lib-donut-chart`
1310
- Gráfica de anillo con capacidad de **Drill-down**, navegación interna y leyenda automática.
1311
- - **Inputs:**
1312
- - `data: ChartItem[]` – Datos granulares (ej. códigos de infracción `D01`, `D02`, `C01`).
1313
- - `drillDown: boolean = false` – Activa el modo de exploración jerárquica.
1314
- - `groupByPrefix: number = 0` – Agrupa los datos por los primeros N caracteres de la etiqueta (ej. `1` para agrupar por letras iniciales).
1315
- - **Comportamiento:**
1316
- - Al activar el drill-down, el componente muestra inicialmente los totales agrupados y permite al usuario pulsar una sección para "abrirla" y ver su desglose, con un botón de "Volver" integrado.
1317
- - Cuando hay **más de 10 ítems**, los labels de las porciones se ocultan automáticamente y se muestra una **leyenda horizontal scrollable** en la parte inferior.
1318
-
1319
- #### `lib-table-chart`
1320
- Tabla expandible integrada en el dashboard de gráficas, con paginación y estado "sin datos".
1321
- - **Inputs:**
1322
- - `title: string = 'Table Chart'` – Título del encabezado.
1323
- - `columns: TableColumn[]` – Definición de columnas (misma interfaz que `lib-table`).
1324
- - `data: TableRow[]` – Datos de la tabla.
1325
- - `totalItems: number = 0` – Total de registros (para la paginación).
1326
- - `itemsPerPage: number = 10` – Registros por página en modo expandido.
1327
- - **Comportamiento:**
1328
- - **Colapsado**: Muestra los primeros **8 registros** sin paginación.
1329
- - **Expandido**: Ocupa pantalla completa (90vw × 90vh) con overlay, muestra **10 registros** por página con `lib-pagination`.
1330
- - Si `data` está vacío muestra `lib-not-found-section` centrado.
1331
-
1332
- **Ejemplo:**
1333
-
1334
- ```html
1335
- <lib-table-chart
1336
- title="Tabla de Comparendos"
1337
- [columns]="columns"
1338
- [data]="comparendosData"
1339
- [totalItems]="comparendosData.length" />
1340
- ```
1341
-
1342
- #### Otros:
1343
- - `lib-line-chart` – Líneas analíticas en evolución.
1344
- - `lib-heatmap` – Mapa de concentración de calor basado en coordenadas / categorías.
1345
- - `lib-map-geo` – Puntos de calor sobre mapa geofísico interactivo.
1346
-
1347
- **Paleta de colores (20 colores):**
1348
- La paleta compartida por todas las gráficas incluye: olive green, lime soft, burgundy, deep teal, sage, chartreuse, sky blue, light steel blue, warm amber, terracotta, dusty purple, jade green, coral clay, charcoal slate, sand gold, mint sage, rose mauve, navy steel, peach y spring green.
1349
-
1350
- **Eventos Globales:**
1351
- Todos los componentes de gráficas emiten el evento `chartClick`, permitiendo capturar clics en secciones específicas para lógicas personalizadas en el padre.
1352
-
1353
- ---
1354
-
1355
- ### 37. `lib-quick-access-cards` (QuickAccessCards)
1356
-
1357
- **Qué hace**
1358
- Componente de **accesos rápidos** que renderiza un grid de tarjetas (`lib-option-card` en modo `quick-access`) con hasta **4 columnas** por fila. Si hay más de 4 items, los restantes se posicionan en la siguiente fila. Los íconos se definen mediante un **nombre de clase CSS** en lugar de SVG inline, simplificando la configuración significativamente.
1359
-
1360
- **Selector:** `lib-quick-access-cards`
1361
-
1362
- **Inputs:**
1363
-
1364
- | Input | Tipo | Default | Descripción |
1365
- |---|---|---|---|
1366
- | `title` | `string` | `'Accesos Rápidos'` | Título visible sobre el grid de tarjetas |
1367
- | `items` | `QuickAccessItem[]` | `[]` | Lista de accesos rápidos a renderizar |
1368
-
1369
- **Outputs:**
1370
-
1371
- - `clickAction: EventEmitter<QuickAccessItem>` – Emite el item completo al hacer clic en una tarjeta.
1372
-
1373
- **Interfaz:**
1374
-
1375
- ```ts
1376
- export interface QuickAccessItem {
1377
- id: string;
1378
- label: string;
1379
- description: string;
1380
- icon: string; // Nombre de clase CSS del ícono, ej. 'icon-building'
1381
- iconBg?: string; // Color de fondo del contenedor del ícono
1382
- }
1383
- ```
1384
-
1385
- **Íconos disponibles:**
1386
-
1387
- | Clase | Descripción |
1388
- |---|---|
1389
- | `icon-settings` | Configuración / engranaje |
1390
- | `icon-check` | Check / verificado |
1391
- | `icon-close` | Cerrar / X |
1392
- | `icon-info` | Información |
1393
- | `icon-alert` | Alerta / triángulo |
1394
- | `icon-star` | Estrella |
1395
- | `icon-users` | Usuarios / personas |
1396
- | `icon-building` | Edificio / organismo |
1397
- | `icon-car` | Vehículo |
1398
- | `icon-shield` | Escudo / seguridad |
1399
- | `icon-clipboard` | Portapapeles |
1400
- | `icon-map-pin` | Ubicación / mapa |
1401
- | `icon-chart` | Gráfica de barras |
1402
- | `icon-file` | Documento / archivo |
1403
- | `icon-refresh` | Refrescar / recargar |
1404
- | `icon-edit` | Editar / lápiz |
1405
- | `icon-search` | Buscar / lupa |
1406
-
1407
- **Ejemplo de uso:**
1408
-
1409
- ```ts
1410
- import { QuickAccessCards, QuickAccessItem } from 'sapenlinea-components';
1411
-
1412
- quickAccessItems: QuickAccessItem[] = [
1413
- { id: '1', label: 'Organismo de tránsito', description: 'Información del organismo', icon: 'icon-building', iconBg: '#00695c' },
1414
- { id: '2', label: 'Usuarios', description: 'Administración de usuarios', icon: 'icon-users', iconBg: '#0d47a1' },
1415
- { id: '3', label: 'Roles', description: 'Administración de roles', icon: 'icon-shield', iconBg: '#f57f17' },
1416
- { id: '4', label: 'Reportes', description: 'Generación de reportes', icon: 'icon-chart', iconBg: '#b71c1c' },
1417
- ];
1418
- ```
1419
-
1420
- ```html
1421
- <lib-quick-access-cards
1422
- [title]="'Accesos Rápidos'"
1423
- [items]="quickAccessItems"
1424
- (clickAction)="onQuickAccess($event)" />
1425
- ```
1426
-
1427
- **Comportamiento responsive:**
1428
-
1429
- | Ancho de pantalla | Columnas |
1430
- |---|---|
1431
- | > 1200px | 4 columnas |
1432
- | 900px – 1200px | 3 columnas |
1433
- | 600px – 900px | 2 columnas |
1434
- | < 600px | 1 columna |
1229
+ ---
1230
+ ### 33. `lib-option-card` (OptionCard)
1231
+
1232
+ **Qué hace**
1233
+ Tarjeta interactiva estilizada con ícono para presentar opciones seleccionables, utilizada típicamente en menús o modales. Permite personalizar el estado visual y colores.
1234
+
1235
+ **Selector:** `lib-option-card`
1236
+
1237
+ **Inputs:**
1238
+ - `label: string` (requerido) – Título principal de la opción.
1239
+ - `description: string` – Texto de acompañamiento secundario.
1240
+ - `buttonBg: string` – Color de fondo CSS del cuerpo general de la tarjeta.
1241
+ - `iconBg: string` – Color de fondo **sólido** del contenedor de ícono interno.
1242
+
1243
+ **Outputs:**
1244
+ - `clickAction: EventEmitter<void>` – Invocado al presionar la tarjeta completa.
1245
+
1246
+ **Proyección:**
1247
+ Usa `<svg icon ...></svg>` (selector `[icon]`) para insertar un gráfico que adoptará de forma automática el color surface contrastante para una correcta legibilidad frente a `iconBg`.
1248
+
1249
+ ---
1250
+
1251
+ ### 34. `lib-kpi-card` (KpiCard)
1252
+
1253
+ **Qué hace**
1254
+ Tarjeta informativa destinada a exponer Indicadores de Rendimiento (KPI) con el título, descripción, icono y valor métrico destacado.
1255
+
1256
+ **Selector:** `lib-kpi-card`
1257
+
1258
+ **Inputs principales:**
1259
+ - `title: string` – Cabecera del KPI.
1260
+ - `description: string` – Metadato o guía visual inferior.
1261
+ - `value: string | number` – Indicador numérico/texto del KPI.
1262
+ - `iconColor: "primary" | "secondary" | "tertiary" | "quaternary"` – Asigna el esquema de colores/tonos automáticamente al ícono.
1263
+
1264
+ **Proyección:**
1265
+ Usa el contenedor de `<svg icon ...></svg>` para alojar el identificador visual genérico del KPI.
1266
+
1267
+ ---
1268
+
1269
+ ### 35. `lib-load-image` (LoadImage)
1270
+
1271
+ **Qué hace**
1272
+ Zona de arrastrar y soltar (Drag & Drop) para la **recepción de imágenes** de los usuarios, la cual permite la visualización in-place, borrado, carga manual y explorador interactivo modal en pantalla completa (lightbox estilo zoom).
1273
+
1274
+ **Selector:** `lib-load-image`
1275
+
1276
+ **Inputs principales:**
1277
+ - `title: string = "Cargar firma"` – Encabezado superior.
1278
+ - `description: string = "Formatos admitidos..."` – Helper text inferior.
1279
+ - `titleIcon: string = ""` – Renderiza una clase CSS particular de ícono sobre el título.
1280
+ - `iconUpload: boolean = false` – Ajuste de la gráfica in-caja que induce a la subida de un archivo.
1281
+ - `imageUrl: string = ""` – Permite inyectar y visualizar nativamente una imagen preexistente obtenida desde una URL externa (ideal para editar la entidad de un bucket).
1282
+
1283
+ **Outputs:**
1284
+ - `imageLoaded: EventEmitter<File | null>` – Entrega el archivo File procesado para subidas directas del usuario o `null` si lo borró.
1285
+
1286
+ ---
1287
+
1288
+ ### 36. Gráficas y Visualización: ECharts (Charts)
1289
+
1290
+ **Qué hacen**
1291
+ Subsistema de envolturas especializadas (wrappers) cimentado sobre `apache/echarts` para habilitar representaciones informativas sólidas a tamaño responsivo y dinámico. Incluye soporte para interactividad, visualizaciones jerárquicas, tablas expandibles y una paleta de 20 colores.
1292
+
1293
+ **Componentes disponibles:**
1294
+
1295
+ #### `lib-bar-chart`
1296
+ Gráfica de barras estandarizada con soporte para una o múltiples series.
1297
+ - **Inputs:**
1298
+ - `data: ChartItem[]` – Datos para gráfica de barra simple.
1299
+ - `multiSeries: BarSeries[]` – (Opcional) Permite mostrar grupos de barras por cada sección.
1300
+ - **Interfaces:**
1301
+ ```ts
1302
+ export interface BarSeries {
1303
+ name: string; // Nombre de la serie (aparece en la leyenda)
1304
+ data: number[]; // Valores numéricos
1305
+ color?: string; // Color personalizado opcional
1306
+ }
1307
+ ```
1308
+
1309
+ #### `lib-donut-chart`
1310
+ Gráfica de anillo con capacidad de **Drill-down**, navegación interna y leyenda automática.
1311
+ - **Inputs:**
1312
+ - `data: ChartItem[]` – Datos granulares (ej. códigos de infracción `D01`, `D02`, `C01`).
1313
+ - `drillDown: boolean = false` – Activa el modo de exploración jerárquica.
1314
+ - `groupByPrefix: number = 0` – Agrupa los datos por los primeros N caracteres de la etiqueta (ej. `1` para agrupar por letras iniciales).
1315
+ - **Comportamiento:**
1316
+ - Al activar el drill-down, el componente muestra inicialmente los totales agrupados y permite al usuario pulsar una sección para "abrirla" y ver su desglose, con un botón de "Volver" integrado.
1317
+ - Cuando hay **más de 10 ítems**, los labels de las porciones se ocultan automáticamente y se muestra una **leyenda horizontal scrollable** en la parte inferior.
1318
+
1319
+ #### `lib-table-chart`
1320
+ Tabla expandible integrada en el dashboard de gráficas, con paginación y estado "sin datos".
1321
+ - **Inputs:**
1322
+ - `title: string = 'Table Chart'` – Título del encabezado.
1323
+ - `columns: TableColumn[]` – Definición de columnas (misma interfaz que `lib-table`).
1324
+ - `data: TableRow[]` – Datos de la tabla.
1325
+ - `totalItems: number = 0` – Total de registros (para la paginación).
1326
+ - `itemsPerPage: number = 10` – Registros por página en modo expandido.
1327
+ - **Comportamiento:**
1328
+ - **Colapsado**: Muestra los primeros **8 registros** sin paginación.
1329
+ - **Expandido**: Ocupa pantalla completa (90vw × 90vh) con overlay, muestra **10 registros** por página con `lib-pagination`.
1330
+ - Si `data` está vacío muestra `lib-not-found-section` centrado.
1331
+
1332
+ **Ejemplo:**
1333
+
1334
+ ```html
1335
+ <lib-table-chart
1336
+ title="Tabla de Comparendos"
1337
+ [columns]="columns"
1338
+ [data]="comparendosData"
1339
+ [totalItems]="comparendosData.length" />
1340
+ ```
1341
+
1342
+ #### Otros:
1343
+ - `lib-line-chart` – Líneas analíticas en evolución.
1344
+ - `lib-heatmap` – Mapa de concentración de calor basado en coordenadas / categorías.
1345
+ - `lib-map-geo` – Puntos de calor sobre mapa geofísico interactivo.
1346
+
1347
+ **Paleta de colores (20 colores):**
1348
+ La paleta compartida por todas las gráficas incluye: olive green, lime soft, burgundy, deep teal, sage, chartreuse, sky blue, light steel blue, warm amber, terracotta, dusty purple, jade green, coral clay, charcoal slate, sand gold, mint sage, rose mauve, navy steel, peach y spring green.
1349
+
1350
+ **Eventos Globales:**
1351
+ Todos los componentes de gráficas emiten el evento `chartClick`, permitiendo capturar clics en secciones específicas para lógicas personalizadas en el padre.
1352
+
1353
+ ---
1354
+
1355
+ ### 37. `lib-quick-access-cards` (QuickAccessCards)
1356
+
1357
+ **Qué hace**
1358
+ Componente de **accesos rápidos** que renderiza un grid de tarjetas (`lib-option-card` en modo `quick-access`) con hasta **4 columnas** por fila. Si hay más de 4 items, los restantes se posicionan en la siguiente fila. Los íconos se definen mediante un **nombre de clase CSS** en lugar de SVG inline, simplificando la configuración significativamente.
1359
+
1360
+ **Selector:** `lib-quick-access-cards`
1361
+
1362
+ **Inputs:**
1363
+
1364
+ | Input | Tipo | Default | Descripción |
1365
+ |---|---|---|---|
1366
+ | `title` | `string` | `'Accesos Rápidos'` | Título visible sobre el grid de tarjetas |
1367
+ | `items` | `QuickAccessItem[]` | `[]` | Lista de accesos rápidos a renderizar |
1368
+
1369
+ **Outputs:**
1370
+
1371
+ - `clickAction: EventEmitter<QuickAccessItem>` – Emite el item completo al hacer clic en una tarjeta.
1372
+
1373
+ **Interfaz:**
1374
+
1375
+ ```ts
1376
+ export interface QuickAccessItem {
1377
+ id: string;
1378
+ label: string;
1379
+ description: string;
1380
+ icon: string; // Nombre de clase CSS del ícono, ej. 'icon-building'
1381
+ iconBg?: string; // Color de fondo del contenedor del ícono
1382
+ }
1383
+ ```
1384
+
1385
+ **Íconos disponibles:**
1386
+
1387
+ | Clase | Descripción |
1388
+ |---|---|
1389
+ | `icon-settings` | Configuración / engranaje |
1390
+ | `icon-check` | Check / verificado |
1391
+ | `icon-close` | Cerrar / X |
1392
+ | `icon-info` | Información |
1393
+ | `icon-alert` | Alerta / triángulo |
1394
+ | `icon-star` | Estrella |
1395
+ | `icon-users` | Usuarios / personas |
1396
+ | `icon-building` | Edificio / organismo |
1397
+ | `icon-car` | Vehículo |
1398
+ | `icon-shield` | Escudo / seguridad |
1399
+ | `icon-clipboard` | Portapapeles |
1400
+ | `icon-map-pin` | Ubicación / mapa |
1401
+ | `icon-chart` | Gráfica de barras |
1402
+ | `icon-file` | Documento / archivo |
1403
+ | `icon-refresh` | Refrescar / recargar |
1404
+ | `icon-edit` | Editar / lápiz |
1405
+ | `icon-search` | Buscar / lupa |
1406
+
1407
+ **Ejemplo de uso:**
1408
+
1409
+ ```ts
1410
+ import { QuickAccessCards, QuickAccessItem } from 'sapenlinea-components';
1411
+
1412
+ quickAccessItems: QuickAccessItem[] = [
1413
+ { id: '1', label: 'Organismo de tránsito', description: 'Información del organismo', icon: 'icon-building', iconBg: '#00695c' },
1414
+ { id: '2', label: 'Usuarios', description: 'Administración de usuarios', icon: 'icon-users', iconBg: '#0d47a1' },
1415
+ { id: '3', label: 'Roles', description: 'Administración de roles', icon: 'icon-shield', iconBg: '#f57f17' },
1416
+ { id: '4', label: 'Reportes', description: 'Generación de reportes', icon: 'icon-chart', iconBg: '#b71c1c' },
1417
+ ];
1418
+ ```
1419
+
1420
+ ```html
1421
+ <lib-quick-access-cards
1422
+ [title]="'Accesos Rápidos'"
1423
+ [items]="quickAccessItems"
1424
+ (clickAction)="onQuickAccess($event)" />
1425
+ ```
1426
+
1427
+ **Comportamiento responsive:**
1428
+
1429
+ | Ancho de pantalla | Columnas |
1430
+ |---|---|
1431
+ | > 1200px | 4 columnas |
1432
+ | 900px – 1200px | 3 columnas |
1433
+ | 600px – 900px | 2 columnas |
1434
+ | < 600px | 1 columna |
1435
+
1436
+ ---
1437
+
1438
+ ### 38. `lib-input-time-filter` (InputTimeFilter)
1439
+
1440
+ **Qué hace**
1441
+ Componente de **filtro de hora** con chips configurables y selector AM/PM desplegable. Implementa `ControlValueAccessor`.
1442
+
1443
+ **Selector:** `lib-input-time-filter`
1444
+
1445
+ **Inputs:**
1446
+
1447
+ - `filters: FilterItem[]` (requerido) – Filtros de hora disponibles.
1448
+ - `clearTrigger: number = 0` – Al incrementar este valor desde el padre se limpian todos los filtros.
1449
+
1450
+ **Outputs:**
1451
+
1452
+ - `filterSelected: EventEmitter<{ filter: string; value: string }>` – Emite el filtro activo y el valor en formato `HH:mm` (24 h).
1453
+ - `valueChange: EventEmitter<string | null>` – Emite la hora seleccionada o `null` al limpiar.
1454
+ - `enterPressed: EventEmitter<void>` – Emite al presionar Enter con el dropdown abierto.
1455
+
1456
+ **Ejemplo de uso:**
1457
+
1458
+ ```html
1459
+ <lib-input-time-filter
1460
+ [filters]="timeFilters"
1461
+ [clearTrigger]="clearVersion"
1462
+ (filterSelected)="onTimeFilter($event)"
1463
+ (valueChange)="onTimeChange($event)"
1464
+ ></lib-input-time-filter>
1465
+ ```
1466
+
1467
+ ```ts
1468
+ timeFilters: FilterItem[] = [
1469
+ { label: 'Hora inicio', value: 'startTime', type: 'time' },
1470
+ { label: 'Hora fin', value: 'endTime', type: 'time' },
1471
+ ];
1472
+ ```
1473
+
1474
+ ---
1475
+
1476
+ ### 39. `lib-pdf-viewer` (PdfViewer) y `PdfViewerService`
1477
+
1478
+ **Qué hacen**
1479
+ Sistema de **visualización de documentos** (PDF e imágenes) en modal:
1480
+
1481
+ - `lib-pdf-viewer`: componente de modal que renderiza el documento activo según el servicio. Soporta múltiples URLs con navegación anterior/siguiente.
1482
+ - `PdfViewerService`: servicio singleton para abrir el visor y establecer el documento desde cualquier parte de la aplicación.
1483
+
1484
+ **Selector:** `lib-pdf-viewer`
1485
+
1486
+ Declarar `<lib-pdf-viewer></lib-pdf-viewer>` **una sola vez** (por ejemplo en `AppComponent`).
1487
+
1488
+ **`PdfViewerService` — API:**
1489
+
1490
+ | Método | Descripción |
1491
+ |---|---|
1492
+ | `open(doc: FileViewerDoc)` | Abre el visor con el documento indicado (recomendado) |
1493
+ | `openModal()` | Muestra el modal sin cambiar el documento |
1494
+ | `closeModal()` | Cierra el modal |
1495
+ | `setSelectedPdf(doc \| null)` | Establece el documento sin abrir el modal |
1496
+
1497
+ **`FileViewerDoc`:**
1498
+
1499
+ ```ts
1500
+ export interface FileViewerDoc {
1501
+ name: string;
1502
+ urls: string[]; // Una o varias URLs
1503
+ type?: 'pdf' | 'image'; // Si no se indica, se detecta por extensión
1504
+ }
1505
+ ```
1506
+
1507
+ **Ejemplo de uso:**
1508
+
1509
+ ```ts
1510
+ import { PdfViewerService } from 'sapenlinea-components';
1511
+
1512
+ constructor(private pdfViewer: PdfViewerService) {}
1513
+
1514
+ verDocumento(url: string) {
1515
+ this.pdfViewer.open({ name: 'Comparendo', urls: [url] });
1516
+ }
1517
+
1518
+ verImagenes(urls: string[]) {
1519
+ this.pdfViewer.open({ name: 'Evidencias', urls, type: 'image' });
1520
+ }
1521
+ ```
1522
+
1523
+ ---
1524
+
1525
+ ### 40. `lib-document-upload` (DocumentUpload)
1526
+
1527
+ **Qué hace**
1528
+ Zona de **arrastrar y soltar archivos** (Drag & Drop) con validación de tipo, tamaño máximo y lista de archivos adjuntados. Permite selección manual y eliminación individual.
1529
+
1530
+ **Selector:** `lib-document-upload`
1531
+
1532
+ **Inputs:**
1533
+
1534
+ - `label: string = 'Arrastra los archivos aquí o haz clic para seleccionar'`
1535
+ - `helperText: string = 'Máximo 25 MB por archivo'`
1536
+ - `accept: string = '.pdf,application/pdf'` – Valor para el atributo `accept` del input de archivo (ej. `"image/*"`, `".pdf,.png"`).
1537
+ - `maxSizeMB: number = 25` – Tamaño máximo permitido por archivo en MB.
1538
+ - `multiple: boolean = true` – Permite adjuntar varios archivos.
1539
+
1540
+ **Outputs:**
1541
+
1542
+ - `filesChanged: OutputEmitterRef<File[]>` – Emite el arreglo completo de archivos válidos cada vez que cambia.
1543
+
1544
+ **Ejemplo de uso:**
1545
+
1546
+ ```html
1547
+ <lib-document-upload
1548
+ label="Arrastra los soportes aquí"
1549
+ helperText="Solo PDF, máximo 10 MB"
1550
+ accept=".pdf"
1551
+ [maxSizeMB]="10"
1552
+ (filesChanged)="onFilesChanged($event)"
1553
+ />
1554
+ ```
1555
+
1556
+ ```ts
1557
+ onFilesChanged(files: File[]) {
1558
+ this.archivos = files;
1559
+ }
1560
+ ```
1561
+
1562
+ ---
1563
+
1564
+ ### 41. `lib-document-item` (DocumentItem)
1565
+
1566
+ **Qué hace**
1567
+ Elemento de lista que representa un **documento adjunto** (PDF, imagen o video) con fecha, nombre, folio opcional y botón de visualización.
1568
+
1569
+ **Selector:** `lib-document-item`
1570
+
1571
+ **Input:**
1572
+
1573
+ - `data: DocumentInfo` – Información del documento:
1574
+
1575
+ ```ts
1576
+ export interface DocumentInfo {
1577
+ folio?: string;
1578
+ name: string;
1579
+ creation_date: string; // ISO 8601
1580
+ type: 'document' | 'image' | 'video';
1581
+ actionKey: string;
1582
+ url?: string; // URL para previsualización o descarga
1583
+ }
1584
+ ```
1585
+
1586
+ **Output:**
1587
+
1588
+ - `view: OutputEmitterRef<DocumentInfo>` – Emite el documento al pulsar la acción de ver.
1589
+
1590
+ **Ejemplo de uso:**
1591
+
1592
+ ```html
1593
+ <lib-document-item
1594
+ [data]="doc"
1595
+ (view)="onViewDocument($event)"
1596
+ />
1597
+ ```
1598
+
1599
+ ```ts
1600
+ onViewDocument(doc: DocumentInfo) {
1601
+ this.pdfViewer.open({ name: doc.name, urls: [doc.url!] });
1602
+ }
1603
+ ```
1604
+
1605
+ ---
1606
+
1607
+ ### 42. `lib-card-history` (CardHistory)
1608
+
1609
+ **Qué hace**
1610
+ Tarjeta de **línea de tiempo / historial** con información de cambio de estado, fecha/hora y descripción expandible. Muestra `previousStatus` → `currentStatus` con badges de color semántico.
1611
+
1612
+ **Selector:** `lib-card-history`
1613
+
1614
+ **Inputs:**
1615
+
1616
+ - `DataCard: DataCard` – Datos de la entrada de historial:
1617
+
1618
+ ```ts
1619
+ export interface DataCard {
1620
+ title: string;
1621
+ time: string;
1622
+ date: string; // ISO 8601
1623
+ previousStatus?: any;
1624
+ currentStatus?: any;
1625
+ type: string;
1626
+ responsible?: string;
1627
+ description?: string;
1628
+ actionType?: 'create' | 'update' | 'delete';
1629
+ }
1630
+ ```
1631
+
1632
+ - `withResponsible: boolean = true` – Muestra u oculta el nombre del responsable.
1633
+
1634
+ **Badges de estado disponibles:**
1635
+
1636
+ | Valor normalizado | Badge |
1637
+ |---|---|
1638
+ | `activo` | Verde (badge-active) |
1639
+ | `inactivo` | Gris (badge-inactive) |
1640
+ | `eliminado` | Rojo oscuro (badge-retired) |
1641
+ | `obsoleto` | Amarillo (badge-obsolete) |
1642
+ | `operativo` | Verde (badge-operativo) |
1643
+ | `mantenimiento` | Naranja (badge-maintenance) |
1644
+ | `fallas` | Rojo (badge-failures) |
1645
+ | `baja` | Marrón (badge-deactivated) |
1646
+
1647
+ **Ejemplo de uso:**
1648
+
1649
+ ```html
1650
+ @for (entry of historial; track entry.date) {
1651
+ <lib-card-history [DataCard]="entry" [withResponsible]="true" />
1652
+ }
1653
+ ```
1654
+
1655
+ ---
1656
+
1657
+ ### 43. `lib-signature` (Signature)
1658
+
1659
+ **Qué hace**
1660
+ Componente de **bloc de firma manuscrita** basado en canvas (`signature_pad`). Permite dibujar, limpiar y guardar la firma como PNG en base64.
1661
+
1662
+ **Selector:** `lib-signature`
1663
+
1664
+ **Output:**
1665
+
1666
+ - `firmaSaved: OutputEmitterRef<string>` – Emite la firma como `data:image/png;base64,...` al llamar a "Guardar".
1667
+
1668
+ **API pública (acceso vía `@ViewChild`):**
1669
+
1670
+ | Método | Descripción |
1671
+ |---|---|
1672
+ | `limpiarFirma()` | Borra el canvas |
1673
+ | `guardarFirma()` | Emite `firmaSaved` si el canvas no está vacío |
1674
+ | `obtenerFirmaBase64(): string` | Retorna el PNG en base64 directamente |
1675
+ | `firmaVacia(): boolean` | Verifica si el canvas está vacío |
1676
+
1677
+ **Ejemplo de uso:**
1678
+
1679
+ ```html
1680
+ <lib-signature (firmaSaved)="onFirmaSaved($event)" />
1681
+ ```
1682
+
1683
+ ```ts
1684
+ onFirmaSaved(base64: string) {
1685
+ this.firmaBase64 = base64;
1686
+ }
1687
+ ```
1688
+
1689
+ ---
1690
+
1691
+ ### 44. `lib-geo-api-maps` (GeoAPIMaps)
1692
+
1693
+ **Qué hace**
1694
+ Mapa interactivo de **Google Maps** con soporte para dos tipos de marcadores: puntos de infracción/comparendo y cámaras de video. Muestra info-windows al hover y al clic, y hace auto-zoom para encuadrar todos los marcadores.
1695
+
1696
+ **Selector:** `lib-geo-api-maps`
1697
+
1698
+ **Requisito:** El script de Google Maps API debe estar cargado globalmente en el `index.html` del proyecto consumidor.
1699
+
1700
+ **Inputs:**
1701
+
1702
+ - `points: GeoPoint[] = []` – Puntos de infracción/comparendo.
1703
+ - `cameras: GeoPointCameras[] = []` – Cámaras con conteo de infracciones.
1704
+
1705
+ **Interfaces:**
1706
+
1707
+ ```ts
1708
+ export interface GeoPoint {
1709
+ subpoenaNumber: string;
1710
+ latitude: number;
1711
+ longitude: number;
1712
+ locationLabel: string;
1713
+ dateTime: string; // ISO 8601
1714
+ infractionCode: string;
1715
+ plate: string;
1716
+ immobilized: boolean; // Azul si false, rojo si true
1717
+ }
1718
+
1719
+ export interface GeoPointCameras {
1720
+ id: number;
1721
+ name: string;
1722
+ latitude: number;
1723
+ longitude: number;
1724
+ locationLabel: string;
1725
+ total: number;
1726
+ by_code: Record<string, number>; // { 'C01': 5, 'D02': 3 }
1727
+ }
1728
+ ```
1729
+
1730
+ **API pública (acceso vía `@ViewChild`):**
1731
+
1732
+ - `goToLocation(lat: number, lng: number)` – Mueve el mapa a la posición indicada con zoom 18.
1733
+
1734
+ **Ejemplo de uso:**
1735
+
1736
+ ```html
1737
+ <lib-geo-api-maps
1738
+ [points]="infracciones"
1739
+ [cameras]="camaras"
1740
+ />
1741
+ ```
1742
+
1743
+ ```ts
1744
+ infracciones: GeoPoint[] = [
1745
+ {
1746
+ subpoenaNumber: 'C-001',
1747
+ latitude: 10.9685,
1748
+ longitude: -74.7813,
1749
+ locationLabel: 'Cra 46 # 72-30',
1750
+ dateTime: '2025-05-20T10:30:00',
1751
+ infractionCode: 'C01',
1752
+ plate: 'ABC123',
1753
+ immobilized: false,
1754
+ }
1755
+ ];
1756
+ ```