sapenlinea-components 0.9.77 → 0.9.78

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.
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { model, input, signal, computed, Component, Injectable, inject, output, HostListener, ViewChildren, forwardRef, effect, ViewChild, ElementRef, booleanAttribute, DestroyRef, EventEmitter, Output, Input as Input$1, viewChildren, ChangeDetectionStrategy } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
- import { CommonModule, UpperCasePipe } from '@angular/common';
4
+ import { CommonModule, UpperCasePipe, NgClass } from '@angular/common';
5
5
  import * as i1 from '@angular/forms';
6
6
  import { NG_VALUE_ACCESSOR, ReactiveFormsModule, FormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
7
7
  import PubSub from 'pubsub-js';
@@ -1143,37 +1143,69 @@ class DateTimeFilter {
1143
1143
  isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
1144
1144
  isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
1145
1145
  dropdownDirection = signal('right', ...(ngDevMode ? [{ debugName: "dropdownDirection" }] : []));
1146
- // Máscara visual dinámica para la guía de fecha __/__/____
1146
+ // Máscara visual dinámica para la guía de fecha __/__/____ o __/__/____, __:__ __
1147
1147
  // Devuelve un arreglo de caracteres con flag "filled" para poder dar color distinto
1148
1148
  inputMask = computed(() => {
1149
1149
  const raw = this.inputTextValue() || '';
1150
1150
  const numbersOnly = raw.replace(/\D/g, '');
1151
+ const isDateTime = this.mode() === 'datetime';
1152
+ const ampmMatch = raw.toUpperCase().match(/[AP]M?/);
1153
+ const ampmStr = ampmMatch ? (ampmMatch[0].startsWith('P') ? 'PM' : 'AM') : 'AM';
1151
1154
  const template = [
1152
- { char: 'd', filled: false },
1153
- { char: 'd', filled: false },
1154
- { char: '/', filled: false },
1155
- { char: 'm', filled: false },
1156
- { char: 'm', filled: false },
1157
- { char: '/', filled: false },
1158
- { char: 'y', filled: false },
1159
- { char: 'y', filled: false },
1160
- { char: 'y', filled: false },
1161
- { char: 'y', filled: false },
1155
+ { char: 'd', filled: false }, // 0
1156
+ { char: 'd', filled: false }, // 1
1157
+ { char: '/', filled: false }, // 2
1158
+ { char: 'm', filled: false }, // 3
1159
+ { char: 'm', filled: false }, // 4
1160
+ { char: '/', filled: false }, // 5
1161
+ { char: 'y', filled: false }, // 6
1162
+ { char: 'y', filled: false }, // 7
1163
+ { char: 'y', filled: false }, // 8
1164
+ { char: 'y', filled: false }, // 9
1162
1165
  ];
1166
+ if (isDateTime) {
1167
+ template.push({ char: ',', filled: false }, // 10
1168
+ { char: ' ', filled: false }, // 11
1169
+ { char: 'h', filled: false }, // 12
1170
+ { char: 'h', filled: false }, // 13
1171
+ { char: ':', filled: false }, // 14
1172
+ { char: 'm', filled: false }, // 15
1173
+ { char: 'm', filled: false }, // 16
1174
+ { char: ' ', filled: false }, // 17
1175
+ { char: ampmStr[0], filled: false }, // 18
1176
+ { char: ampmStr[1], filled: false } // 19
1177
+ );
1178
+ }
1163
1179
  let index = 0;
1164
- for (let i = 0; i < template.length && index < numbersOnly.length; i++) {
1165
- if (template[i].char === '/')
1180
+ for (let i = 0; i < template.length; i++) {
1181
+ if (template[i].char === '/' || template[i].char === ',' || template[i].char === ' ' || template[i].char === ':')
1166
1182
  continue;
1167
- template[i] = { char: numbersOnly[index++], filled: true };
1168
- }
1169
- // Cuando se completa el segmento, el slash correspondiente pasa a "filled"
1170
- if (numbersOnly.length >= 2) {
1171
- template[2] = { char: '/', filled: true }; // después de DD
1183
+ if (isDateTime && (i === 18 || i === 19)) {
1184
+ if (numbersOnly.length >= 12) {
1185
+ template[i].filled = true;
1186
+ }
1187
+ continue;
1188
+ }
1189
+ if (index < numbersOnly.length) {
1190
+ template[i] = { char: numbersOnly[index++], filled: true };
1191
+ }
1172
1192
  }
1173
- if (numbersOnly.length >= 4) {
1174
- template[5] = { char: '/', filled: true }; // después de MM
1193
+ // Cuando se completa el segmento, el slash/separador correspondiente pasa a "filled"
1194
+ if (numbersOnly.length >= 2)
1195
+ template[2].filled = true;
1196
+ if (numbersOnly.length >= 4)
1197
+ template[5].filled = true;
1198
+ if (isDateTime) {
1199
+ if (numbersOnly.length >= 8) {
1200
+ template[10].filled = true;
1201
+ template[11].filled = true;
1202
+ }
1203
+ if (numbersOnly.length >= 10)
1204
+ template[14].filled = true;
1205
+ if (numbersOnly.length >= 12)
1206
+ template[17].filled = true;
1175
1207
  }
1176
- return template; // para usar en el template y colorear por carácter
1208
+ return template;
1177
1209
  }, ...(ngDevMode ? [{ debugName: "inputMask" }] : []));
1178
1210
  clearTrigger = input(0, ...(ngDevMode ? [{ debugName: "clearTrigger" }] : []));
1179
1211
  // Computed Properties based on active filter
@@ -1330,11 +1362,13 @@ class DateTimeFilter {
1330
1362
  return;
1331
1363
  const input = event.target;
1332
1364
  let value = input.value;
1333
- // Remove all non-numeric characters
1365
+ const isDateTime = this.mode() === 'datetime';
1366
+ // Remove all non-numeric characters for digits processing
1334
1367
  const numbersOnly = value.replace(/\D/g, '');
1335
- // Limit to 8 digits (DD/MM/YYYY)
1336
- const limitedNumbers = numbersOnly.slice(0, 8);
1337
- // Format with slashes: DD/MM/YYYY
1368
+ // Limit to 8 digits (DD/MM/YYYY) or 12 for datetime
1369
+ const maxDigits = isDateTime ? 12 : 8;
1370
+ const limitedNumbers = numbersOnly.slice(0, maxDigits);
1371
+ // Format string
1338
1372
  let formatted = '';
1339
1373
  if (limitedNumbers.length > 0) {
1340
1374
  formatted = limitedNumbers.slice(0, 2);
@@ -1344,13 +1378,30 @@ class DateTimeFilter {
1344
1378
  if (limitedNumbers.length > 4) {
1345
1379
  formatted += '/' + limitedNumbers.slice(4, 8);
1346
1380
  }
1381
+ if (isDateTime && limitedNumbers.length > 8) {
1382
+ formatted += ', ' + limitedNumbers.slice(8, 10);
1383
+ }
1384
+ if (isDateTime && limitedNumbers.length > 10) {
1385
+ formatted += ':' + limitedNumbers.slice(10, 12);
1386
+ }
1387
+ if (isDateTime && limitedNumbers.length === 12) {
1388
+ const lastChars = value.slice(-3).toUpperCase();
1389
+ let ampm = this.selectedAmPm();
1390
+ if (lastChars.includes('P'))
1391
+ ampm = 'PM';
1392
+ else if (lastChars.includes('A'))
1393
+ ampm = 'AM';
1394
+ this.selectedAmPm.set(ampm);
1395
+ formatted += ' ' + ampm;
1396
+ }
1347
1397
  }
1348
1398
  // Update the input value
1349
1399
  this.inputTextValue.set(formatted);
1350
1400
  input.value = formatted;
1351
1401
  this.markAsTouched();
1352
- // Only parse when we have a complete date (DD/MM/YYYY = 10 characters)
1353
- if (formatted.length === 10) {
1402
+ const completeLength = isDateTime ? (formatted.length >= 20 ? 12 : -1) : 10;
1403
+ const isComplete = isDateTime ? limitedNumbers.length === 12 : formatted.length === 10;
1404
+ if (isComplete) {
1354
1405
  const parsedDate = this.parseDateInput(formatted);
1355
1406
  if (parsedDate) {
1356
1407
  if (this.isDateDisabled(parsedDate)) {
@@ -1388,7 +1439,7 @@ class DateTimeFilter {
1388
1439
  if (!value || !value.includes('/'))
1389
1440
  return;
1390
1441
  // Determine which segment the cursor is in
1391
- // DD = 0..1, slash at 2, MM = 3..4, slash at 5, YYYY = 6..9
1442
+ const isDateTime = this.mode() === 'datetime';
1392
1443
  let start;
1393
1444
  let end;
1394
1445
  if (pos <= 2) {
@@ -1399,10 +1450,22 @@ class DateTimeFilter {
1399
1450
  start = 3;
1400
1451
  end = 5;
1401
1452
  }
1402
- else {
1453
+ else if (pos <= 10 || !isDateTime) {
1403
1454
  start = 6;
1404
1455
  end = 10;
1405
1456
  }
1457
+ else if (pos <= 14) {
1458
+ start = 12;
1459
+ end = 14;
1460
+ }
1461
+ else if (pos <= 17) {
1462
+ start = 15;
1463
+ end = 17;
1464
+ }
1465
+ else {
1466
+ start = 18;
1467
+ end = 20;
1468
+ }
1406
1469
  // Use setTimeout to override the browser's default selection behavior
1407
1470
  setTimeout(() => {
1408
1471
  input.setSelectionRange(start, end);
@@ -1433,23 +1496,37 @@ class DateTimeFilter {
1433
1496
  if (!value || !value.includes('/'))
1434
1497
  return;
1435
1498
  const pos = input.selectionStart ?? 0;
1436
- // Determine current segment: 0 = day, 1 = month, 2 = year
1499
+ const isDateTime = this.mode() === 'datetime';
1500
+ // Determine current segment
1437
1501
  let currentSegment;
1438
- if (pos <= 2) {
1502
+ if (pos <= 2)
1439
1503
  currentSegment = 0;
1440
- }
1441
- else if (pos <= 5) {
1504
+ else if (pos <= 5)
1442
1505
  currentSegment = 1;
1443
- }
1444
- else {
1506
+ else if (pos <= 10 || !isDateTime)
1445
1507
  currentSegment = 2;
1446
- }
1508
+ else if (pos <= 14)
1509
+ currentSegment = 3;
1510
+ else if (pos <= 17)
1511
+ currentSegment = 4;
1512
+ else
1513
+ currentSegment = 5;
1447
1514
  // Segment ranges
1448
- const segments = [
1449
- { start: 0, end: 2 }, // DD
1450
- { start: 3, end: 5 }, // MM
1451
- { start: 6, end: 10 }, // YYYY
1452
- ];
1515
+ const segments = isDateTime
1516
+ ? [
1517
+ { start: 0, end: 2 }, // DD
1518
+ { start: 3, end: 5 }, // MM
1519
+ { start: 6, end: 10 }, // YYYY
1520
+ { start: 12, end: 14 }, // HH
1521
+ { start: 15, end: 17 }, // MIN
1522
+ { start: 18, end: 20 }, // AMPM
1523
+ ]
1524
+ : [
1525
+ { start: 0, end: 2 }, // DD
1526
+ { start: 3, end: 5 }, // MM
1527
+ { start: 6, end: 10 }, // YYYY
1528
+ ];
1529
+ const numSegments = isDateTime ? 6 : 3;
1453
1530
  if (event.key === 'Tab') {
1454
1531
  if (event.shiftKey) {
1455
1532
  // Move to previous segment
@@ -1458,21 +1535,19 @@ class DateTimeFilter {
1458
1535
  const prev = segments[currentSegment - 1];
1459
1536
  setTimeout(() => input.setSelectionRange(prev.start, prev.end), 0);
1460
1537
  }
1461
- // If at first segment, let Tab work normally (move focus out)
1462
1538
  }
1463
1539
  else {
1464
1540
  // Move to next segment
1465
- if (currentSegment < 2) {
1541
+ if (currentSegment < numSegments - 1) {
1466
1542
  event.preventDefault();
1467
1543
  const next = segments[currentSegment + 1];
1468
1544
  setTimeout(() => input.setSelectionRange(next.start, next.end), 0);
1469
1545
  }
1470
- // If at last segment, let Tab work normally (move focus out)
1471
1546
  }
1472
1547
  return;
1473
1548
  }
1474
1549
  if (event.key === 'ArrowRight') {
1475
- if (currentSegment < 2) {
1550
+ if (currentSegment < numSegments - 1) {
1476
1551
  event.preventDefault();
1477
1552
  const next = segments[currentSegment + 1];
1478
1553
  setTimeout(() => input.setSelectionRange(next.start, next.end), 0);
@@ -1489,16 +1564,28 @@ class DateTimeFilter {
1489
1564
  }
1490
1565
  if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
1491
1566
  event.preventDefault();
1492
- // Parse current value
1493
- const match = value.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
1494
- if (!match)
1495
- return;
1496
- let day = parseInt(match[1], 10);
1497
- let month = parseInt(match[2], 10);
1498
- let year = parseInt(match[3], 10);
1567
+ let day = 1, month = 1, year = 2024, hour = 12, min = 0, ampm = 'AM';
1568
+ if (isDateTime) {
1569
+ const match = value.match(/^(\d{2})\/(\d{2})\/(\d{4}),\s(\d{2}):(\d{2})\s(AM|PM)$/i);
1570
+ if (!match)
1571
+ return;
1572
+ day = parseInt(match[1], 10);
1573
+ month = parseInt(match[2], 10);
1574
+ year = parseInt(match[3], 10);
1575
+ hour = parseInt(match[4], 10);
1576
+ min = parseInt(match[5], 10);
1577
+ ampm = match[6].toUpperCase();
1578
+ }
1579
+ else {
1580
+ const match = value.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
1581
+ if (!match)
1582
+ return;
1583
+ day = parseInt(match[1], 10);
1584
+ month = parseInt(match[2], 10);
1585
+ year = parseInt(match[3], 10);
1586
+ }
1499
1587
  const delta = event.key === 'ArrowUp' ? 1 : -1;
1500
1588
  if (currentSegment === 0) {
1501
- // Increment/decrement day
1502
1589
  day += delta;
1503
1590
  const maxDay = new Date(year, month, 0).getDate();
1504
1591
  if (day < 1)
@@ -1507,30 +1594,49 @@ class DateTimeFilter {
1507
1594
  day = 1;
1508
1595
  }
1509
1596
  else if (currentSegment === 1) {
1510
- // Increment/decrement month
1511
1597
  month += delta;
1512
1598
  if (month < 1)
1513
1599
  month = 12;
1514
1600
  if (month > 12)
1515
1601
  month = 1;
1516
- // Clamp day to valid range for new month
1517
1602
  const maxDay = new Date(year, month, 0).getDate();
1518
1603
  if (day > maxDay)
1519
1604
  day = maxDay;
1520
1605
  }
1521
- else {
1522
- // Increment/decrement year
1606
+ else if (currentSegment === 2) {
1523
1607
  year += delta;
1524
1608
  if (year < 1900)
1525
1609
  year = 1900;
1526
1610
  if (year > 2100)
1527
1611
  year = 2100;
1528
- // Clamp day (for leap year changes on Feb 29)
1529
1612
  const maxDay = new Date(year, month, 0).getDate();
1530
1613
  if (day > maxDay)
1531
1614
  day = maxDay;
1532
1615
  }
1533
- const newFormatted = `${day.toString().padStart(2, '0')}/${month.toString().padStart(2, '0')}/${year}`;
1616
+ else if (currentSegment === 3) {
1617
+ hour += delta;
1618
+ if (hour < 1)
1619
+ hour = 12;
1620
+ if (hour > 12)
1621
+ hour = 1;
1622
+ }
1623
+ else if (currentSegment === 4) {
1624
+ min += delta;
1625
+ if (min < 0)
1626
+ min = 59;
1627
+ if (min > 59)
1628
+ min = 0;
1629
+ }
1630
+ else if (currentSegment === 5) {
1631
+ ampm = ampm === 'AM' ? 'PM' : 'AM';
1632
+ }
1633
+ let newFormatted = '';
1634
+ if (isDateTime) {
1635
+ newFormatted = `${day.toString().padStart(2, '0')}/${month.toString().padStart(2, '0')}/${year}, ${hour.toString().padStart(2, '0')}:${min.toString().padStart(2, '0')} ${ampm}`;
1636
+ }
1637
+ else {
1638
+ newFormatted = `${day.toString().padStart(2, '0')}/${month.toString().padStart(2, '0')}/${year}`;
1639
+ }
1534
1640
  this.inputTextValue.set(newFormatted);
1535
1641
  input.value = newFormatted;
1536
1642
  // Parse and update if valid
@@ -1561,18 +1667,37 @@ class DateTimeFilter {
1561
1667
  parseDateInput(input) {
1562
1668
  if (!input || input.trim() === '')
1563
1669
  return null;
1564
- // Only accept DD/MM/YYYY format
1565
- const match = input.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
1566
- if (match) {
1567
- const day = parseInt(match[1], 10);
1568
- const month = parseInt(match[2], 10) - 1;
1569
- const year = parseInt(match[3], 10);
1570
- // Validate date
1571
- if (day >= 1 && day <= 31 && month >= 0 && month <= 11 && year >= 1900 && year <= 2100) {
1572
- const date = new Date(year, month, day);
1573
- // Check if date is valid (handles invalid dates like 31/02/2024)
1574
- if (date.getDate() === day && date.getMonth() === month && date.getFullYear() === year) {
1575
- return date;
1670
+ const isDateTime = this.mode() === 'datetime';
1671
+ if (isDateTime) {
1672
+ const match = input.trim().match(/^(\d{2})\/(\d{2})\/(\d{4}),\s(\d{2}):(\d{2})\s(AM|PM)$/i);
1673
+ if (match) {
1674
+ const day = parseInt(match[1], 10);
1675
+ const month = parseInt(match[2], 10) - 1;
1676
+ const year = parseInt(match[3], 10);
1677
+ const hour12 = parseInt(match[4], 10);
1678
+ const minute = parseInt(match[5], 10);
1679
+ const ampm = match[6].toUpperCase();
1680
+ if (day >= 1 && day <= 31 && month >= 0 && month <= 11 && year >= 1900 && year <= 2100 &&
1681
+ hour12 >= 1 && hour12 <= 12 && minute >= 0 && minute <= 59) {
1682
+ const hour24 = ampm === 'PM' ? (hour12 === 12 ? 12 : hour12 + 12) : (hour12 === 12 ? 0 : hour12);
1683
+ const date = new Date(year, month, day, hour24, minute);
1684
+ if (date.getDate() === day && date.getMonth() === month && date.getFullYear() === year) {
1685
+ return date;
1686
+ }
1687
+ }
1688
+ }
1689
+ }
1690
+ else {
1691
+ const match = input.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
1692
+ if (match) {
1693
+ const day = parseInt(match[1], 10);
1694
+ const month = parseInt(match[2], 10) - 1;
1695
+ const year = parseInt(match[3], 10);
1696
+ if (day >= 1 && day <= 31 && month >= 0 && month <= 11 && year >= 1900 && year <= 2100) {
1697
+ const date = new Date(year, month, day);
1698
+ if (date.getDate() === day && date.getMonth() === month && date.getFullYear() === year) {
1699
+ return date;
1700
+ }
1576
1701
  }
1577
1702
  }
1578
1703
  }
@@ -1640,6 +1765,15 @@ class DateTimeFilter {
1640
1765
  const day = date.getDate().toString().padStart(2, '0');
1641
1766
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
1642
1767
  const year = date.getFullYear();
1768
+ if (this.mode() === 'datetime') {
1769
+ let h = date.getHours();
1770
+ const m = date.getMinutes().toString().padStart(2, '0');
1771
+ const ampm = h >= 12 ? 'PM' : 'AM';
1772
+ h = h % 12;
1773
+ h = h ? h : 12;
1774
+ const hStr = h.toString().padStart(2, '0');
1775
+ return `${day}/${month}/${year}, ${hStr}:${m} ${ampm}`;
1776
+ }
1643
1777
  return `${day}/${month}/${year}`;
1644
1778
  }
1645
1779
  markAsTouched() {
@@ -1791,7 +1925,7 @@ class DateTimeFilter {
1791
1925
  useExisting: forwardRef(() => DateTimeFilter),
1792
1926
  multi: true,
1793
1927
  },
1794
- ], viewQueries: [{ propertyName: "chipRef", first: true, predicate: ["chip"], descendants: true }], ngImport: i0, template: "<div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip-input-wrapper\" #chip [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\">\r\n <!-- Etiqueta flotante -->\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || 'dd/mm/aaaa' }}</label>\r\n\r\n <!-- M\u00E1scara de gu\u00EDa de fecha din\u00E1mica (__/__/____) -->\r\n <div class=\"chip-input-mask\">\r\n @for (part of inputMask(); track $index) {\r\n <span class=\"mask-char\" [class.mask-char-filled]=\"part.filled\" [class.mask-char-placeholder]=\"!part.filled\">\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input type=\"text\" [value]=\"inputTextValue()\" (input)=\"onInputChange($event, item.value)\"\r\n (click)=\"onInputClick($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\" [placeholder]=\"item.placeholder || 'Seleccionar Fecha'\" class=\"chip-input\"\r\n [disabled]=\"isDisabled()\" (keydown)=\"onInputKeyDown($event, item.value)\" />\r\n\r\n <button type=\"button\" class=\"calendar-icon-button\" (click)=\"toggle(item.value)\" title=\"Abrir calendario\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path d=\"M4 5m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z\" />\r\n <path d=\"M16 3l0 4\" />\r\n <path d=\"M8 3l0 4\" />\r\n <path d=\"M4 11l16 0\" />\r\n <path d=\"M8 15h2v2h-2z\" />\r\n </svg>\r\n </button>\r\n\r\n @if (isOpen() && activeFilterType() === item.value) {\r\n <div class=\"dropdown\" [class.open-left]=\"dropdownDirection() === 'left'\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousYear()\" title=\"A\u00F1o anterior\">\r\n \u2039\u2039\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousMonth()\" title=\"Mes anterior\">\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">\r\n {{ monthName() }} {{ currentYear() }}\r\n </div>\r\n\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" title=\"Siguiente mes\">\r\n \u203A\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextYear()\" title=\"Siguiente a\u00F1o\">\r\n \u203A\u203A\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- D\u00EDas de la semana -->\r\n <div class=\"weekdays\">\r\n <div class=\"weekday\">Dom</div>\r\n <div class=\"weekday\">Lun</div>\r\n <div class=\"weekday\">Mar</div>\r\n <div class=\"weekday\">Mi\u00E9</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">S\u00E1b</div>\r\n </div>\r\n\r\n <!-- D\u00EDas -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div class=\"calendar-day\" [class.selected]=\"isDaySelected(day)\" [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\" [class.empty]=\"!day\" (click)=\"selectDay(day)\">\r\n {{ day || \"\" }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- TIME PICKER -->\r\n @if (mode() === 'datetime') {\r\n <div class=\"time-section\">\r\n <div class=\"time-header\">Horario</div>\r\n\r\n <div class=\"time-selectors\">\r\n <div class=\"time-group\">\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Hora</div>\r\n <div class=\"time-scroll\">\r\n @for (hour of hours12(); track hour.value) {\r\n <div class=\"time-option\" [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\">\r\n {{ hour.display }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-separator-vertical\">:</div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Min</div>\r\n <div class=\"time-scroll\">\r\n @for (minute of minutes(); track minute) {\r\n <div class=\"time-option\" [class.selected]=\"minute === selectedMinute()\" (click)=\"setMinute(minute)\">\r\n {{ minute.toString().padStart(2, \"0\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">AM/PM</div>\r\n <div class=\"time-scroll ampm\">\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'AM'\" (click)=\"setAmPm('AM')\">\r\n AM\r\n </div>\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'PM'\" (click)=\"setAmPm('PM')\">\r\n PM\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- botones -->\r\n <div class=\"action-buttons\">\r\n <button type=\"button\" class=\"action-btn secondary\" (click)=\"today()\">\r\n Hoy\r\n </button>\r\n\r\n @if (mode() === 'datetime') {\r\n <button type=\"button\" class=\"action-btn primary\" (click)=\"close()\">\r\n Aceptar\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [".datetime-container{position:relative;width:100%;overflow-x:clip}.filter-chips{display:flex;gap:10px;border-radius:12px;position:relative}.chip-input-wrapper{position:relative;display:flex;align-items:center;border-radius:8px;border-style:solid;border-color:var(--schemes-outline-variant, #c0c7cd);border-width:1px;min-width:80px;max-width:180px;height:32px;flex-shrink:0;transition:.2s ease;background-color:transparent}.chip-input-wrapper:hover{background-color:#ececcf}.chip-input-wrapper:focus-within,.chip-input-wrapper.active{color:var(--on-surface, #171c1f);border-color:#b6b69b}.floating-label{position:absolute;left:12px;top:-8px;color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:1.1rem;line-height:12px;letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);opacity:0;pointer-events:none;transition:all .2s ease;z-index:2;background-color:#e3e3d1;padding:0 4px;border-radius:2px;text-transform:capitalize}.chip-input-wrapper:focus-within .floating-label{opacity:.6;top:-8px}.chip-input-wrapper.has-value .floating-label{opacity:.9}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 8px;height:100%;width:100%;color:transparent;caret-color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 1.4rem);line-height:var(--theme-label-large-line-height, 20px);letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);border-radius:8px;position:relative;z-index:2}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6;text-transform:capitalize}.chip-input:disabled{cursor:not-allowed;opacity:.6}input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;box-shadow:0 0 0 1000px #e3e3d1 inset;-webkit-text-fill-color:#454733;caret-color:#454733;transition:background-color 9999s ease-in-out 0s}input:-moz-autofill,textarea:-moz-autofill{box-shadow:0 0 0 1000px #e3e3d1 inset}input[readonly]:-webkit-autofill,input:disabled:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;-webkit-text-fill-color:#a9a97f}.chip-input-mask{position:absolute;left:8px;right:40px;top:50%;transform:translateY(-50%);pointer-events:none;font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 14px);font-weight:var(--theme-label-large-font-weight, 500);z-index:1;display:flex;opacity:0;transition:opacity .2s ease}.chip-input-wrapper:focus-within .chip-input-mask,.chip-input-wrapper.has-value .chip-input-mask{opacity:1}.chip-input-wrapper:focus-within .chip-input::placeholder{opacity:0}.mask-char-placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.4}.mask-char-filled{color:var(--schemes-on-surface, #171c1f);opacity:1}.calendar-icon-button{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--schemes-on-surface-variant, #454733);border-radius:4px;transition:all .2s;z-index:3}.calendar-icon-button svg{width:18px;height:18px}.icon.icon-tabler-calendar-event{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.date-picker-container{margin-top:12px;width:100%;display:flex;justify-content:flex-start}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled{cursor:not-allowed;opacity:.6}.selected-text{color:#454733;font-size:1.3rem;flex:1}.selected-text.placeholder{color:#787861}.header-icons{display:flex;align-items:center;gap:8px}.clear-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:#787861;font-size:1.5rem;cursor:pointer;border-radius:50%;transition:all .2s}.clear-icon:hover{background-color:#7878611a;color:#454733}.arrow{width:15px;height:15px;background-image:url(\"data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:15px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{transform:rotate(180deg)}.dropdown{position:absolute;top:100%;left:0;background:#e3e3d1;border:1px solid #787861;border-top:none;border-radius:0 0 5px 5px;z-index:1000;box-shadow:0 4px 12px #00000026;min-width:400px}.dropdown.open-left{left:auto;right:0}.datetime-content{display:flex}.calendar-section{flex:1;min-width:280px}.calendar-nav{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid rgba(120,120,97,.2)}.nav-section{display:flex;gap:5px}.nav-btn{background:none;border:none;color:#787861;cursor:pointer;font-size:1.2rem;padding:5px 10px;border-radius:3px;transition:all .2s}.nav-btn:hover{background-color:#a9a97f1a;color:#454733}.current-date{font-weight:500;color:#454733;font-size:1.1rem}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);background:#7878611a}.weekday{padding:10px 5px;text-align:center;font-size:.9rem;font-weight:500;color:#787861}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.calendar-day{padding:12px 5px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;border-right:1px solid rgba(120,120,97,.1);border-bottom:1px solid rgba(120,120,97,.1);transition:all .2s}.calendar-day:hover:not(.disabled):not(.empty){background-color:#a9a97f33}.calendar-day.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.calendar-day.today:not(.selected){background-color:#a9a97f4d;font-weight:500}.calendar-day.disabled{color:#78786166;cursor:not-allowed}.calendar-day.empty{cursor:default}.calendar-day:nth-child(7n){border-right:none}.time-section{border-left:1px solid rgba(120,120,97,.2);min-width:140px;display:flex;flex-direction:column;background:#a9a97f0d}.time-header{padding:15px;border-bottom:1px solid rgba(120,120,97,.2);text-align:center;font-weight:500;color:#454733;background:#a9a97f1a}.time-selectors{display:flex;flex-direction:column;padding:15px;gap:20px;flex:1}.time-group{display:flex;align-items:center;gap:10px}.time-column{flex:1;display:flex;flex-direction:column;align-items:center}.time-label{font-size:.9rem;color:#787861;margin-bottom:10px;font-weight:500}.time-scroll{max-height:150px;overflow-y:auto;border:1px solid rgba(120,120,97,.2);border-radius:3px;width:50px;background:#a9a97f}.time-option{padding:8px 12px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;transition:all .2s}.time-option:hover{background-color:#a9a97f1a}.time-option.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.time-separator-vertical{font-size:1.5rem;color:#787861;font-weight:700;align-self:flex-end;margin-bottom:10px}.time-scroll::-webkit-scrollbar{width:4px}.time-scroll::-webkit-scrollbar-track{background:#7878611a}.time-scroll::-webkit-scrollbar-thumb{background:#787861;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#a9a97f}.action-buttons{display:flex;justify-content:space-between;padding:15px;border-top:1px solid rgba(120,120,97,.2);gap:10px}.action-btn{padding:10px 20px;border:none;border-radius:3px;cursor:pointer;font-size:1rem;transition:all .2s}.action-btn.secondary{background:transparent;color:#787861;border:1px solid #787861}.action-btn.secondary:hover{background:#7878611a;color:#454733}.action-btn.primary{background:#a9a97f;color:#e3e3d1;border:1px solid #a9a97f}.action-btn.primary:hover{background:#969669;border-color:#969669}@media (max-width: 768px){.dropdown{min-width:320px}.datetime-content{flex-direction:column}.time-section{border-left:none;border-top:1px solid rgba(120,120,97,.2)}.time-selectors{flex-direction:row;justify-content:center;padding:15px}.time-group{gap:15px}.datetime-header{padding:12px 15px}.calendar-nav{padding:12px}.calendar-day{padding:10px 3px;font-size:.9rem}.action-buttons{padding:12px}}@media (max-width: 480px){.dropdown{min-width:280px}.time-section{min-width:auto}.time-scroll{width:45px}.time-selectors{padding:10px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
1928
+ ], viewQueries: [{ propertyName: "chipRef", first: true, predicate: ["chip"], descendants: true }], ngImport: i0, template: "<div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip-input-wrapper\" #chip [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\">\r\n <!-- Etiqueta flotante -->\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || (item.type === 'datetime' ? 'dd/mm/aaaa, hh:mm AM/PM' : 'dd/mm/aaaa') }}</label>\r\n\r\n <!-- M\u00E1scara de gu\u00EDa de fecha din\u00E1mica (__/__/____) -->\r\n <div class=\"chip-input-mask\">\r\n @for (part of inputMask(); track $index) {\r\n <span class=\"mask-char\" [class.mask-char-filled]=\"part.filled\" [class.mask-char-placeholder]=\"!part.filled\">\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input type=\"text\" [value]=\"inputTextValue()\" (input)=\"onInputChange($event, item.value)\"\r\n (click)=\"onInputClick($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\" [placeholder]=\"item.placeholder || 'Seleccionar Fecha'\" class=\"chip-input\"\r\n [disabled]=\"isDisabled()\" (keydown)=\"onInputKeyDown($event, item.value)\" />\r\n\r\n <button type=\"button\" class=\"calendar-icon-button\" (click)=\"toggle(item.value)\" title=\"Abrir calendario\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path d=\"M4 5m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z\" />\r\n <path d=\"M16 3l0 4\" />\r\n <path d=\"M8 3l0 4\" />\r\n <path d=\"M4 11l16 0\" />\r\n <path d=\"M8 15h2v2h-2z\" />\r\n </svg>\r\n </button>\r\n\r\n @if (isOpen() && activeFilterType() === item.value) {\r\n <div class=\"dropdown\" [class.open-left]=\"dropdownDirection() === 'left'\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousYear()\" title=\"A\u00F1o anterior\">\r\n \u2039\u2039\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousMonth()\" title=\"Mes anterior\">\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">\r\n {{ monthName() }} {{ currentYear() }}\r\n </div>\r\n\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" title=\"Siguiente mes\">\r\n \u203A\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextYear()\" title=\"Siguiente a\u00F1o\">\r\n \u203A\u203A\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- D\u00EDas de la semana -->\r\n <div class=\"weekdays\">\r\n <div class=\"weekday\">Dom</div>\r\n <div class=\"weekday\">Lun</div>\r\n <div class=\"weekday\">Mar</div>\r\n <div class=\"weekday\">Mi\u00E9</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">S\u00E1b</div>\r\n </div>\r\n\r\n <!-- D\u00EDas -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div class=\"calendar-day\" [class.selected]=\"isDaySelected(day)\" [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\" [class.empty]=\"!day\" (click)=\"selectDay(day)\">\r\n {{ day || \"\" }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- TIME PICKER -->\r\n @if (mode() === 'datetime') {\r\n <div class=\"time-section\">\r\n <div class=\"time-header\">Horario</div>\r\n\r\n <div class=\"time-selectors\">\r\n <div class=\"time-group\">\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Hora</div>\r\n <div class=\"time-scroll\">\r\n @for (hour of hours12(); track hour.value) {\r\n <div class=\"time-option\" [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\">\r\n {{ hour.display }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-separator-vertical\">:</div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Min</div>\r\n <div class=\"time-scroll\">\r\n @for (minute of minutes(); track minute) {\r\n <div class=\"time-option\" [class.selected]=\"minute === selectedMinute()\" (click)=\"setMinute(minute)\">\r\n {{ minute.toString().padStart(2, \"0\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">AM/PM</div>\r\n <div class=\"time-scroll ampm\">\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'AM'\" (click)=\"setAmPm('AM')\">\r\n AM\r\n </div>\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'PM'\" (click)=\"setAmPm('PM')\">\r\n PM\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- botones -->\r\n <div class=\"action-buttons\">\r\n <button type=\"button\" class=\"action-btn secondary\" (click)=\"today()\">\r\n Hoy\r\n </button>\r\n\r\n @if (mode() === 'datetime') {\r\n <button type=\"button\" class=\"action-btn primary\" (click)=\"close()\">\r\n Aceptar\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [".datetime-container{position:relative;width:100%;overflow-x:clip}.filter-chips{display:flex;gap:10px;border-radius:12px;position:relative}.chip-input-wrapper{position:relative;display:flex;align-items:center;border-radius:8px;border-style:solid;border-color:var(--schemes-outline-variant, #c0c7cd);border-width:1px;min-width:80px;max-width:260px;height:32px;flex-shrink:0;transition:.2s ease;background-color:transparent}.chip-input-wrapper:hover{background-color:#ececcf}.chip-input-wrapper:focus-within,.chip-input-wrapper.active{color:var(--on-surface, #171c1f);border-color:#b6b69b}.floating-label{position:absolute;left:12px;top:-8px;color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:1.1rem;line-height:12px;letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);opacity:0;pointer-events:none;transition:all .2s ease;z-index:2;background-color:#e3e3d1;padding:0 4px;border-radius:2px;text-transform:capitalize}.chip-input-wrapper:focus-within .floating-label{opacity:.6;top:-8px}.chip-input-wrapper.has-value .floating-label{opacity:.9}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 8px;height:100%;width:100%;color:transparent;caret-color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 1.4rem);line-height:var(--theme-label-large-line-height, 20px);letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);border-radius:8px;position:relative;z-index:2}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6;text-transform:capitalize}.chip-input:disabled{cursor:not-allowed;opacity:.6}input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;box-shadow:0 0 0 1000px #e3e3d1 inset;-webkit-text-fill-color:#454733;caret-color:#454733;transition:background-color 9999s ease-in-out 0s}input:-moz-autofill,textarea:-moz-autofill{box-shadow:0 0 0 1000px #e3e3d1 inset}input[readonly]:-webkit-autofill,input:disabled:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;-webkit-text-fill-color:#a9a97f}.chip-input-mask{position:absolute;left:8px;right:40px;top:50%;transform:translateY(-50%);pointer-events:none;font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 14px);font-weight:var(--theme-label-large-font-weight, 500);z-index:1;display:flex;opacity:0;transition:opacity .2s ease}.chip-input-wrapper:focus-within .chip-input-mask,.chip-input-wrapper.has-value .chip-input-mask{opacity:1}.chip-input-wrapper:focus-within .chip-input::placeholder{opacity:0}.mask-char-placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.4}.mask-char-filled{color:var(--schemes-on-surface, #171c1f);opacity:1}.calendar-icon-button{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--schemes-on-surface-variant, #454733);border-radius:4px;transition:all .2s;z-index:3}.calendar-icon-button svg{width:18px;height:18px}.icon.icon-tabler-calendar-event{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.date-picker-container{margin-top:12px;width:100%;display:flex;justify-content:flex-start}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled{cursor:not-allowed;opacity:.6}.selected-text{color:#454733;font-size:1.3rem;flex:1}.selected-text.placeholder{color:#787861}.header-icons{display:flex;align-items:center;gap:8px}.clear-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:#787861;font-size:1.5rem;cursor:pointer;border-radius:50%;transition:all .2s}.clear-icon:hover{background-color:#7878611a;color:#454733}.arrow{width:15px;height:15px;background-image:url(\"data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:15px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{transform:rotate(180deg)}.dropdown{position:absolute;top:100%;left:0;background:#e3e3d1;border:1px solid #787861;border-top:none;border-radius:0 0 5px 5px;z-index:1000;box-shadow:0 4px 12px #00000026;min-width:400px}.dropdown.open-left{left:auto;right:0}.datetime-content{display:flex}.calendar-section{flex:1;min-width:280px}.calendar-nav{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid rgba(120,120,97,.2)}.nav-section{display:flex;gap:5px}.nav-btn{background:none;border:none;color:#787861;cursor:pointer;font-size:1.2rem;padding:5px 10px;border-radius:3px;transition:all .2s}.nav-btn:hover{background-color:#a9a97f1a;color:#454733}.current-date{font-weight:500;color:#454733;font-size:1.1rem}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);background:#7878611a}.weekday{padding:10px 5px;text-align:center;font-size:.9rem;font-weight:500;color:#787861}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.calendar-day{padding:12px 5px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;border-right:1px solid rgba(120,120,97,.1);border-bottom:1px solid rgba(120,120,97,.1);transition:all .2s}.calendar-day:hover:not(.disabled):not(.empty){background-color:#a9a97f33}.calendar-day.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.calendar-day.today:not(.selected){background-color:#a9a97f4d;font-weight:500}.calendar-day.disabled{color:#78786166;cursor:not-allowed}.calendar-day.empty{cursor:default}.calendar-day:nth-child(7n){border-right:none}.time-section{border-left:1px solid rgba(120,120,97,.2);min-width:140px;display:flex;flex-direction:column;background:#a9a97f0d}.time-header{padding:15px;border-bottom:1px solid rgba(120,120,97,.2);text-align:center;font-weight:500;color:#454733;background:#a9a97f1a}.time-selectors{display:flex;flex-direction:column;padding:15px;gap:20px;flex:1}.time-group{display:flex;align-items:center;gap:10px}.time-column{flex:1;display:flex;flex-direction:column;align-items:center}.time-label{font-size:.9rem;color:#787861;margin-bottom:10px;font-weight:500}.time-scroll{max-height:150px;overflow-y:auto;border:1px solid rgba(120,120,97,.2);border-radius:3px;width:50px;background:#a9a97f}.time-option{padding:8px 12px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;transition:all .2s}.time-option:hover{background-color:#a9a97f1a}.time-option.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.time-separator-vertical{font-size:1.5rem;color:#787861;font-weight:700;align-self:flex-end;margin-bottom:10px}.time-scroll::-webkit-scrollbar{width:4px}.time-scroll::-webkit-scrollbar-track{background:#7878611a}.time-scroll::-webkit-scrollbar-thumb{background:#787861;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#a9a97f}.action-buttons{display:flex;justify-content:space-between;padding:15px;border-top:1px solid rgba(120,120,97,.2);gap:10px}.action-btn{padding:10px 20px;border:none;border-radius:3px;cursor:pointer;font-size:1rem;transition:all .2s}.action-btn.secondary{background:transparent;color:#787861;border:1px solid #787861}.action-btn.secondary:hover{background:#7878611a;color:#454733}.action-btn.primary{background:#a9a97f;color:#e3e3d1;border:1px solid #a9a97f}.action-btn.primary:hover{background:#969669;border-color:#969669}@media (max-width: 768px){.dropdown{min-width:320px}.datetime-content{flex-direction:column}.time-section{border-left:none;border-top:1px solid rgba(120,120,97,.2)}.time-selectors{flex-direction:row;justify-content:center;padding:15px}.time-group{gap:15px}.datetime-header{padding:12px 15px}.calendar-nav{padding:12px}.calendar-day{padding:10px 3px;font-size:.9rem}.action-buttons{padding:12px}}@media (max-width: 480px){.dropdown{min-width:280px}.time-section{min-width:auto}.time-scroll{width:45px}.time-selectors{padding:10px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
1795
1929
  }
1796
1930
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DateTimeFilter, decorators: [{
1797
1931
  type: Component,
@@ -1801,7 +1935,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1801
1935
  useExisting: forwardRef(() => DateTimeFilter),
1802
1936
  multi: true,
1803
1937
  },
1804
- ], template: "<div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip-input-wrapper\" #chip [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\">\r\n <!-- Etiqueta flotante -->\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || 'dd/mm/aaaa' }}</label>\r\n\r\n <!-- M\u00E1scara de gu\u00EDa de fecha din\u00E1mica (__/__/____) -->\r\n <div class=\"chip-input-mask\">\r\n @for (part of inputMask(); track $index) {\r\n <span class=\"mask-char\" [class.mask-char-filled]=\"part.filled\" [class.mask-char-placeholder]=\"!part.filled\">\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input type=\"text\" [value]=\"inputTextValue()\" (input)=\"onInputChange($event, item.value)\"\r\n (click)=\"onInputClick($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\" [placeholder]=\"item.placeholder || 'Seleccionar Fecha'\" class=\"chip-input\"\r\n [disabled]=\"isDisabled()\" (keydown)=\"onInputKeyDown($event, item.value)\" />\r\n\r\n <button type=\"button\" class=\"calendar-icon-button\" (click)=\"toggle(item.value)\" title=\"Abrir calendario\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path d=\"M4 5m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z\" />\r\n <path d=\"M16 3l0 4\" />\r\n <path d=\"M8 3l0 4\" />\r\n <path d=\"M4 11l16 0\" />\r\n <path d=\"M8 15h2v2h-2z\" />\r\n </svg>\r\n </button>\r\n\r\n @if (isOpen() && activeFilterType() === item.value) {\r\n <div class=\"dropdown\" [class.open-left]=\"dropdownDirection() === 'left'\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousYear()\" title=\"A\u00F1o anterior\">\r\n \u2039\u2039\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousMonth()\" title=\"Mes anterior\">\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">\r\n {{ monthName() }} {{ currentYear() }}\r\n </div>\r\n\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" title=\"Siguiente mes\">\r\n \u203A\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextYear()\" title=\"Siguiente a\u00F1o\">\r\n \u203A\u203A\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- D\u00EDas de la semana -->\r\n <div class=\"weekdays\">\r\n <div class=\"weekday\">Dom</div>\r\n <div class=\"weekday\">Lun</div>\r\n <div class=\"weekday\">Mar</div>\r\n <div class=\"weekday\">Mi\u00E9</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">S\u00E1b</div>\r\n </div>\r\n\r\n <!-- D\u00EDas -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div class=\"calendar-day\" [class.selected]=\"isDaySelected(day)\" [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\" [class.empty]=\"!day\" (click)=\"selectDay(day)\">\r\n {{ day || \"\" }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- TIME PICKER -->\r\n @if (mode() === 'datetime') {\r\n <div class=\"time-section\">\r\n <div class=\"time-header\">Horario</div>\r\n\r\n <div class=\"time-selectors\">\r\n <div class=\"time-group\">\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Hora</div>\r\n <div class=\"time-scroll\">\r\n @for (hour of hours12(); track hour.value) {\r\n <div class=\"time-option\" [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\">\r\n {{ hour.display }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-separator-vertical\">:</div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Min</div>\r\n <div class=\"time-scroll\">\r\n @for (minute of minutes(); track minute) {\r\n <div class=\"time-option\" [class.selected]=\"minute === selectedMinute()\" (click)=\"setMinute(minute)\">\r\n {{ minute.toString().padStart(2, \"0\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">AM/PM</div>\r\n <div class=\"time-scroll ampm\">\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'AM'\" (click)=\"setAmPm('AM')\">\r\n AM\r\n </div>\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'PM'\" (click)=\"setAmPm('PM')\">\r\n PM\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- botones -->\r\n <div class=\"action-buttons\">\r\n <button type=\"button\" class=\"action-btn secondary\" (click)=\"today()\">\r\n Hoy\r\n </button>\r\n\r\n @if (mode() === 'datetime') {\r\n <button type=\"button\" class=\"action-btn primary\" (click)=\"close()\">\r\n Aceptar\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [".datetime-container{position:relative;width:100%;overflow-x:clip}.filter-chips{display:flex;gap:10px;border-radius:12px;position:relative}.chip-input-wrapper{position:relative;display:flex;align-items:center;border-radius:8px;border-style:solid;border-color:var(--schemes-outline-variant, #c0c7cd);border-width:1px;min-width:80px;max-width:180px;height:32px;flex-shrink:0;transition:.2s ease;background-color:transparent}.chip-input-wrapper:hover{background-color:#ececcf}.chip-input-wrapper:focus-within,.chip-input-wrapper.active{color:var(--on-surface, #171c1f);border-color:#b6b69b}.floating-label{position:absolute;left:12px;top:-8px;color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:1.1rem;line-height:12px;letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);opacity:0;pointer-events:none;transition:all .2s ease;z-index:2;background-color:#e3e3d1;padding:0 4px;border-radius:2px;text-transform:capitalize}.chip-input-wrapper:focus-within .floating-label{opacity:.6;top:-8px}.chip-input-wrapper.has-value .floating-label{opacity:.9}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 8px;height:100%;width:100%;color:transparent;caret-color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 1.4rem);line-height:var(--theme-label-large-line-height, 20px);letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);border-radius:8px;position:relative;z-index:2}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6;text-transform:capitalize}.chip-input:disabled{cursor:not-allowed;opacity:.6}input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;box-shadow:0 0 0 1000px #e3e3d1 inset;-webkit-text-fill-color:#454733;caret-color:#454733;transition:background-color 9999s ease-in-out 0s}input:-moz-autofill,textarea:-moz-autofill{box-shadow:0 0 0 1000px #e3e3d1 inset}input[readonly]:-webkit-autofill,input:disabled:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;-webkit-text-fill-color:#a9a97f}.chip-input-mask{position:absolute;left:8px;right:40px;top:50%;transform:translateY(-50%);pointer-events:none;font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 14px);font-weight:var(--theme-label-large-font-weight, 500);z-index:1;display:flex;opacity:0;transition:opacity .2s ease}.chip-input-wrapper:focus-within .chip-input-mask,.chip-input-wrapper.has-value .chip-input-mask{opacity:1}.chip-input-wrapper:focus-within .chip-input::placeholder{opacity:0}.mask-char-placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.4}.mask-char-filled{color:var(--schemes-on-surface, #171c1f);opacity:1}.calendar-icon-button{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--schemes-on-surface-variant, #454733);border-radius:4px;transition:all .2s;z-index:3}.calendar-icon-button svg{width:18px;height:18px}.icon.icon-tabler-calendar-event{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.date-picker-container{margin-top:12px;width:100%;display:flex;justify-content:flex-start}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled{cursor:not-allowed;opacity:.6}.selected-text{color:#454733;font-size:1.3rem;flex:1}.selected-text.placeholder{color:#787861}.header-icons{display:flex;align-items:center;gap:8px}.clear-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:#787861;font-size:1.5rem;cursor:pointer;border-radius:50%;transition:all .2s}.clear-icon:hover{background-color:#7878611a;color:#454733}.arrow{width:15px;height:15px;background-image:url(\"data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:15px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{transform:rotate(180deg)}.dropdown{position:absolute;top:100%;left:0;background:#e3e3d1;border:1px solid #787861;border-top:none;border-radius:0 0 5px 5px;z-index:1000;box-shadow:0 4px 12px #00000026;min-width:400px}.dropdown.open-left{left:auto;right:0}.datetime-content{display:flex}.calendar-section{flex:1;min-width:280px}.calendar-nav{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid rgba(120,120,97,.2)}.nav-section{display:flex;gap:5px}.nav-btn{background:none;border:none;color:#787861;cursor:pointer;font-size:1.2rem;padding:5px 10px;border-radius:3px;transition:all .2s}.nav-btn:hover{background-color:#a9a97f1a;color:#454733}.current-date{font-weight:500;color:#454733;font-size:1.1rem}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);background:#7878611a}.weekday{padding:10px 5px;text-align:center;font-size:.9rem;font-weight:500;color:#787861}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.calendar-day{padding:12px 5px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;border-right:1px solid rgba(120,120,97,.1);border-bottom:1px solid rgba(120,120,97,.1);transition:all .2s}.calendar-day:hover:not(.disabled):not(.empty){background-color:#a9a97f33}.calendar-day.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.calendar-day.today:not(.selected){background-color:#a9a97f4d;font-weight:500}.calendar-day.disabled{color:#78786166;cursor:not-allowed}.calendar-day.empty{cursor:default}.calendar-day:nth-child(7n){border-right:none}.time-section{border-left:1px solid rgba(120,120,97,.2);min-width:140px;display:flex;flex-direction:column;background:#a9a97f0d}.time-header{padding:15px;border-bottom:1px solid rgba(120,120,97,.2);text-align:center;font-weight:500;color:#454733;background:#a9a97f1a}.time-selectors{display:flex;flex-direction:column;padding:15px;gap:20px;flex:1}.time-group{display:flex;align-items:center;gap:10px}.time-column{flex:1;display:flex;flex-direction:column;align-items:center}.time-label{font-size:.9rem;color:#787861;margin-bottom:10px;font-weight:500}.time-scroll{max-height:150px;overflow-y:auto;border:1px solid rgba(120,120,97,.2);border-radius:3px;width:50px;background:#a9a97f}.time-option{padding:8px 12px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;transition:all .2s}.time-option:hover{background-color:#a9a97f1a}.time-option.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.time-separator-vertical{font-size:1.5rem;color:#787861;font-weight:700;align-self:flex-end;margin-bottom:10px}.time-scroll::-webkit-scrollbar{width:4px}.time-scroll::-webkit-scrollbar-track{background:#7878611a}.time-scroll::-webkit-scrollbar-thumb{background:#787861;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#a9a97f}.action-buttons{display:flex;justify-content:space-between;padding:15px;border-top:1px solid rgba(120,120,97,.2);gap:10px}.action-btn{padding:10px 20px;border:none;border-radius:3px;cursor:pointer;font-size:1rem;transition:all .2s}.action-btn.secondary{background:transparent;color:#787861;border:1px solid #787861}.action-btn.secondary:hover{background:#7878611a;color:#454733}.action-btn.primary{background:#a9a97f;color:#e3e3d1;border:1px solid #a9a97f}.action-btn.primary:hover{background:#969669;border-color:#969669}@media (max-width: 768px){.dropdown{min-width:320px}.datetime-content{flex-direction:column}.time-section{border-left:none;border-top:1px solid rgba(120,120,97,.2)}.time-selectors{flex-direction:row;justify-content:center;padding:15px}.time-group{gap:15px}.datetime-header{padding:12px 15px}.calendar-nav{padding:12px}.calendar-day{padding:10px 3px;font-size:.9rem}.action-buttons{padding:12px}}@media (max-width: 480px){.dropdown{min-width:280px}.time-section{min-width:auto}.time-scroll{width:45px}.time-selectors{padding:10px}}\n"] }]
1938
+ ], template: "<div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip-input-wrapper\" #chip [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\">\r\n <!-- Etiqueta flotante -->\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || (item.type === 'datetime' ? 'dd/mm/aaaa, hh:mm AM/PM' : 'dd/mm/aaaa') }}</label>\r\n\r\n <!-- M\u00E1scara de gu\u00EDa de fecha din\u00E1mica (__/__/____) -->\r\n <div class=\"chip-input-mask\">\r\n @for (part of inputMask(); track $index) {\r\n <span class=\"mask-char\" [class.mask-char-filled]=\"part.filled\" [class.mask-char-placeholder]=\"!part.filled\">\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input type=\"text\" [value]=\"inputTextValue()\" (input)=\"onInputChange($event, item.value)\"\r\n (click)=\"onInputClick($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\" [placeholder]=\"item.placeholder || 'Seleccionar Fecha'\" class=\"chip-input\"\r\n [disabled]=\"isDisabled()\" (keydown)=\"onInputKeyDown($event, item.value)\" />\r\n\r\n <button type=\"button\" class=\"calendar-icon-button\" (click)=\"toggle(item.value)\" title=\"Abrir calendario\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path d=\"M4 5m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z\" />\r\n <path d=\"M16 3l0 4\" />\r\n <path d=\"M8 3l0 4\" />\r\n <path d=\"M4 11l16 0\" />\r\n <path d=\"M8 15h2v2h-2z\" />\r\n </svg>\r\n </button>\r\n\r\n @if (isOpen() && activeFilterType() === item.value) {\r\n <div class=\"dropdown\" [class.open-left]=\"dropdownDirection() === 'left'\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousYear()\" title=\"A\u00F1o anterior\">\r\n \u2039\u2039\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"previousMonth()\" title=\"Mes anterior\">\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">\r\n {{ monthName() }} {{ currentYear() }}\r\n </div>\r\n\r\n <div class=\"nav-section\">\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth()\" title=\"Siguiente mes\">\r\n \u203A\r\n </button>\r\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextYear()\" title=\"Siguiente a\u00F1o\">\r\n \u203A\u203A\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- D\u00EDas de la semana -->\r\n <div class=\"weekdays\">\r\n <div class=\"weekday\">Dom</div>\r\n <div class=\"weekday\">Lun</div>\r\n <div class=\"weekday\">Mar</div>\r\n <div class=\"weekday\">Mi\u00E9</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">S\u00E1b</div>\r\n </div>\r\n\r\n <!-- D\u00EDas -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div class=\"calendar-day\" [class.selected]=\"isDaySelected(day)\" [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\" [class.empty]=\"!day\" (click)=\"selectDay(day)\">\r\n {{ day || \"\" }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- TIME PICKER -->\r\n @if (mode() === 'datetime') {\r\n <div class=\"time-section\">\r\n <div class=\"time-header\">Horario</div>\r\n\r\n <div class=\"time-selectors\">\r\n <div class=\"time-group\">\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Hora</div>\r\n <div class=\"time-scroll\">\r\n @for (hour of hours12(); track hour.value) {\r\n <div class=\"time-option\" [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\">\r\n {{ hour.display }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-separator-vertical\">:</div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Min</div>\r\n <div class=\"time-scroll\">\r\n @for (minute of minutes(); track minute) {\r\n <div class=\"time-option\" [class.selected]=\"minute === selectedMinute()\" (click)=\"setMinute(minute)\">\r\n {{ minute.toString().padStart(2, \"0\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">AM/PM</div>\r\n <div class=\"time-scroll ampm\">\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'AM'\" (click)=\"setAmPm('AM')\">\r\n AM\r\n </div>\r\n <div class=\"time-option\" [class.selected]=\"selectedAmPm() === 'PM'\" (click)=\"setAmPm('PM')\">\r\n PM\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- botones -->\r\n <div class=\"action-buttons\">\r\n <button type=\"button\" class=\"action-btn secondary\" (click)=\"today()\">\r\n Hoy\r\n </button>\r\n\r\n @if (mode() === 'datetime') {\r\n <button type=\"button\" class=\"action-btn primary\" (click)=\"close()\">\r\n Aceptar\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [".datetime-container{position:relative;width:100%;overflow-x:clip}.filter-chips{display:flex;gap:10px;border-radius:12px;position:relative}.chip-input-wrapper{position:relative;display:flex;align-items:center;border-radius:8px;border-style:solid;border-color:var(--schemes-outline-variant, #c0c7cd);border-width:1px;min-width:80px;max-width:260px;height:32px;flex-shrink:0;transition:.2s ease;background-color:transparent}.chip-input-wrapper:hover{background-color:#ececcf}.chip-input-wrapper:focus-within,.chip-input-wrapper.active{color:var(--on-surface, #171c1f);border-color:#b6b69b}.floating-label{position:absolute;left:12px;top:-8px;color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:1.1rem;line-height:12px;letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);opacity:0;pointer-events:none;transition:all .2s ease;z-index:2;background-color:#e3e3d1;padding:0 4px;border-radius:2px;text-transform:capitalize}.chip-input-wrapper:focus-within .floating-label{opacity:.6;top:-8px}.chip-input-wrapper.has-value .floating-label{opacity:.9}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 8px;height:100%;width:100%;color:transparent;caret-color:var(--schemes-on-surface-variant, #454733);font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 1.4rem);line-height:var(--theme-label-large-line-height, 20px);letter-spacing:var(--theme-label-large-letter-spacing, .1px);font-weight:var(--theme-label-large-font-weight, 500);border-radius:8px;position:relative;z-index:2}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6;text-transform:capitalize}.chip-input:disabled{cursor:not-allowed;opacity:.6}input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;box-shadow:0 0 0 1000px #e3e3d1 inset;-webkit-text-fill-color:#454733;caret-color:#454733;transition:background-color 9999s ease-in-out 0s}input:-moz-autofill,textarea:-moz-autofill{box-shadow:0 0 0 1000px #e3e3d1 inset}input[readonly]:-webkit-autofill,input:disabled:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #E3E3D1 inset;-webkit-text-fill-color:#a9a97f}.chip-input-mask{position:absolute;left:8px;right:40px;top:50%;transform:translateY(-50%);pointer-events:none;font-family:var( --theme-label-large-font-family, \"Roboto-Medium\", sans-serif );font-size:var(--theme-label-large-font-size, 14px);font-weight:var(--theme-label-large-font-weight, 500);z-index:1;display:flex;opacity:0;transition:opacity .2s ease}.chip-input-wrapper:focus-within .chip-input-mask,.chip-input-wrapper.has-value .chip-input-mask{opacity:1}.chip-input-wrapper:focus-within .chip-input::placeholder{opacity:0}.mask-char-placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.4}.mask-char-filled{color:var(--schemes-on-surface, #171c1f);opacity:1}.calendar-icon-button{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:var(--schemes-on-surface-variant, #454733);border-radius:4px;transition:all .2s;z-index:3}.calendar-icon-button svg{width:18px;height:18px}.icon.icon-tabler-calendar-event{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.date-picker-container{margin-top:12px;width:100%;display:flex;justify-content:flex-start}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled{cursor:not-allowed;opacity:.6}.selected-text{color:#454733;font-size:1.3rem;flex:1}.selected-text.placeholder{color:#787861}.header-icons{display:flex;align-items:center;gap:8px}.clear-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:#787861;font-size:1.5rem;cursor:pointer;border-radius:50%;transition:all .2s}.clear-icon:hover{background-color:#7878611a;color:#454733}.arrow{width:15px;height:15px;background-image:url(\"data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:15px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{transform:rotate(180deg)}.dropdown{position:absolute;top:100%;left:0;background:#e3e3d1;border:1px solid #787861;border-top:none;border-radius:0 0 5px 5px;z-index:1000;box-shadow:0 4px 12px #00000026;min-width:400px}.dropdown.open-left{left:auto;right:0}.datetime-content{display:flex}.calendar-section{flex:1;min-width:280px}.calendar-nav{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid rgba(120,120,97,.2)}.nav-section{display:flex;gap:5px}.nav-btn{background:none;border:none;color:#787861;cursor:pointer;font-size:1.2rem;padding:5px 10px;border-radius:3px;transition:all .2s}.nav-btn:hover{background-color:#a9a97f1a;color:#454733}.current-date{font-weight:500;color:#454733;font-size:1.1rem}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);background:#7878611a}.weekday{padding:10px 5px;text-align:center;font-size:.9rem;font-weight:500;color:#787861}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.calendar-day{padding:12px 5px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;border-right:1px solid rgba(120,120,97,.1);border-bottom:1px solid rgba(120,120,97,.1);transition:all .2s}.calendar-day:hover:not(.disabled):not(.empty){background-color:#a9a97f33}.calendar-day.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.calendar-day.today:not(.selected){background-color:#a9a97f4d;font-weight:500}.calendar-day.disabled{color:#78786166;cursor:not-allowed}.calendar-day.empty{cursor:default}.calendar-day:nth-child(7n){border-right:none}.time-section{border-left:1px solid rgba(120,120,97,.2);min-width:140px;display:flex;flex-direction:column;background:#a9a97f0d}.time-header{padding:15px;border-bottom:1px solid rgba(120,120,97,.2);text-align:center;font-weight:500;color:#454733;background:#a9a97f1a}.time-selectors{display:flex;flex-direction:column;padding:15px;gap:20px;flex:1}.time-group{display:flex;align-items:center;gap:10px}.time-column{flex:1;display:flex;flex-direction:column;align-items:center}.time-label{font-size:.9rem;color:#787861;margin-bottom:10px;font-weight:500}.time-scroll{max-height:150px;overflow-y:auto;border:1px solid rgba(120,120,97,.2);border-radius:3px;width:50px;background:#a9a97f}.time-option{padding:8px 12px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;transition:all .2s}.time-option:hover{background-color:#a9a97f1a}.time-option.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.time-separator-vertical{font-size:1.5rem;color:#787861;font-weight:700;align-self:flex-end;margin-bottom:10px}.time-scroll::-webkit-scrollbar{width:4px}.time-scroll::-webkit-scrollbar-track{background:#7878611a}.time-scroll::-webkit-scrollbar-thumb{background:#787861;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#a9a97f}.action-buttons{display:flex;justify-content:space-between;padding:15px;border-top:1px solid rgba(120,120,97,.2);gap:10px}.action-btn{padding:10px 20px;border:none;border-radius:3px;cursor:pointer;font-size:1rem;transition:all .2s}.action-btn.secondary{background:transparent;color:#787861;border:1px solid #787861}.action-btn.secondary:hover{background:#7878611a;color:#454733}.action-btn.primary{background:#a9a97f;color:#e3e3d1;border:1px solid #a9a97f}.action-btn.primary:hover{background:#969669;border-color:#969669}@media (max-width: 768px){.dropdown{min-width:320px}.datetime-content{flex-direction:column}.time-section{border-left:none;border-top:1px solid rgba(120,120,97,.2)}.time-selectors{flex-direction:row;justify-content:center;padding:15px}.time-group{gap:15px}.datetime-header{padding:12px 15px}.calendar-nav{padding:12px}.calendar-day{padding:10px 3px;font-size:.9rem}.action-buttons{padding:12px}}@media (max-width: 480px){.dropdown{min-width:280px}.time-section{min-width:auto}.time-scroll{width:45px}.time-selectors{padding:10px}}\n"] }]
1805
1939
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { chipRef: [{
1806
1940
  type: ViewChild,
1807
1941
  args: ['chip']
@@ -6205,6 +6339,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6205
6339
  args: [{ selector: 'lib-document-upload', standalone: true, imports: [], template: "<div class=\"upload-container\" (dragover)=\"onDragOver($event)\" (dragleave)=\"onDragLeave()\" (drop)=\"onDrop($event)\"\r\n [class.dragging]=\"isDragging()\">\r\n\r\n <input type=\"file\" #fileInput [accept]=\"accept()\" [multiple]=\"multiple()\" (change)=\"onFileSelect($event)\" hidden />\r\n\r\n <div class=\"upload-zone\" (click)=\"fileInput.click()\">\r\n <svg class=\"upload-icon\" viewBox=\"0 0 486.3 486.3\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g>\r\n <path d=\"M395.5,135.8c-5.2-30.9-20.5-59.1-43.9-80.5c-26-23.8-59.8-36.9-95-36.9c-27.2,0-53.7,7.8-76.4,22.5 c-18.9,12.2-34.6,28.7-45.7,48.1c-4.8-0.9-9.8-1.4-14.8-1.4c-42.5,0-77.1,34.6-77.1,77.1c0,5.5,0.6,10.8,1.6,16 C16.7,200.7,0,232.9,0,267.2c0,27.7,10.3,54.6,29.1,75.9c19.3,21.8,44.8,34.7,72,36.2c0.3,0,0.5,0,0.8,0h86 c7.5,0,13.5-6,13.5-13.5s-6-13.5-13.5-13.5h-85.6C61.4,349.8,27,310.9,27,267.1c0-28.3,15.2-54.7,39.7-69 c5.7-3.3,8.1-10.2,5.9-16.4c-2-5.4-3-11.1-3-17.2c0-27.6,22.5-50.1,50.1-50.1c5.9,0,11.7,1,17.1,3c6.6,2.4,13.9-0.6,16.9-6.9 c18.7-39.7,59.1-65.3,103-65.3c59,0,107.7,44.2,113.3,102.8c0.6,6.1,5.2,11,11.2,12c44.5,7.6,78.1,48.7,78.1,95.6 c0,49.7-39.1,92.9-87.3,96.6h-73.7c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5h74.2c0.3,0,0.6,0,1,0c30.5-2.2,59-16.2,80.2-39.6 c21.1-23.2,32.6-53,32.6-84C486.2,199.5,447.9,149.6,395.5,135.8z\"/>\r\n <path d=\"M324.2,280c5.3-5.3,5.3-13.8,0-19.1l-71.5-71.5c-2.5-2.5-6-4-9.5-4s-7,1.4-9.5,4l-71.5,71.5c-5.3,5.3-5.3,13.8,0,19.1 c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4l48.5-48.5v222.9c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5V231.5l48.5,48.5 C310.4,285.3,318.9,285.3,324.2,280z\"/>\r\n </g>\r\n </svg>\r\n <p class=\"upload-label\"><strong>{{ label() }}</strong></p>\r\n <small class=\"upload-helper\">{{ helperText() }}</small>\r\n </div>\r\n\r\n @if (files().length > 0) {\r\n <div class=\"files-row\">\r\n @for (file of files(); track file.name) {\r\n <div class=\"file-card\">\r\n <button type=\"button\" class=\"file-card-remove\" (click)=\"removeFile(file)\" title=\"Eliminar archivo\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <svg class=\"file-card-icon\" viewBox=\"0 0 64 64\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M12 4 L12 60 L52 60 L52 20 L36 4 Z\" fill=\"#e3e3d1\" stroke=\"#8a9a2f\" stroke-width=\"2.5\" stroke-linejoin=\"round\"/>\r\n <path d=\"M36 4 L36 20 L52 20\" fill=\"none\" stroke=\"#8a9a2f\" stroke-width=\"2.5\" stroke-linejoin=\"round\"/>\r\n <rect x=\"20\" y=\"30\" width=\"24\" height=\"2.5\" rx=\"1.25\" fill=\"#8a9a2f\"/>\r\n <rect x=\"20\" y=\"37\" width=\"24\" height=\"2.5\" rx=\"1.25\" fill=\"#8a9a2f\"/>\r\n <rect x=\"20\" y=\"44\" width=\"16\" height=\"2.5\" rx=\"1.25\" fill=\"#8a9a2f\"/>\r\n </svg>\r\n <span class=\"file-card-ext\">{{ getFileExtension(file) }}</span>\r\n <span class=\"file-card-name\" [title]=\"file.name\">{{ file.name }}</span>\r\n <span class=\"file-card-size\">{{ formatSize(file.size) }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [".upload-container{display:flex;flex-direction:column;gap:16px}.upload-zone{border:2px dashed #8a9a2f;border-radius:8px;padding:48px;text-align:center;cursor:pointer;background-color:#f5f7e8;transition:background .2s}.upload-zone:hover,.dragging .upload-zone{background-color:#eaeecc}.upload-icon{width:56px;height:56px;fill:#8a9a2f;display:block;margin:0 auto 12px}.upload-label{font-size:1.4rem;color:#454733;margin:0 0 6px}.upload-helper{font-size:1.2rem;color:#8a9a2f}.files-row{display:flex;flex-direction:row;gap:12px;overflow-x:auto;padding:4px 2px 8px;scrollbar-width:thin;scrollbar-color:#8a9a2f #f0f0e0}.files-row::-webkit-scrollbar{height:6px}.files-row::-webkit-scrollbar-track{background:#f0f0e0;border-radius:3px}.files-row::-webkit-scrollbar-thumb{background:#8a9a2f;border-radius:3px}.file-card{position:relative;flex-shrink:0;width:132px;height:140px;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:4px;padding:10px 10px 12px;border:1px solid #c5c9a0;border-radius:10px;background-color:#f5f7e8;transition:border-color .2s,background .2s;overflow:hidden}.file-card:hover{border-color:#8a9a2f;background-color:#eaeecc}.file-card-icon{width:52px;height:52px;flex-shrink:0;margin-bottom:2px}.file-card-ext{font-size:1rem;font-weight:700;color:#8a9a2f;letter-spacing:.04em;line-height:1}.file-card-name{width:100%;font-size:1.1rem;color:#454733;text-align:center;overflow:hidden;display:-webkit-box;line-clamp:2;-webkit-box-orient:vertical;line-height:1.3;word-break:break-all}.file-card-size{font-size:1rem;color:#8a9a6e;line-height:1}.file-card-remove{position:absolute;top:6px;right:6px;width:22px;height:22px;display:flex;align-items:center;justify-content:center;background:#ffffffd9;border:1px solid #c5c9a0;border-radius:50%;cursor:pointer;color:#787861;padding:0;transition:background .15s,color .15s,border-color .15s;line-height:1}.file-card-remove:hover{background:#c33;border-color:#c33;color:#fff}.file-card-remove svg{width:12px;height:12px}\n"] }]
6206
6340
  }], propDecorators: { filesChanged: [{ type: i0.Output, args: ["filesChanged"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxSizeMB: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSizeMB", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }] } });
6207
6341
 
6342
+ class CardHistory {
6343
+ DataCard = input(...(ngDevMode ? [undefined, { debugName: "DataCard" }] : []));
6344
+ isExpanded = signal(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
6345
+ months = [
6346
+ 'enero',
6347
+ 'febrero',
6348
+ 'marzo',
6349
+ 'abril',
6350
+ 'mayo',
6351
+ 'junio',
6352
+ 'julio',
6353
+ 'agosto',
6354
+ 'septiembre',
6355
+ 'octubre',
6356
+ 'noviembre',
6357
+ 'diciembre',
6358
+ ];
6359
+ toggleExpanded() {
6360
+ this.isExpanded.set(!this.isExpanded());
6361
+ }
6362
+ formatDate(isoDate) {
6363
+ const date = new Date(isoDate);
6364
+ const day = date.getDate();
6365
+ const month = this.months[date.getMonth()];
6366
+ const year = date.getFullYear();
6367
+ return `${day} ${month} ${year}`;
6368
+ }
6369
+ // getBadgeClass(status: string): string {
6370
+ // const statusLower = status.toLowerCase();
6371
+ // if (statusLower.includes('operativo') || statusLower.includes('operacional')) {
6372
+ // return 'badge-operational';
6373
+ // } else if (statusLower.includes('mantenimiento')) {
6374
+ // return 'badge-maintenance';
6375
+ // } else if (statusLower.includes('sin ficha') || statusLower.includes('sin fecha')) {
6376
+ // return 'badge-no-date';
6377
+ // }
6378
+ // return 'badge-operational';
6379
+ // }
6380
+ statusData = {
6381
+ activo: { label: 'Activo', class: 'badge-active' },
6382
+ inactivo: { label: 'Inactivo', class: 'badge-inactive' },
6383
+ eliminado: { label: 'Eliminado', class: 'badge-retired' },
6384
+ obsoleto: { label: 'Obsoleto', class: 'badge-obsolete' },
6385
+ operativo: { label: 'Operativo', class: 'badge-operativo' },
6386
+ mantenimiento: { label: 'En mantenimiento', class: 'badge-maintenance' },
6387
+ fallas: { label: 'Con fallas', class: 'badge-failures' },
6388
+ baja: { label: 'Dado de baja', class: 'badge-deactivated' },
6389
+ default: { label: 'Desconocido', class: 'badge-default' },
6390
+ };
6391
+ getBadgeClass(status) {
6392
+ const normalizedStatus = status?.toLowerCase().trim();
6393
+ return this.statusData[normalizedStatus]?.class ?? this.statusData['default'].class;
6394
+ }
6395
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CardHistory, deps: [], target: i0.ɵɵFactoryTarget.Component });
6396
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: CardHistory, isStandalone: true, selector: "lib-card-history", inputs: { DataCard: { classPropertyName: "DataCard", publicName: "DataCard", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"card-history\">\r\n <span class=\"card-date\">{{ formatDate(DataCard()?.date || \"\") }}</span>\r\n <div class=\"event-card\" [class.expanded]=\"isExpanded()\">\r\n <div class=\"event-header\" (click)=\"toggleExpanded()\">\r\n <div class=\"event-info\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"expand-icon icon icon-tabler icons-tabler-outline icon-tabler-chevron-up\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M6 15l6 -6l6 6\" />\r\n </svg>\r\n <span class=\"event-type\">{{ DataCard()?.title }}</span>\r\n <span class=\"event-time\">{{ DataCard()?.time }}</span>\r\n </div>\r\n <div class=\"status-badges\">\r\n <span\r\n class=\"badge\"\r\n [ngClass]=\"getBadgeClass(DataCard()?.previousStatus || '')\"\r\n >\r\n {{ DataCard()?.previousStatus }}\r\n </span>\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-chevrons-right\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M7 7l5 5l-5 5\" />\r\n <path d=\"M13 7l5 5l-5 5\" />\r\n </svg>\r\n\r\n <span\r\n class=\"badge\"\r\n [ngClass]=\"getBadgeClass(DataCard()?.currentStatus || '')\"\r\n >\r\n {{ DataCard()?.currentStatus }}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"event-details\">\r\n <div class=\"responsible-info\">\r\n <div class=\"avatar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-user\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0\" />\r\n <path d=\"M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2\" />\r\n </svg>\r\n </div>\r\n <div class=\"responsible-details\">\r\n <h4>Responsable</h4>\r\n <div class=\"responsible-name\">{{ DataCard()?.responsible }}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"technical-description\">\r\n <div class=\"tech-label\">Descripci\u00F3n t\u00E9cnica</div>\r\n <div class=\"tech-content\">\r\n {{ DataCard()?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".card-history{display:flex;flex-direction:column;gap:15px}.card-date{color:#1c1c12;font-size:1.4rem;font-weight:600}.event-card{background-color:#f0f0db;border-radius:8px;margin-bottom:15px;overflow:hidden;border:1px solid #c7c7ad}.event-header{padding:12px 16px;display:flex;align-items:center;justify-content:space-between;cursor:pointer}.event-header:hover{background-color:#e0e0c8}.event-info{display:flex;align-items:center;gap:8px}.expand-icon{font-size:12px;transform:rotate(180deg);transition:transform .2s}.event-card.expanded .expand-icon{transform:rotate(90deg)}.event-type{font-weight:600;font-size:1.4rem;color:#1c1c12}.event-time{color:#454733;font-size:1.1rem}.status-badges{display:flex;align-items:center;gap:8px}.badge{padding:6px 10px;border-radius:6px;font-size:1.2rem;font-weight:600;border:none}.badge-maintenance{background:#bfd100;color:#4f5700}.badge-operational{background-color:#78db5c;color:#0f5e00}.badge-no-date{background-color:#bfe9ff;color:#004d65}.event-details{max-height:0;overflow:hidden;padding:0 10px;background-color:#f0f0e0;transition:max-height .3s ease-in-out,padding .3s ease-in-out}.event-card.expanded .event-details{max-height:300px;padding:20px 10px}.responsible-info{display:flex;align-items:center;gap:12px;margin-bottom:15px;padding:20px 10px;background-color:#ebe8d6;border-radius:8px}.avatar{width:36px;height:36px;border-radius:50%;background-color:#bfd100;display:flex;align-items:center;justify-content:center;font-weight:700}.avatar img{width:24px;height:24px}.responsible-details h4{font-size:1.2rem;color:#454733;margin-bottom:2px;font-weight:400}.responsible-name{font-size:1.4rem;font-weight:600;color:#1c1c12}.technical-description{padding:20px 10px;background-color:#ebe8d6;border-radius:8px;height:120px}.tech-label{font-size:1.2rem;color:#454733;margin-bottom:5px}.tech-content{font-size:1.4rem;color:#1c1c12;font-weight:600}.badge-active{color:#006d2f;font-weight:600;background-color:#c6f6c1;border-radius:8px;padding:6px 10px}.badge-inactive{color:#454733e7;font-weight:600;background-color:#e0e0e0;border-radius:8px;padding:6px 10px}.badge-retired{color:#ba1a1a;font-weight:600;background-color:#ffe5e5;border-radius:8px;padding:6px 10px}.badge-obsolete{color:#454733;font-weight:600;border:1px solid #c7c7ad;border-radius:8px;padding:6px 10px}.badge-operativo{color:#0f5e00;font-weight:600;background-color:#80ff66;border-radius:8px;padding:6px 10px}.badge-maintenance{color:#4f5700;font-weight:600;background-color:#bfd100;border-radius:8px;padding:6px 10px}.badge-failures{color:#94000a;font-weight:600;background-color:#fcd;border-radius:8px;padding:6px 10px}.badge-deactivated{color:#ba1a1a;font-weight:600;border:1px solid #ba1a1a;border-radius:8px;padding:6px 10px}.badge-default{color:#6b6b47;font-weight:600;border:1px dashed #c7c7ad;border-radius:8px;padding:6px 10px;font-style:italic}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
6397
+ }
6398
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CardHistory, decorators: [{
6399
+ type: Component,
6400
+ args: [{ selector: 'lib-card-history', imports: [NgClass], template: "<div class=\"card-history\">\r\n <span class=\"card-date\">{{ formatDate(DataCard()?.date || \"\") }}</span>\r\n <div class=\"event-card\" [class.expanded]=\"isExpanded()\">\r\n <div class=\"event-header\" (click)=\"toggleExpanded()\">\r\n <div class=\"event-info\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"expand-icon icon icon-tabler icons-tabler-outline icon-tabler-chevron-up\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M6 15l6 -6l6 6\" />\r\n </svg>\r\n <span class=\"event-type\">{{ DataCard()?.title }}</span>\r\n <span class=\"event-time\">{{ DataCard()?.time }}</span>\r\n </div>\r\n <div class=\"status-badges\">\r\n <span\r\n class=\"badge\"\r\n [ngClass]=\"getBadgeClass(DataCard()?.previousStatus || '')\"\r\n >\r\n {{ DataCard()?.previousStatus }}\r\n </span>\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-chevrons-right\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M7 7l5 5l-5 5\" />\r\n <path d=\"M13 7l5 5l-5 5\" />\r\n </svg>\r\n\r\n <span\r\n class=\"badge\"\r\n [ngClass]=\"getBadgeClass(DataCard()?.currentStatus || '')\"\r\n >\r\n {{ DataCard()?.currentStatus }}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"event-details\">\r\n <div class=\"responsible-info\">\r\n <div class=\"avatar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-user\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0\" />\r\n <path d=\"M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2\" />\r\n </svg>\r\n </div>\r\n <div class=\"responsible-details\">\r\n <h4>Responsable</h4>\r\n <div class=\"responsible-name\">{{ DataCard()?.responsible }}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"technical-description\">\r\n <div class=\"tech-label\">Descripci\u00F3n t\u00E9cnica</div>\r\n <div class=\"tech-content\">\r\n {{ DataCard()?.description }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".card-history{display:flex;flex-direction:column;gap:15px}.card-date{color:#1c1c12;font-size:1.4rem;font-weight:600}.event-card{background-color:#f0f0db;border-radius:8px;margin-bottom:15px;overflow:hidden;border:1px solid #c7c7ad}.event-header{padding:12px 16px;display:flex;align-items:center;justify-content:space-between;cursor:pointer}.event-header:hover{background-color:#e0e0c8}.event-info{display:flex;align-items:center;gap:8px}.expand-icon{font-size:12px;transform:rotate(180deg);transition:transform .2s}.event-card.expanded .expand-icon{transform:rotate(90deg)}.event-type{font-weight:600;font-size:1.4rem;color:#1c1c12}.event-time{color:#454733;font-size:1.1rem}.status-badges{display:flex;align-items:center;gap:8px}.badge{padding:6px 10px;border-radius:6px;font-size:1.2rem;font-weight:600;border:none}.badge-maintenance{background:#bfd100;color:#4f5700}.badge-operational{background-color:#78db5c;color:#0f5e00}.badge-no-date{background-color:#bfe9ff;color:#004d65}.event-details{max-height:0;overflow:hidden;padding:0 10px;background-color:#f0f0e0;transition:max-height .3s ease-in-out,padding .3s ease-in-out}.event-card.expanded .event-details{max-height:300px;padding:20px 10px}.responsible-info{display:flex;align-items:center;gap:12px;margin-bottom:15px;padding:20px 10px;background-color:#ebe8d6;border-radius:8px}.avatar{width:36px;height:36px;border-radius:50%;background-color:#bfd100;display:flex;align-items:center;justify-content:center;font-weight:700}.avatar img{width:24px;height:24px}.responsible-details h4{font-size:1.2rem;color:#454733;margin-bottom:2px;font-weight:400}.responsible-name{font-size:1.4rem;font-weight:600;color:#1c1c12}.technical-description{padding:20px 10px;background-color:#ebe8d6;border-radius:8px;height:120px}.tech-label{font-size:1.2rem;color:#454733;margin-bottom:5px}.tech-content{font-size:1.4rem;color:#1c1c12;font-weight:600}.badge-active{color:#006d2f;font-weight:600;background-color:#c6f6c1;border-radius:8px;padding:6px 10px}.badge-inactive{color:#454733e7;font-weight:600;background-color:#e0e0e0;border-radius:8px;padding:6px 10px}.badge-retired{color:#ba1a1a;font-weight:600;background-color:#ffe5e5;border-radius:8px;padding:6px 10px}.badge-obsolete{color:#454733;font-weight:600;border:1px solid #c7c7ad;border-radius:8px;padding:6px 10px}.badge-operativo{color:#0f5e00;font-weight:600;background-color:#80ff66;border-radius:8px;padding:6px 10px}.badge-maintenance{color:#4f5700;font-weight:600;background-color:#bfd100;border-radius:8px;padding:6px 10px}.badge-failures{color:#94000a;font-weight:600;background-color:#fcd;border-radius:8px;padding:6px 10px}.badge-deactivated{color:#ba1a1a;font-weight:600;border:1px solid #ba1a1a;border-radius:8px;padding:6px 10px}.badge-default{color:#6b6b47;font-weight:600;border:1px dashed #c7c7ad;border-radius:8px;padding:6px 10px;font-style:italic}\n"] }]
6401
+ }], propDecorators: { DataCard: [{ type: i0.Input, args: [{ isSignal: true, alias: "DataCard", required: false }] }] } });
6402
+
6208
6403
  // src/app/components/public-api.ts
6209
6404
  // Exportar los componentes
6210
6405
 
@@ -6212,5 +6407,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6212
6407
  * Generated bundle index. Do not edit.
6213
6408
  */
6214
6409
 
6215
- export { BarChart, BaseChart, Button, ButtonCards, CARD_BG, CardContent, Colors, DateTimeFilter, DateTimePicker, DevicesCarousel, DialogAlertComponent, DialogConfirmation, DocumentUpload, DonutChart, DynamicFormFields, FeatureCard, Footer, GeoAPIMaps, Heatmap, InfoGroup, Input, InputNumberFilter, InputSelectFilter, InputTextFilter, InputTimeFilter, KpiCard, LineChart, LoadImage, Loader, MapGeo, ModalForm, NotFoundModal, NotFoundSection, NotificationModal, OptionCard, PaginationComponent, PdfViewer, PdfViewerService, ProcessingOverlay, ProgressBar, ProgressFormService, QuickAccessCards, SelectCustomSearch, SideCard, SideCardDetail, TOAST_EVENTS, Table, TableChart, Tabs, TitleFilters, Toast, ToastHelper, ToastService, ToggleCustom, UI_CHART_TOKENS, WizardForm };
6410
+ export { BarChart, BaseChart, Button, ButtonCards, CARD_BG, CardContent, CardHistory, Colors, DateTimeFilter, DateTimePicker, DevicesCarousel, DialogAlertComponent, DialogConfirmation, DocumentUpload, DonutChart, DynamicFormFields, FeatureCard, Footer, GeoAPIMaps, Heatmap, InfoGroup, Input, InputNumberFilter, InputSelectFilter, InputTextFilter, InputTimeFilter, KpiCard, LineChart, LoadImage, Loader, MapGeo, ModalForm, NotFoundModal, NotFoundSection, NotificationModal, OptionCard, PaginationComponent, PdfViewer, PdfViewerService, ProcessingOverlay, ProgressBar, ProgressFormService, QuickAccessCards, SelectCustomSearch, SideCard, SideCardDetail, TOAST_EVENTS, Table, TableChart, Tabs, TitleFilters, Toast, ToastHelper, ToastService, ToggleCustom, UI_CHART_TOKENS, WizardForm };
6216
6411
  //# sourceMappingURL=sapenlinea-components.mjs.map