sapenlinea-components 0.0.27 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/sapenlinea-components.mjs +1104 -901
- package/fesm2022/sapenlinea-components.mjs.map +1 -1
- package/index.d.ts +216 -110
- package/package.json +3 -2
|
@@ -1,267 +1,293 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import * as i1$1 from '@angular/forms';
|
|
4
|
-
import { ReactiveFormsModule, NG_VALUE_ACCESSOR, FormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
|
|
2
|
+
import { EventEmitter, signal, computed, Output, Input as Input$1, Component, input, output, HostListener, ViewChildren, forwardRef, effect, model, Injectable } from '@angular/core';
|
|
5
3
|
import * as i1 from '@angular/common';
|
|
6
4
|
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as i1$1 from '@angular/forms';
|
|
6
|
+
import { NG_VALUE_ACCESSOR, ReactiveFormsModule, FormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
|
|
7
|
+
import PubSub from 'pubsub-js';
|
|
7
8
|
|
|
8
|
-
class
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
activeFilterType = signal(null, ...(ngDevMode ? [{ debugName: "activeFilterType" }] : []));
|
|
9
|
+
class PaginationComponent {
|
|
10
|
+
page = 1;
|
|
11
|
+
pageSize = 10;
|
|
12
|
+
totalItems = 0;
|
|
13
|
+
showPageSizeSelector = false;
|
|
14
|
+
pageSizeOptions = [5, 10, 20, 50];
|
|
15
|
+
pageChange = new EventEmitter();
|
|
16
|
+
pageSizeChange = new EventEmitter();
|
|
17
|
+
pageSizeValue = signal(this.pageSize, ...(ngDevMode ? [{ debugName: "pageSizeValue" }] : []));
|
|
18
18
|
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
19
|
-
selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : []));
|
|
20
|
-
inputTextValue = signal('', ...(ngDevMode ? [{ debugName: "inputTextValue" }] : []));
|
|
21
19
|
isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{ char: 'y', filled: false },
|
|
38
|
-
{ char: 'y', filled: false },
|
|
39
|
-
];
|
|
40
|
-
let index = 0;
|
|
41
|
-
for (let i = 0; i < template.length && index < numbersOnly.length; i++) {
|
|
42
|
-
if (template[i].char === '/')
|
|
43
|
-
continue;
|
|
44
|
-
template[i] = { char: numbersOnly[index++], filled: true };
|
|
45
|
-
}
|
|
46
|
-
// Cuando se completa el segmento, el slash correspondiente pasa a "filled"
|
|
47
|
-
if (numbersOnly.length >= 2) {
|
|
48
|
-
template[2] = { char: '/', filled: true }; // después de DD
|
|
49
|
-
}
|
|
50
|
-
if (numbersOnly.length >= 4) {
|
|
51
|
-
template[5] = { char: '/', filled: true }; // después de MM
|
|
52
|
-
}
|
|
53
|
-
return template; // para usar en el template y colorear por carácter
|
|
54
|
-
}, ...(ngDevMode ? [{ debugName: "inputMask" }] : []));
|
|
55
|
-
clearTrigger = input(0, ...(ngDevMode ? [{ debugName: "clearTrigger" }] : []));
|
|
56
|
-
// Computed Properties based on active filter
|
|
57
|
-
activeFilter = computed(() => {
|
|
58
|
-
const type = this.activeFilterType();
|
|
59
|
-
return this.filters().find(f => f.value === type) || null;
|
|
60
|
-
}, ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
|
|
61
|
-
mode = computed(() => {
|
|
62
|
-
const filter = this.activeFilter();
|
|
63
|
-
return filter?.type === 'datetime' ? 'datetime' : 'date';
|
|
64
|
-
}, ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
65
|
-
placeholder = computed(() => this.activeFilter()?.placeholder || 'Seleccionar fecha', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
66
|
-
minDate = computed(() => this.activeFilter()?.minDate || null, ...(ngDevMode ? [{ debugName: "minDate" }] : []));
|
|
67
|
-
maxDate = computed(() => this.activeFilter()?.maxDate || null, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
68
|
-
filterValue = computed(() => this.activeFilter()?.value || '', ...(ngDevMode ? [{ debugName: "filterValue" }] : []));
|
|
69
|
-
// Calendar Navigation
|
|
70
|
-
currentMonth = signal(new Date().getMonth(), ...(ngDevMode ? [{ debugName: "currentMonth" }] : []));
|
|
71
|
-
currentYear = signal(new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "currentYear" }] : []));
|
|
72
|
-
// Time State
|
|
73
|
-
selectedHour = signal(0, ...(ngDevMode ? [{ debugName: "selectedHour" }] : []));
|
|
74
|
-
selectedMinute = signal(0, ...(ngDevMode ? [{ debugName: "selectedMinute" }] : []));
|
|
75
|
-
selectedAmPm = signal('AM', ...(ngDevMode ? [{ debugName: "selectedAmPm" }] : []));
|
|
76
|
-
documentClickListener;
|
|
77
|
-
onChange = () => { };
|
|
78
|
-
onTouched = () => { };
|
|
79
|
-
constructor(elementRef, ngZone) {
|
|
80
|
-
this.elementRef = elementRef;
|
|
81
|
-
this.ngZone = ngZone;
|
|
82
|
-
effect(() => {
|
|
83
|
-
const trigger = this.clearTrigger();
|
|
84
|
-
if (trigger > 0) {
|
|
85
|
-
this.clear();
|
|
86
|
-
}
|
|
87
|
-
});
|
|
20
|
+
showPageSizeMenu = signal(false, ...(ngDevMode ? [{ debugName: "showPageSizeMenu" }] : []));
|
|
21
|
+
totalPages = computed(() => {
|
|
22
|
+
const size = this.pageSizeValue();
|
|
23
|
+
const total = this.totalItems;
|
|
24
|
+
return size > 0 ? Math.ceil(total / size) : 1;
|
|
25
|
+
}, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
|
|
26
|
+
pages = computed(() => {
|
|
27
|
+
const tp = this.totalPages();
|
|
28
|
+
return Array.from({ length: tp }, (_, i) => i + 1);
|
|
29
|
+
}, ...(ngDevMode ? [{ debugName: "pages" }] : []));
|
|
30
|
+
selectedPageSize = computed(() => this.pageSizeValue(), ...(ngDevMode ? [{ debugName: "selectedPageSize" }] : []));
|
|
31
|
+
goToPage(p) {
|
|
32
|
+
if (p < 1 || p > this.totalPages())
|
|
33
|
+
return;
|
|
34
|
+
this.pageChange.emit(p);
|
|
88
35
|
}
|
|
89
|
-
|
|
90
|
-
this.
|
|
36
|
+
togglePageSizeMenu() {
|
|
37
|
+
this.isOpen.update(v => !v);
|
|
38
|
+
this.showPageSizeMenu.update(v => !v);
|
|
91
39
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
else if (typeof value === 'string' && value) {
|
|
99
|
-
const parsedDate = new Date(value);
|
|
100
|
-
if (!isNaN(parsedDate.getTime())) {
|
|
101
|
-
date = parsedDate;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
if (date) {
|
|
105
|
-
this.updateInternalState(date);
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
this.resetInternalState();
|
|
109
|
-
}
|
|
40
|
+
selectPageSize(size) {
|
|
41
|
+
this.pageSizeValue.set(size);
|
|
42
|
+
this.pageSizeChange.emit(size);
|
|
43
|
+
this.showPageSizeMenu.set(false);
|
|
44
|
+
this.isOpen.set(false);
|
|
110
45
|
}
|
|
111
|
-
|
|
112
|
-
|
|
46
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
47
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: PaginationComponent, isStandalone: true, selector: "lib-pagination", inputs: { page: "page", pageSize: "pageSize", totalItems: "totalItems", showPageSizeSelector: "showPageSizeSelector", pageSizeOptions: "pageSizeOptions" }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, ngImport: i0, template: "<div class=\"pagination-container\">\r\n <div class=\"pagination\">\r\n <!-- Bot\u00F3n doble atr\u00E1s -->\r\n <button class=\"icon-button\" (click)=\"goToPage(1)\" [disabled]=\"page === 1\">\r\n \u00AB\u00AB\r\n </button>\r\n\r\n <!-- Bot\u00F3n atr\u00E1s -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page - 1)\" [disabled]=\"page === 1\">\r\n \u00AB\r\n </button>\r\n\r\n <!-- N\u00FAmeros de p\u00E1gina -->\r\n <div class=\"pages\">\r\n <button\r\n class=\"page-btn\"\r\n *ngFor=\"let p of pages(); let idx = index\"\r\n [class.active]=\"page === idx + 1\"\r\n (click)=\"goToPage(idx + 1)\"\r\n >\r\n {{ idx + 1 }}\r\n </button>\r\n </div>\r\n\r\n <!-- Bot\u00F3n siguiente -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page + 1)\" [disabled]=\"page === totalPages()\">\r\n \u00BB\r\n </button>\r\n\r\n <!-- Bot\u00F3n doble adelante -->\r\n <button class=\"icon-button\" (click)=\"goToPage(totalPages())\" [disabled]=\"page === totalPages()\">\r\n \u00BB\u00BB\r\n </button>\r\n </div>\r\n\r\n <!-- Selector Items por p\u00E1gina -->\r\n <div *ngIf=\"showPageSizeSelector\">\r\n <div class=\"pagination-v-4\">\r\n <div class=\"label-pagination\">Items por p\u00E1gina</div>\r\n <div class=\"elements-pagination\">\r\n <div class=\"split-button\" (click)=\"togglePageSizeMenu()\">\r\n <div class=\"leading-button\">\r\n <div class=\"state-layer\">\r\n <div class=\"label\">{{ pageSizeValue() }}</div>\r\n </div>\r\n </div>\r\n <div class=\"trailing-button\">\r\n <div class=\"arrow\" [class.open]=\"isOpen()\">\r\n <svg class=\"arrow\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Men\u00FA desplegable -->\r\n <div class=\"page-size-menu\" *ngIf=\"showPageSizeMenu()\">\r\n <div\r\n class=\"menu-option\"\r\n *ngFor=\"let opt of pageSizeOptions\"\r\n [class.active]=\"opt === pageSizeValue()\"\r\n (click)=\"selectPageSize(opt)\"\r\n >\r\n {{ opt }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".pagination-container{display:flex;flex-direction:row;justify-content:center;width:100%;padding:8px 0;position:relative}.pagination{display:flex;align-items:center;gap:12px;padding:12px;justify-content:center;flex:1}.icon-button{width:40px;height:40px;border-radius:50%;background:var(--primary, #596300);color:var(--surface, #ffffff);border:none;cursor:pointer;font-size:16px;font-weight:700;display:flex;align-items:center;justify-content:center;box-shadow:0 1px 2px #00000026;transition:background .2s ease,transform .1s ease}.icon-button:disabled{background:#969696;color:var(--on-surface, #171c1f);opacity:.45;cursor:not-allowed}.pages{display:flex;gap:4px;overflow:hidden;border-radius:20px}.page-btn{background:var(--secondary-container, #dee58f);width:40px;height:40px;border:none;cursor:pointer;padding:8px 14px;font-size:14px;color:var(--schemes-on-surface, #3a3a3a);font-family:Roboto,sans-serif;border-radius:8px;transition:background .2s ease}.page-btn:hover:not(.active){background:var(--schemes-on-secondary-container, #61661f);color:var(--schemes-secondary-container, #dee58f)}.page-btn.active{background:var(--schemes-primary, #596300);color:var(--schemes-on-primary, #ffffff);font-weight:600;border-radius:20px}.pagination-v-4{display:flex;gap:10px;align-items:center;margin-left:auto}.label-pagination{font-size:14px;font-weight:600;color:var(--schemes-on-surface)}.elements-pagination{position:relative;display:flex;gap:4px;border-radius:20px}.split-button{display:flex;cursor:pointer;border-radius:20px;overflow:hidden}.leading-button{background:var(--schemes-secondary-container);border-radius:20px 4px 4px 20px;display:flex;align-items:center;height:40px}.state-layer{padding:10px 16px;background-color:#dee58f;margin-right:4px;border-radius:8px}.state-layer:open{color:#f5f5e0;background-color:#596300}.label{font-size:14px;font-weight:500;color:var(--schemes-on-secondary-container)}.trailing-button{background:var(--secondary-container, #dee58f);padding-left:12px;padding-right:12px;border:none;cursor:pointer;font-size:14px;color:var(--schemes-on-surface, #3a3a3a);font-family:Roboto,sans-serif;border-radius:8px;transition:background .2s ease;align-items:center;align-content:center}.arrow{width:20px;height:20px;color:#171c1f;transition:transform .25s ease}.arrow.open{transform:rotate(180deg)}.page-size-menu{background:#f5f5e0;position:absolute;min-width:100px;border-radius:4px;box-shadow:0 2px 8px #0003;overflow:hidden;z-index:999;bottom:50px;right:0;transform-origin:top right}.menu-option{padding:8px 12px;cursor:pointer}.menu-option:hover{background:#dee58f5b}.menu-option.active{background:#dee58f;color:#61661f}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
48
|
+
}
|
|
49
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PaginationComponent, decorators: [{
|
|
50
|
+
type: Component,
|
|
51
|
+
args: [{ selector: 'lib-pagination', standalone: true, imports: [CommonModule], template: "<div class=\"pagination-container\">\r\n <div class=\"pagination\">\r\n <!-- Bot\u00F3n doble atr\u00E1s -->\r\n <button class=\"icon-button\" (click)=\"goToPage(1)\" [disabled]=\"page === 1\">\r\n \u00AB\u00AB\r\n </button>\r\n\r\n <!-- Bot\u00F3n atr\u00E1s -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page - 1)\" [disabled]=\"page === 1\">\r\n \u00AB\r\n </button>\r\n\r\n <!-- N\u00FAmeros de p\u00E1gina -->\r\n <div class=\"pages\">\r\n <button\r\n class=\"page-btn\"\r\n *ngFor=\"let p of pages(); let idx = index\"\r\n [class.active]=\"page === idx + 1\"\r\n (click)=\"goToPage(idx + 1)\"\r\n >\r\n {{ idx + 1 }}\r\n </button>\r\n </div>\r\n\r\n <!-- Bot\u00F3n siguiente -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page + 1)\" [disabled]=\"page === totalPages()\">\r\n \u00BB\r\n </button>\r\n\r\n <!-- Bot\u00F3n doble adelante -->\r\n <button class=\"icon-button\" (click)=\"goToPage(totalPages())\" [disabled]=\"page === totalPages()\">\r\n \u00BB\u00BB\r\n </button>\r\n </div>\r\n\r\n <!-- Selector Items por p\u00E1gina -->\r\n <div *ngIf=\"showPageSizeSelector\">\r\n <div class=\"pagination-v-4\">\r\n <div class=\"label-pagination\">Items por p\u00E1gina</div>\r\n <div class=\"elements-pagination\">\r\n <div class=\"split-button\" (click)=\"togglePageSizeMenu()\">\r\n <div class=\"leading-button\">\r\n <div class=\"state-layer\">\r\n <div class=\"label\">{{ pageSizeValue() }}</div>\r\n </div>\r\n </div>\r\n <div class=\"trailing-button\">\r\n <div class=\"arrow\" [class.open]=\"isOpen()\">\r\n <svg class=\"arrow\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Men\u00FA desplegable -->\r\n <div class=\"page-size-menu\" *ngIf=\"showPageSizeMenu()\">\r\n <div\r\n class=\"menu-option\"\r\n *ngFor=\"let opt of pageSizeOptions\"\r\n [class.active]=\"opt === pageSizeValue()\"\r\n (click)=\"selectPageSize(opt)\"\r\n >\r\n {{ opt }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".pagination-container{display:flex;flex-direction:row;justify-content:center;width:100%;padding:8px 0;position:relative}.pagination{display:flex;align-items:center;gap:12px;padding:12px;justify-content:center;flex:1}.icon-button{width:40px;height:40px;border-radius:50%;background:var(--primary, #596300);color:var(--surface, #ffffff);border:none;cursor:pointer;font-size:16px;font-weight:700;display:flex;align-items:center;justify-content:center;box-shadow:0 1px 2px #00000026;transition:background .2s ease,transform .1s ease}.icon-button:disabled{background:#969696;color:var(--on-surface, #171c1f);opacity:.45;cursor:not-allowed}.pages{display:flex;gap:4px;overflow:hidden;border-radius:20px}.page-btn{background:var(--secondary-container, #dee58f);width:40px;height:40px;border:none;cursor:pointer;padding:8px 14px;font-size:14px;color:var(--schemes-on-surface, #3a3a3a);font-family:Roboto,sans-serif;border-radius:8px;transition:background .2s ease}.page-btn:hover:not(.active){background:var(--schemes-on-secondary-container, #61661f);color:var(--schemes-secondary-container, #dee58f)}.page-btn.active{background:var(--schemes-primary, #596300);color:var(--schemes-on-primary, #ffffff);font-weight:600;border-radius:20px}.pagination-v-4{display:flex;gap:10px;align-items:center;margin-left:auto}.label-pagination{font-size:14px;font-weight:600;color:var(--schemes-on-surface)}.elements-pagination{position:relative;display:flex;gap:4px;border-radius:20px}.split-button{display:flex;cursor:pointer;border-radius:20px;overflow:hidden}.leading-button{background:var(--schemes-secondary-container);border-radius:20px 4px 4px 20px;display:flex;align-items:center;height:40px}.state-layer{padding:10px 16px;background-color:#dee58f;margin-right:4px;border-radius:8px}.state-layer:open{color:#f5f5e0;background-color:#596300}.label{font-size:14px;font-weight:500;color:var(--schemes-on-secondary-container)}.trailing-button{background:var(--secondary-container, #dee58f);padding-left:12px;padding-right:12px;border:none;cursor:pointer;font-size:14px;color:var(--schemes-on-surface, #3a3a3a);font-family:Roboto,sans-serif;border-radius:8px;transition:background .2s ease;align-items:center;align-content:center}.arrow{width:20px;height:20px;color:#171c1f;transition:transform .25s ease}.arrow.open{transform:rotate(180deg)}.page-size-menu{background:#f5f5e0;position:absolute;min-width:100px;border-radius:4px;box-shadow:0 2px 8px #0003;overflow:hidden;z-index:999;bottom:50px;right:0;transform-origin:top right}.menu-option{padding:8px 12px;cursor:pointer}.menu-option:hover{background:#dee58f5b}.menu-option.active{background:#dee58f;color:#61661f}\n"] }]
|
|
52
|
+
}], propDecorators: { page: [{
|
|
53
|
+
type: Input$1
|
|
54
|
+
}], pageSize: [{
|
|
55
|
+
type: Input$1
|
|
56
|
+
}], totalItems: [{
|
|
57
|
+
type: Input$1
|
|
58
|
+
}], showPageSizeSelector: [{
|
|
59
|
+
type: Input$1
|
|
60
|
+
}], pageSizeOptions: [{
|
|
61
|
+
type: Input$1
|
|
62
|
+
}], pageChange: [{
|
|
63
|
+
type: Output
|
|
64
|
+
}], pageSizeChange: [{
|
|
65
|
+
type: Output
|
|
66
|
+
}] } });
|
|
67
|
+
|
|
68
|
+
const STATUS_TONE_STYLES = {
|
|
69
|
+
success: { bg: '#E6F4EA', color: '#1E8E3E' },
|
|
70
|
+
error: { bg: '#FCE8E6', color: '#D93025' },
|
|
71
|
+
warning: { bg: '#FFF4E5', color: '#E67E22' },
|
|
72
|
+
info: { bg: '#E6F4EA', color: '#0077B6' },
|
|
73
|
+
neutral: { bg: '#F4F4F4', color: '#5F6368' },
|
|
74
|
+
};
|
|
75
|
+
class Table {
|
|
76
|
+
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
77
|
+
data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
78
|
+
actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
|
|
79
|
+
showActions = input(true, ...(ngDevMode ? [{ debugName: "showActions" }] : []));
|
|
80
|
+
openedMenu = signal(null, ...(ngDevMode ? [{ debugName: "openedMenu" }] : []));
|
|
81
|
+
selectedRow = signal(null, ...(ngDevMode ? [{ debugName: "selectedRow" }] : []));
|
|
82
|
+
sortColumn = signal(null, ...(ngDevMode ? [{ debugName: "sortColumn" }] : []));
|
|
83
|
+
sortDirection = signal('desc', ...(ngDevMode ? [{ debugName: "sortDirection" }] : []));
|
|
84
|
+
optionSelected = output();
|
|
85
|
+
iconAction = output();
|
|
86
|
+
statusToneMap = input({}, ...(ngDevMode ? [{ debugName: "statusToneMap" }] : []));
|
|
87
|
+
chips;
|
|
88
|
+
ngAfterViewInit() {
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
const chipEls = this.chips.map(c => c.nativeElement);
|
|
91
|
+
const widths = chipEls.map(el => el.scrollWidth);
|
|
92
|
+
const maxContentWidth = Math.max(...widths);
|
|
93
|
+
chipEls.forEach(el => {
|
|
94
|
+
el.style.width = maxContentWidth + 'px';
|
|
95
|
+
});
|
|
96
|
+
});
|
|
113
97
|
}
|
|
114
|
-
|
|
115
|
-
this.
|
|
98
|
+
toggleMenu(index) {
|
|
99
|
+
this.openedMenu.set(this.openedMenu() === index ? null : index);
|
|
116
100
|
}
|
|
117
|
-
|
|
118
|
-
this.
|
|
101
|
+
onOptionClick(option, row) {
|
|
102
|
+
this.optionSelected.emit({ action: option.label, row });
|
|
103
|
+
this.openedMenu.set(null);
|
|
119
104
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (this.
|
|
123
|
-
|
|
124
|
-
if (this.activeFilterType() === filterValue && this.isOpen()) {
|
|
125
|
-
this.close();
|
|
105
|
+
openModal(row, event) {
|
|
106
|
+
event?.stopPropagation();
|
|
107
|
+
if (this.selectedRow()?.['id'] === row['id']) {
|
|
108
|
+
this.selectedRow.set(null);
|
|
126
109
|
}
|
|
127
110
|
else {
|
|
128
|
-
this.
|
|
129
|
-
this.open();
|
|
111
|
+
this.selectedRow.set(row);
|
|
130
112
|
}
|
|
131
113
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
this.isOpen.set(true);
|
|
137
|
-
this.addDocumentListener();
|
|
138
|
-
const selected = this.selectedDate();
|
|
139
|
-
if (selected) {
|
|
140
|
-
this.currentMonth.set(selected.getMonth());
|
|
141
|
-
this.currentYear.set(selected.getFullYear());
|
|
114
|
+
onClickOutside(event) {
|
|
115
|
+
const target = event.target;
|
|
116
|
+
if (!target.closest('.menu-acciones')) {
|
|
117
|
+
this.selectedRow.set(null);
|
|
142
118
|
}
|
|
143
119
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (!day || this.isDisabled())
|
|
157
|
-
return;
|
|
158
|
-
const newDate = new Date(this.currentYear(), this.currentMonth(), day, this.selectedHour(), this.selectedMinute());
|
|
159
|
-
if (this.isDateDisabled(newDate))
|
|
160
|
-
return;
|
|
161
|
-
this.updateInternalState(newDate);
|
|
162
|
-
this.onChange(newDate.toISOString());
|
|
163
|
-
this.markAsTouched();
|
|
164
|
-
this.dateChange.emit(newDate);
|
|
165
|
-
this.dateSelected.emit({
|
|
166
|
-
filter: this.filterValue(),
|
|
167
|
-
value: newDate,
|
|
168
|
-
});
|
|
169
|
-
if (this.mode() === 'date') {
|
|
170
|
-
this.close();
|
|
120
|
+
getAlignment(col) {
|
|
121
|
+
if (col.align && col.align !== 'auto')
|
|
122
|
+
return col.align;
|
|
123
|
+
switch (col.type) {
|
|
124
|
+
case 'number':
|
|
125
|
+
case 'money':
|
|
126
|
+
case 'percentage':
|
|
127
|
+
return 'right';
|
|
128
|
+
case 'status':
|
|
129
|
+
return 'center';
|
|
130
|
+
default:
|
|
131
|
+
return 'left';
|
|
171
132
|
}
|
|
172
133
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const date = this.selectedDate();
|
|
176
|
-
if (!date)
|
|
134
|
+
formatValue(col, value) {
|
|
135
|
+
if (value === null || value === undefined)
|
|
177
136
|
return '';
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
137
|
+
switch (col.type) {
|
|
138
|
+
case 'money':
|
|
139
|
+
return new Intl.NumberFormat('es-CO', {
|
|
140
|
+
style: 'currency',
|
|
141
|
+
currency: 'COP',
|
|
142
|
+
minimumFractionDigits: 0
|
|
143
|
+
}).format(value);
|
|
144
|
+
case 'number':
|
|
145
|
+
return new Intl.NumberFormat('es-CO').format(value);
|
|
146
|
+
case 'percentage':
|
|
147
|
+
return `${value}%`;
|
|
148
|
+
case 'date':
|
|
149
|
+
const d = new Date(value);
|
|
150
|
+
return d.toLocaleDateString('es-CO'); // dd/mm/yyyy
|
|
151
|
+
default:
|
|
152
|
+
return String(value);
|
|
187
153
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
154
|
+
}
|
|
155
|
+
getStatusStyle(value) {
|
|
156
|
+
if (!value) {
|
|
157
|
+
return STATUS_TONE_STYLES.neutral;
|
|
158
|
+
}
|
|
159
|
+
const key = this.normalizeStatus(value);
|
|
160
|
+
const tone = this.statusToneMap()?.[key] ?? 'neutral';
|
|
161
|
+
return STATUS_TONE_STYLES[tone];
|
|
162
|
+
}
|
|
163
|
+
normalizeStatus(value) {
|
|
164
|
+
return String(value ?? '')
|
|
165
|
+
.toLowerCase()
|
|
166
|
+
.trim()
|
|
167
|
+
.replace(/\s+/g, '_');
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Devuelve las acciones para una fila.
|
|
171
|
+
* Puede ser que `actions` sea un arreglo (se muestra tal cual) o una función
|
|
172
|
+
* que recibe la fila y retorna las acciones correspondientes.
|
|
173
|
+
*/
|
|
174
|
+
getActionsForRow(row) {
|
|
175
|
+
const acts = this.actions();
|
|
176
|
+
if (!acts)
|
|
177
|
+
return [];
|
|
178
|
+
if (typeof acts === 'function') {
|
|
179
|
+
try {
|
|
180
|
+
return acts(row) ?? [];
|
|
206
181
|
}
|
|
207
|
-
|
|
208
|
-
|
|
182
|
+
catch {
|
|
183
|
+
return [];
|
|
209
184
|
}
|
|
210
185
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
this.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
186
|
+
return acts;
|
|
187
|
+
}
|
|
188
|
+
sortData() {
|
|
189
|
+
const col = this.sortColumn();
|
|
190
|
+
if (!col)
|
|
191
|
+
return this.data();
|
|
192
|
+
const dir = this.sortDirection();
|
|
193
|
+
return [...this.data()].sort((a, b) => {
|
|
194
|
+
const x = a[col] ?? '';
|
|
195
|
+
const y = b[col] ?? '';
|
|
196
|
+
// Caso: fechas
|
|
197
|
+
if (this.isDate(x) && this.isDate(y)) {
|
|
198
|
+
return dir === 'asc'
|
|
199
|
+
? new Date(x).getTime() - new Date(y).getTime()
|
|
200
|
+
: new Date(y).getTime() - new Date(x).getTime();
|
|
201
|
+
}
|
|
202
|
+
// Caso: números
|
|
203
|
+
if (!isNaN(Number(x)) && !isNaN(Number(y))) {
|
|
204
|
+
return dir === 'asc' ? Number(x) - Number(y) : Number(y) - Number(x);
|
|
230
205
|
}
|
|
206
|
+
// Caso: strings
|
|
207
|
+
return dir === 'asc'
|
|
208
|
+
? x.toString().localeCompare(y.toString())
|
|
209
|
+
: y.toString().localeCompare(x.toString());
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
isDate(value) {
|
|
213
|
+
return (typeof value === 'string' &&
|
|
214
|
+
value.length > 5 &&
|
|
215
|
+
!isNaN(Date.parse(value)));
|
|
216
|
+
}
|
|
217
|
+
onSort(col) {
|
|
218
|
+
if (this.sortColumn() === col.key) {
|
|
219
|
+
// cambiar asc <-> desc
|
|
220
|
+
this.sortDirection.set(this.sortDirection() === 'asc' ? 'desc' : 'asc');
|
|
231
221
|
}
|
|
232
|
-
else
|
|
233
|
-
//
|
|
234
|
-
this.
|
|
235
|
-
this.
|
|
236
|
-
this.dateChange.emit(null);
|
|
222
|
+
else {
|
|
223
|
+
// nueva columna → empieza en desc (más reciente primero)
|
|
224
|
+
this.sortColumn.set(col.key);
|
|
225
|
+
this.sortDirection.set('desc');
|
|
237
226
|
}
|
|
238
227
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
228
|
+
onIconColumnClick(col, row, event) {
|
|
229
|
+
event.stopPropagation();
|
|
230
|
+
this.iconAction.emit({
|
|
231
|
+
action: col.iconKey ?? col.key,
|
|
232
|
+
row
|
|
233
|
+
});
|
|
244
234
|
}
|
|
245
|
-
|
|
246
|
-
if (!input || input.trim() === '')
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (match) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Table, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
236
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: Table, isStandalone: true, selector: "lib-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, statusToneMap: { classPropertyName: "statusToneMap", publicName: "statusToneMap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionSelected: "optionSelected", iconAction: "iconAction" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "chips", predicate: ["statusChip"], descendants: true }], ngImport: i0, template: "<div class=\"table-wrapper\">\r\n <table class=\"inner-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th\r\n (click)=\"col.sortable !== false && onSort(col)\"\r\n [class.sortable]=\"col.sortable !== false\"\r\n [class]=\"getAlignment(col)\"\r\n >\r\n {{ col.label }}\r\n\r\n <!-- iconos de orden opcionales -->\r\n @if (sortColumn() === col.key) {\r\n <span class=\"sort-icon\">\r\n {{ sortDirection() === 'asc' ? '\u25B2' : '\u25BC' }}\r\n </span>\r\n }\r\n </th>\r\n }\r\n\r\n <!-- columna para acciones -->\r\n @if (showActions()) {\r\n <th></th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of sortData(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td [class]=\"getAlignment(col)\">\r\n @if (col.type === 'status') { @let style =\r\n getStatusStyle(row[col.key]);\r\n <span #statusChip\r\n class=\"status-chip\"\r\n [style.background-color]=\"style.bg\"\r\n [style.color]=\"style.color\"\r\n >\r\n <span\r\n class=\"status-dot\"\r\n [style.background-color]=\"style.color\"\r\n ></span>\r\n\r\n {{ row[col.key]?.toString().toUpperCase() }}\r\n </span>\r\n\r\n } @else if (col.type === 'icon-button') {\r\n\r\n <button (click)=\"onIconColumnClick(col, row, $event)\">\r\n <span\r\n class=\"icon\"\r\n [class]=\"col.icon\"\r\n [style.color]=\"col.iconColor\"\r\n ></span>\r\n </button>\r\n\r\n } @else { {{ formatValue(col, row[col.key]) }} }\r\n </td>\r\n }\r\n\r\n <!-- Celda de acciones -->\r\n @if (showActions()) {\r\n <td class=\"acciones-cell\">\r\n <div class=\"menu-acciones\">\r\n <button class=\"icon-button\" (click)=\"openModal(row)\">\r\n <div class=\"content\">\r\n <div class=\"state-layer\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"more-vert\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </button>\r\n @if(selectedRow()?.['id'] === row['id']){\r\n <div class=\"modal-options\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-content\">\r\n <ul>\r\n @for (option of getActionsForRow(row); track $index) {\r\n <li\r\n class=\"option-item\"\r\n [style.color]=\"option.color\"\r\n (click)=\"onOptionClick(option, row)\"\r\n >\r\n <span class=\"icon\" [class]=\"option.icon\"></span>\r\n <span class=\"label\">{{ option.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".table-wrapper{width:100%;border-radius:20px;border:1px solid #c7c7ad}.inner-table{width:100%;border-collapse:separate;font-size:14px;border-spacing:0;border-radius:20px;background:#ebe8d6}.inner-table thead{background:#f0f0db}.inner-table thead tr th:first-child{border-top-left-radius:20px}.inner-table thead tr th:last-child{border-top-right-radius:20px}.inner-table th{text-align:left;padding:12px 16px;font-weight:600;color:#3a3a3a;text-transform:uppercase}.inner-table td{padding:12px 16px;color:#4a4a4a;border-top:1px solid #c7c7ad;table-layout:auto}.acciones-cell{text-align:center;padding:6px;position:relative}.menu-acciones{display:flex;align-items:center;justify-content:center;position:relative}button{background-color:transparent;border:none}.icon-button{background-color:var(--secondary-container, #dee58f);width:36px;height:36px;border:none;cursor:pointer;padding:0;border-radius:100%;display:flex;align-items:center;justify-content:center}.icon-button:hover{background:#0000000f}.more-vert{color:#4a4a4a;display:block}.modal-options{display:flex;justify-items:center;align-items:center;background-color:var(--surface-container-lowest, #ffffff);width:200px;border-radius:8px;position:absolute;top:100%;right:0;z-index:99}.modal-content{width:100%;border-radius:8px;border:1px solid var(--outline-variant, #c7c7ad);overflow:hidden}.option-item{display:flex;align-items:center;height:56px;padding:8px 12px;cursor:pointer}.option-item:hover{background-color:#0000001a}.option-item:active{background-color:#dee58f}.icon{margin-right:8px}.option-item .label{font-weight:500;font-size:16px}.icon-refresh,.icon-delete,.icon-edit,.icon-activate,.icon-deactivate,.icon-view,.icon-sanction,.icon-file{width:24px;height:24px;background-color:currentColor;color:currentColor;-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;mask-size:contain;mask-repeat:no-repeat;display:inline-block;cursor:pointer}.icon-refresh{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>')}.icon-delete{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>')}.icon-edit{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>')}.icon-activate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>')}.icon-deactivate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>')}.icon-view{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>')}.icon-sanction{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>')}.icon-file{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>')}th.left.sortable,th.left,td.left{text-align:left}th.right.sortable,th.right,td.right{text-align:right}th.center.sortable,th.center,td.center{text-align:center}.status-chip{display:inline-flex;align-items:center;gap:.5rem;padding:.375rem .75rem;border-radius:6px;font-size:.875rem;font-weight:500;white-space:nowrap;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.sortable:hover{opacity:.7}.sort-icon{margin-left:6px;font-size:12px;pointer-events:none}\n"] });
|
|
237
|
+
}
|
|
238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Table, decorators: [{
|
|
239
|
+
type: Component,
|
|
240
|
+
args: [{ selector: 'lib-table', imports: [], standalone: true, template: "<div class=\"table-wrapper\">\r\n <table class=\"inner-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th\r\n (click)=\"col.sortable !== false && onSort(col)\"\r\n [class.sortable]=\"col.sortable !== false\"\r\n [class]=\"getAlignment(col)\"\r\n >\r\n {{ col.label }}\r\n\r\n <!-- iconos de orden opcionales -->\r\n @if (sortColumn() === col.key) {\r\n <span class=\"sort-icon\">\r\n {{ sortDirection() === 'asc' ? '\u25B2' : '\u25BC' }}\r\n </span>\r\n }\r\n </th>\r\n }\r\n\r\n <!-- columna para acciones -->\r\n @if (showActions()) {\r\n <th></th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of sortData(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td [class]=\"getAlignment(col)\">\r\n @if (col.type === 'status') { @let style =\r\n getStatusStyle(row[col.key]);\r\n <span #statusChip\r\n class=\"status-chip\"\r\n [style.background-color]=\"style.bg\"\r\n [style.color]=\"style.color\"\r\n >\r\n <span\r\n class=\"status-dot\"\r\n [style.background-color]=\"style.color\"\r\n ></span>\r\n\r\n {{ row[col.key]?.toString().toUpperCase() }}\r\n </span>\r\n\r\n } @else if (col.type === 'icon-button') {\r\n\r\n <button (click)=\"onIconColumnClick(col, row, $event)\">\r\n <span\r\n class=\"icon\"\r\n [class]=\"col.icon\"\r\n [style.color]=\"col.iconColor\"\r\n ></span>\r\n </button>\r\n\r\n } @else { {{ formatValue(col, row[col.key]) }} }\r\n </td>\r\n }\r\n\r\n <!-- Celda de acciones -->\r\n @if (showActions()) {\r\n <td class=\"acciones-cell\">\r\n <div class=\"menu-acciones\">\r\n <button class=\"icon-button\" (click)=\"openModal(row)\">\r\n <div class=\"content\">\r\n <div class=\"state-layer\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"more-vert\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </button>\r\n @if(selectedRow()?.['id'] === row['id']){\r\n <div class=\"modal-options\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-content\">\r\n <ul>\r\n @for (option of getActionsForRow(row); track $index) {\r\n <li\r\n class=\"option-item\"\r\n [style.color]=\"option.color\"\r\n (click)=\"onOptionClick(option, row)\"\r\n >\r\n <span class=\"icon\" [class]=\"option.icon\"></span>\r\n <span class=\"label\">{{ option.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".table-wrapper{width:100%;border-radius:20px;border:1px solid #c7c7ad}.inner-table{width:100%;border-collapse:separate;font-size:14px;border-spacing:0;border-radius:20px;background:#ebe8d6}.inner-table thead{background:#f0f0db}.inner-table thead tr th:first-child{border-top-left-radius:20px}.inner-table thead tr th:last-child{border-top-right-radius:20px}.inner-table th{text-align:left;padding:12px 16px;font-weight:600;color:#3a3a3a;text-transform:uppercase}.inner-table td{padding:12px 16px;color:#4a4a4a;border-top:1px solid #c7c7ad;table-layout:auto}.acciones-cell{text-align:center;padding:6px;position:relative}.menu-acciones{display:flex;align-items:center;justify-content:center;position:relative}button{background-color:transparent;border:none}.icon-button{background-color:var(--secondary-container, #dee58f);width:36px;height:36px;border:none;cursor:pointer;padding:0;border-radius:100%;display:flex;align-items:center;justify-content:center}.icon-button:hover{background:#0000000f}.more-vert{color:#4a4a4a;display:block}.modal-options{display:flex;justify-items:center;align-items:center;background-color:var(--surface-container-lowest, #ffffff);width:200px;border-radius:8px;position:absolute;top:100%;right:0;z-index:99}.modal-content{width:100%;border-radius:8px;border:1px solid var(--outline-variant, #c7c7ad);overflow:hidden}.option-item{display:flex;align-items:center;height:56px;padding:8px 12px;cursor:pointer}.option-item:hover{background-color:#0000001a}.option-item:active{background-color:#dee58f}.icon{margin-right:8px}.option-item .label{font-weight:500;font-size:16px}.icon-refresh,.icon-delete,.icon-edit,.icon-activate,.icon-deactivate,.icon-view,.icon-sanction,.icon-file{width:24px;height:24px;background-color:currentColor;color:currentColor;-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;mask-size:contain;mask-repeat:no-repeat;display:inline-block;cursor:pointer}.icon-refresh{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>')}.icon-delete{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>')}.icon-edit{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>')}.icon-activate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>')}.icon-deactivate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>')}.icon-view{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>')}.icon-sanction{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>')}.icon-file{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>')}th.left.sortable,th.left,td.left{text-align:left}th.right.sortable,th.right,td.right{text-align:right}th.center.sortable,th.center,td.center{text-align:center}.status-chip{display:inline-flex;align-items:center;gap:.5rem;padding:.375rem .75rem;border-radius:6px;font-size:.875rem;font-weight:500;white-space:nowrap;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.sortable:hover{opacity:.7}.sort-icon{margin-left:6px;font-size:12px;pointer-events:none}\n"] }]
|
|
241
|
+
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], optionSelected: [{ type: i0.Output, args: ["optionSelected"] }], iconAction: [{ type: i0.Output, args: ["iconAction"] }], statusToneMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusToneMap", required: false }] }], chips: [{
|
|
242
|
+
type: ViewChildren,
|
|
243
|
+
args: ['statusChip']
|
|
244
|
+
}], onClickOutside: [{
|
|
245
|
+
type: HostListener,
|
|
246
|
+
args: ['document:click', ['$event']]
|
|
247
|
+
}] } });
|
|
248
|
+
|
|
249
|
+
class DateTimePicker {
|
|
250
|
+
elementRef;
|
|
251
|
+
ngZone;
|
|
252
|
+
mode = input('date', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
253
|
+
placeholder = input('Seleccionar fecha', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
254
|
+
minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : []));
|
|
255
|
+
maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
256
|
+
dateChange = output();
|
|
257
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
258
|
+
selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : []));
|
|
259
|
+
isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
260
|
+
isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
|
|
261
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
262
|
+
isBlocked = computed(() => this.isDisabled() || this.readonly(), ...(ngDevMode ? [{ debugName: "isBlocked" }] : []));
|
|
263
|
+
// Texto que escribe el usuario (DD/MM/YYYY)
|
|
264
|
+
inputTextValue = signal('', ...(ngDevMode ? [{ debugName: "inputTextValue" }] : []));
|
|
265
|
+
// Navegación del calendario
|
|
266
|
+
currentMonth = signal(new Date().getMonth(), ...(ngDevMode ? [{ debugName: "currentMonth" }] : []));
|
|
267
|
+
currentYear = signal(new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "currentYear" }] : []));
|
|
268
|
+
// Hora en formato 24h (para el backend)
|
|
269
|
+
selectedHour = signal(0, ...(ngDevMode ? [{ debugName: "selectedHour" }] : []));
|
|
270
|
+
selectedMinute = signal(0, ...(ngDevMode ? [{ debugName: "selectedMinute" }] : []));
|
|
271
|
+
// Estado AM/PM
|
|
272
|
+
selectedAmPm = signal('AM', ...(ngDevMode ? [{ debugName: "selectedAmPm" }] : []));
|
|
273
|
+
documentClickListener;
|
|
274
|
+
/**
|
|
275
|
+
* Valor que se muestra en el campo de texto.
|
|
276
|
+
* Siempre muestra la fecha en formato DD/MM/YYYY.
|
|
277
|
+
*/
|
|
278
|
+
displayValue = computed(() => {
|
|
279
|
+
const text = this.inputTextValue().trim();
|
|
280
|
+
if (text) {
|
|
281
|
+
return text;
|
|
262
282
|
}
|
|
263
|
-
|
|
264
|
-
|
|
283
|
+
const date = this.selectedDate();
|
|
284
|
+
if (!date)
|
|
285
|
+
return '';
|
|
286
|
+
const day = date.getDate().toString().padStart(2, '0');
|
|
287
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
288
|
+
const year = date.getFullYear();
|
|
289
|
+
return `${day}/${month}/${year}`;
|
|
290
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
265
291
|
monthName = computed(() => {
|
|
266
292
|
const months = [
|
|
267
293
|
'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
|
|
@@ -277,12 +303,17 @@ class DateTimeFilter {
|
|
|
277
303
|
const daysInMonth = lastDay.getDate();
|
|
278
304
|
const startingDayOfWeek = firstDay.getDay();
|
|
279
305
|
const days = [];
|
|
280
|
-
|
|
306
|
+
// Días vacíos al inicio
|
|
307
|
+
for (let i = 0; i < startingDayOfWeek; i++) {
|
|
281
308
|
days.push(null);
|
|
282
|
-
|
|
309
|
+
}
|
|
310
|
+
// Días del mes
|
|
311
|
+
for (let day = 1; day <= daysInMonth; day++) {
|
|
283
312
|
days.push(day);
|
|
313
|
+
}
|
|
284
314
|
return days;
|
|
285
315
|
}, ...(ngDevMode ? [{ debugName: "calendarDays" }] : []));
|
|
316
|
+
// Horas en formato 12h
|
|
286
317
|
hours12 = computed(() => {
|
|
287
318
|
return Array.from({ length: 12 }, (_, i) => {
|
|
288
319
|
const hour12 = i === 0 ? 12 : i;
|
|
@@ -292,6 +323,7 @@ class DateTimeFilter {
|
|
|
292
323
|
};
|
|
293
324
|
});
|
|
294
325
|
}, ...(ngDevMode ? [{ debugName: "hours12" }] : []));
|
|
326
|
+
// Hora seleccionada en formato 12h
|
|
295
327
|
selectedHour12 = computed(() => {
|
|
296
328
|
const hour24 = this.selectedHour();
|
|
297
329
|
if (hour24 === 0)
|
|
@@ -301,62 +333,124 @@ class DateTimeFilter {
|
|
|
301
333
|
return hour24;
|
|
302
334
|
}, ...(ngDevMode ? [{ debugName: "selectedHour12" }] : []));
|
|
303
335
|
minutes = computed(() => Array.from({ length: 60 }, (_, i) => i), ...(ngDevMode ? [{ debugName: "minutes" }] : []));
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
this.
|
|
308
|
-
this.
|
|
309
|
-
this.selectedHour.set(date.getHours());
|
|
310
|
-
this.selectedMinute.set(date.getMinutes());
|
|
311
|
-
this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');
|
|
312
|
-
// Update input text value to match the formatted date
|
|
313
|
-
const formatted = this.formatDateForInput(date);
|
|
314
|
-
this.inputTextValue.set(formatted);
|
|
336
|
+
onChange = (value) => { };
|
|
337
|
+
onTouched = () => { };
|
|
338
|
+
constructor(elementRef, ngZone) {
|
|
339
|
+
this.elementRef = elementRef;
|
|
340
|
+
this.ngZone = ngZone;
|
|
315
341
|
}
|
|
316
|
-
|
|
317
|
-
this.
|
|
318
|
-
this.inputTextValue.set('');
|
|
319
|
-
this.selectedHour.set(0);
|
|
320
|
-
this.selectedMinute.set(0);
|
|
321
|
-
this.selectedAmPm.set('AM');
|
|
342
|
+
ngOnDestroy() {
|
|
343
|
+
this.removeDocumentListener();
|
|
322
344
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
345
|
+
writeValue(value) {
|
|
346
|
+
let date = null;
|
|
347
|
+
if (value instanceof Date) {
|
|
348
|
+
date = value;
|
|
349
|
+
}
|
|
350
|
+
else if (typeof value === 'string' && value) {
|
|
351
|
+
// Manejar tanto fechas ISO como otros formatos de string
|
|
352
|
+
const parsedDate = new Date(value);
|
|
353
|
+
if (!isNaN(parsedDate.getTime())) {
|
|
354
|
+
date = parsedDate;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (date) {
|
|
358
|
+
this.updateInternalState(date);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
this.resetInternalState();
|
|
362
|
+
}
|
|
328
363
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
364
|
+
registerOnChange(fn) {
|
|
365
|
+
this.onChange = fn;
|
|
366
|
+
}
|
|
367
|
+
registerOnTouched(fn) {
|
|
368
|
+
this.onTouched = fn;
|
|
369
|
+
}
|
|
370
|
+
setDisabledState(isDisabled) {
|
|
371
|
+
this.isDisabled.set(isDisabled);
|
|
372
|
+
}
|
|
373
|
+
toggle() {
|
|
374
|
+
if (this.isBlocked())
|
|
375
|
+
return;
|
|
376
|
+
this.markAsTouched();
|
|
377
|
+
if (this.isOpen()) {
|
|
378
|
+
this.close();
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
this.open();
|
|
333
382
|
}
|
|
334
383
|
}
|
|
335
|
-
|
|
336
|
-
if (this.
|
|
337
|
-
|
|
338
|
-
this.
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
setTimeout(() => document.addEventListener('click', this.documentClickListener, true), 10);
|
|
351
|
-
});
|
|
384
|
+
open() {
|
|
385
|
+
if (this.isBlocked())
|
|
386
|
+
return;
|
|
387
|
+
this.markAsTouched();
|
|
388
|
+
this.isOpen.set(true);
|
|
389
|
+
this.addDocumentListener();
|
|
390
|
+
// Si hay fecha seleccionada, navegar a ese mes/año
|
|
391
|
+
const selected = this.selectedDate();
|
|
392
|
+
if (selected) {
|
|
393
|
+
this.currentMonth.set(selected.getMonth());
|
|
394
|
+
this.currentYear.set(selected.getFullYear());
|
|
395
|
+
}
|
|
352
396
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
397
|
+
close() {
|
|
398
|
+
this.isOpen.set(false);
|
|
399
|
+
this.removeDocumentListener();
|
|
400
|
+
this.markAsTouched();
|
|
401
|
+
}
|
|
402
|
+
selectDay(day) {
|
|
403
|
+
if (!day || this.isBlocked())
|
|
404
|
+
return;
|
|
405
|
+
const newDate = new Date(this.currentYear(), this.currentMonth(), day, this.selectedHour(), this.selectedMinute());
|
|
406
|
+
if (this.isDateDisabled(newDate))
|
|
407
|
+
return;
|
|
408
|
+
this.updateInternalState(newDate);
|
|
409
|
+
this.onChange(newDate.toISOString());
|
|
410
|
+
this.markAsTouched();
|
|
411
|
+
this.dateChange.emit(newDate);
|
|
412
|
+
// Solo cerrar automáticamente si es modo 'date'
|
|
413
|
+
if (this.mode() === 'date') {
|
|
414
|
+
this.close();
|
|
357
415
|
}
|
|
358
416
|
}
|
|
359
|
-
|
|
417
|
+
setHour12(hour12) {
|
|
418
|
+
if (this.isBlocked())
|
|
419
|
+
return;
|
|
420
|
+
// Convertir de 12h a 24h
|
|
421
|
+
let hour24;
|
|
422
|
+
const amPm = this.selectedAmPm();
|
|
423
|
+
if (hour12 === 12) {
|
|
424
|
+
hour24 = amPm === 'AM' ? 0 : 12;
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
hour24 = amPm === 'AM' ? hour12 : hour12 + 12;
|
|
428
|
+
}
|
|
429
|
+
this.selectedHour.set(hour24);
|
|
430
|
+
this.updateDateTime();
|
|
431
|
+
}
|
|
432
|
+
setMinute(minute) {
|
|
433
|
+
if (this.isBlocked())
|
|
434
|
+
return;
|
|
435
|
+
this.selectedMinute.set(minute);
|
|
436
|
+
this.updateDateTime();
|
|
437
|
+
}
|
|
438
|
+
setAmPm(amPm) {
|
|
439
|
+
if (this.isBlocked())
|
|
440
|
+
return;
|
|
441
|
+
const currentHour24 = this.selectedHour();
|
|
442
|
+
const currentHour12 = this.selectedHour12();
|
|
443
|
+
let newHour24;
|
|
444
|
+
if (amPm === 'AM') {
|
|
445
|
+
newHour24 = currentHour12 === 12 ? 0 : currentHour12;
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
newHour24 = currentHour12 === 12 ? 12 : currentHour12 + 12;
|
|
449
|
+
}
|
|
450
|
+
this.selectedAmPm.set(amPm);
|
|
451
|
+
this.selectedHour.set(newHour24);
|
|
452
|
+
this.updateDateTime();
|
|
453
|
+
}
|
|
360
454
|
previousMonth() {
|
|
361
455
|
const currentMonth = this.currentMonth();
|
|
362
456
|
const currentYear = this.currentYear();
|
|
@@ -379,85 +473,63 @@ class DateTimeFilter {
|
|
|
379
473
|
this.currentMonth.set(currentMonth + 1);
|
|
380
474
|
}
|
|
381
475
|
}
|
|
382
|
-
previousYear() {
|
|
383
|
-
|
|
476
|
+
previousYear() {
|
|
477
|
+
this.currentYear.set(this.currentYear() - 1);
|
|
478
|
+
}
|
|
479
|
+
nextYear() {
|
|
480
|
+
this.currentYear.set(this.currentYear() + 1);
|
|
481
|
+
}
|
|
384
482
|
today() {
|
|
385
483
|
const today = new Date();
|
|
386
484
|
this.updateInternalState(today);
|
|
387
485
|
this.onChange(today.toISOString());
|
|
388
486
|
this.markAsTouched();
|
|
389
487
|
this.dateChange.emit(today);
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
clear() {
|
|
395
|
-
this.resetInternalState();
|
|
396
|
-
this.onChange(null);
|
|
397
|
-
this.markAsTouched();
|
|
398
|
-
this.dateChange.emit(null);
|
|
399
|
-
this.close();
|
|
400
|
-
}
|
|
401
|
-
// Time setters
|
|
402
|
-
setHour12(hour12) {
|
|
403
|
-
if (this.isDisabled())
|
|
404
|
-
return;
|
|
405
|
-
const amPm = this.selectedAmPm();
|
|
406
|
-
const hour24 = hour12 === 12 ? (amPm === 'AM' ? 0 : 12) : (amPm === 'AM' ? hour12 : hour12 + 12);
|
|
407
|
-
this.selectedHour.set(hour24);
|
|
408
|
-
this.updateDateTime();
|
|
409
|
-
}
|
|
410
|
-
setMinute(minute) {
|
|
411
|
-
if (this.isDisabled())
|
|
412
|
-
return;
|
|
413
|
-
this.selectedMinute.set(minute);
|
|
414
|
-
this.updateDateTime();
|
|
415
|
-
}
|
|
416
|
-
setAmPm(amPm) {
|
|
417
|
-
if (this.isDisabled())
|
|
418
|
-
return;
|
|
419
|
-
const currentHour12 = this.selectedHour12();
|
|
420
|
-
const newHour24 = amPm === 'AM' ? (currentHour12 === 12 ? 0 : currentHour12) : (currentHour12 === 12 ? 12 : currentHour12 + 12);
|
|
421
|
-
this.selectedAmPm.set(amPm);
|
|
422
|
-
this.selectedHour.set(newHour24);
|
|
423
|
-
this.updateDateTime();
|
|
424
|
-
}
|
|
425
|
-
updateDateTime() {
|
|
426
|
-
const selected = this.selectedDate();
|
|
427
|
-
if (!selected)
|
|
428
|
-
return;
|
|
429
|
-
const newDate = new Date(selected);
|
|
430
|
-
newDate.setHours(this.selectedHour());
|
|
431
|
-
newDate.setMinutes(this.selectedMinute());
|
|
432
|
-
this.selectedDate.set(newDate);
|
|
433
|
-
// Update input text value
|
|
434
|
-
const formatted = this.formatDateForInput(newDate);
|
|
435
|
-
this.inputTextValue.set(formatted);
|
|
436
|
-
this.onChange(newDate.toISOString());
|
|
488
|
+
if (this.mode() === 'date') {
|
|
489
|
+
this.close();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
clear() {
|
|
493
|
+
this.resetInternalState();
|
|
494
|
+
this.onChange(null);
|
|
437
495
|
this.markAsTouched();
|
|
438
|
-
this.dateChange.emit(
|
|
439
|
-
this.
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
496
|
+
this.dateChange.emit(null);
|
|
497
|
+
this.close();
|
|
498
|
+
}
|
|
499
|
+
onKeyDown(event) {
|
|
500
|
+
if (this.isBlocked())
|
|
501
|
+
return;
|
|
502
|
+
if (event.key === 'Escape') {
|
|
503
|
+
this.close();
|
|
504
|
+
}
|
|
505
|
+
else if (event.key === 'Tab') {
|
|
506
|
+
this.markAsTouched();
|
|
507
|
+
this.close();
|
|
508
|
+
}
|
|
443
509
|
}
|
|
444
|
-
// Validation helpers
|
|
445
510
|
isDaySelected(day) {
|
|
446
511
|
if (!day)
|
|
447
512
|
return false;
|
|
448
513
|
const selected = this.selectedDate();
|
|
449
|
-
|
|
514
|
+
if (!selected)
|
|
515
|
+
return false;
|
|
516
|
+
return (selected.getDate() === day &&
|
|
517
|
+
selected.getMonth() === this.currentMonth() &&
|
|
518
|
+
selected.getFullYear() === this.currentYear());
|
|
450
519
|
}
|
|
451
520
|
isToday(day) {
|
|
452
521
|
if (!day)
|
|
453
522
|
return false;
|
|
454
523
|
const today = new Date();
|
|
455
|
-
return today.getDate() === day &&
|
|
524
|
+
return (today.getDate() === day &&
|
|
525
|
+
today.getMonth() === this.currentMonth() &&
|
|
526
|
+
today.getFullYear() === this.currentYear());
|
|
456
527
|
}
|
|
457
528
|
isDayDisabled(day) {
|
|
458
529
|
if (!day)
|
|
459
530
|
return true;
|
|
460
|
-
|
|
531
|
+
const date = new Date(this.currentYear(), this.currentMonth(), day);
|
|
532
|
+
return this.isDateDisabled(date);
|
|
461
533
|
}
|
|
462
534
|
isDateDisabled(date) {
|
|
463
535
|
const minDate = this.minDate();
|
|
@@ -468,371 +540,278 @@ class DateTimeFilter {
|
|
|
468
540
|
return true;
|
|
469
541
|
return false;
|
|
470
542
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
provide: NG_VALUE_ACCESSOR,
|
|
475
|
-
useExisting: forwardRef(() => DateTimeFilter),
|
|
476
|
-
multi: true,
|
|
477
|
-
},
|
|
478
|
-
], ngImport: i0, template: "<div class=\"datetime-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div\r\n class=\"chip-input-wrapper\"\r\n [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\"\r\n >\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\r\n class=\"mask-char\"\r\n [class.mask-char-filled]=\"part.filled\"\r\n [class.mask-char-placeholder]=\"!part.filled\"\r\n >\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input\r\n type=\"text\"\r\n [value]=\"inputTextValue()\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\"\r\n [placeholder]=\"''\"\r\n class=\"chip-input\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n\r\n <button\r\n type=\"button\"\r\n class=\"calendar-icon-button\"\r\n (click)=\"toggle(item.value)\"\r\n title=\"Abrir calendario\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\"\r\n >\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path\r\n 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 />\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\">\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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>\r\n</div>\r\n", styles: [".datetime-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;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;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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip-input-wrapper.has-value .floating-label{opacity:.6}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 16px;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, 14px);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}.chip-input:disabled{cursor:not-allowed;opacity:.6}.chip-input-mask{position:absolute;left:16px;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);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);z-index:1;display:flex}.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:1}.calendar-icon-button:hover{background-color:#7878611a;color:var(--schemes-on-surface-variant, #454733)}.calendar-icon-button:active{background-color:#78786133}.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;right: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}.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 }] });
|
|
479
|
-
}
|
|
480
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DateTimeFilter, decorators: [{
|
|
481
|
-
type: Component,
|
|
482
|
-
args: [{ selector: 'lib-date-time-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule], providers: [
|
|
483
|
-
{
|
|
484
|
-
provide: NG_VALUE_ACCESSOR,
|
|
485
|
-
useExisting: forwardRef(() => DateTimeFilter),
|
|
486
|
-
multi: true,
|
|
487
|
-
},
|
|
488
|
-
], template: "<div class=\"datetime-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div\r\n class=\"chip-input-wrapper\"\r\n [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\"\r\n >\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\r\n class=\"mask-char\"\r\n [class.mask-char-filled]=\"part.filled\"\r\n [class.mask-char-placeholder]=\"!part.filled\"\r\n >\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input\r\n type=\"text\"\r\n [value]=\"inputTextValue()\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\"\r\n [placeholder]=\"''\"\r\n class=\"chip-input\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n\r\n <button\r\n type=\"button\"\r\n class=\"calendar-icon-button\"\r\n (click)=\"toggle(item.value)\"\r\n title=\"Abrir calendario\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\"\r\n >\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path\r\n 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 />\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\">\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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>\r\n</div>\r\n", styles: [".datetime-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;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;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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip-input-wrapper.has-value .floating-label{opacity:.6}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 16px;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, 14px);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}.chip-input:disabled{cursor:not-allowed;opacity:.6}.chip-input-mask{position:absolute;left:16px;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);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);z-index:1;display:flex}.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:1}.calendar-icon-button:hover{background-color:#7878611a;color:var(--schemes-on-surface-variant, #454733)}.calendar-icon-button:active{background-color:#78786133}.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;right: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}.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"] }]
|
|
489
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], clearTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTrigger", required: false }] }] } });
|
|
490
|
-
|
|
491
|
-
class PaginationComponent {
|
|
492
|
-
page = 1;
|
|
493
|
-
pageSize = 10;
|
|
494
|
-
totalItems = 0;
|
|
495
|
-
showPageSizeSelector = false;
|
|
496
|
-
pageSizeOptions = [5, 10, 20, 50];
|
|
497
|
-
pageChange = new EventEmitter();
|
|
498
|
-
pageSizeChange = new EventEmitter();
|
|
499
|
-
pageSizeValue = signal(this.pageSize, ...(ngDevMode ? [{ debugName: "pageSizeValue" }] : []));
|
|
500
|
-
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
501
|
-
isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
502
|
-
showPageSizeMenu = signal(false, ...(ngDevMode ? [{ debugName: "showPageSizeMenu" }] : []));
|
|
503
|
-
totalPages = computed(() => {
|
|
504
|
-
const size = this.pageSizeValue();
|
|
505
|
-
const total = this.totalItems;
|
|
506
|
-
return size > 0 ? Math.ceil(total / size) : 1;
|
|
507
|
-
}, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
|
|
508
|
-
pages = computed(() => {
|
|
509
|
-
const tp = this.totalPages();
|
|
510
|
-
return Array.from({ length: tp }, (_, i) => i + 1);
|
|
511
|
-
}, ...(ngDevMode ? [{ debugName: "pages" }] : []));
|
|
512
|
-
selectedPageSize = computed(() => this.pageSizeValue(), ...(ngDevMode ? [{ debugName: "selectedPageSize" }] : []));
|
|
513
|
-
goToPage(p) {
|
|
514
|
-
if (p < 1 || p > this.totalPages())
|
|
543
|
+
updateDateTime() {
|
|
544
|
+
const selected = this.selectedDate();
|
|
545
|
+
if (!selected)
|
|
515
546
|
return;
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
this.
|
|
520
|
-
this.
|
|
547
|
+
const newDate = new Date(selected);
|
|
548
|
+
newDate.setHours(this.selectedHour());
|
|
549
|
+
newDate.setMinutes(this.selectedMinute());
|
|
550
|
+
this.updateInternalState(newDate);
|
|
551
|
+
this.onChange(newDate.toISOString());
|
|
552
|
+
this.markAsTouched();
|
|
553
|
+
this.dateChange.emit(newDate);
|
|
521
554
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
this.
|
|
525
|
-
|
|
526
|
-
|
|
555
|
+
// Manejo de input de texto (DD/MM/YYYY)
|
|
556
|
+
onInputChange(event) {
|
|
557
|
+
if (this.isBlocked())
|
|
558
|
+
return;
|
|
559
|
+
const input = event.target;
|
|
560
|
+
let value = input.value;
|
|
561
|
+
// Eliminar todo lo que no sea número
|
|
562
|
+
const numbersOnly = value.replace(/\D/g, '');
|
|
563
|
+
// Limitar a 8 dígitos (DDMMYYYY)
|
|
564
|
+
const limitedNumbers = numbersOnly.slice(0, 8);
|
|
565
|
+
// Formatear con barras: DD/MM/YYYY
|
|
566
|
+
let formatted = '';
|
|
567
|
+
if (limitedNumbers.length > 0) {
|
|
568
|
+
formatted = limitedNumbers.slice(0, 2);
|
|
569
|
+
if (limitedNumbers.length > 2) {
|
|
570
|
+
formatted += '/' + limitedNumbers.slice(2, 4);
|
|
571
|
+
}
|
|
572
|
+
if (limitedNumbers.length > 4) {
|
|
573
|
+
formatted += '/' + limitedNumbers.slice(4, 8);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
this.inputTextValue.set(formatted);
|
|
577
|
+
input.value = formatted;
|
|
578
|
+
this.markAsTouched();
|
|
579
|
+
// Solo intentamos parsear cuando tenemos DD/MM/YYYY completo (10 caracteres)
|
|
580
|
+
if (formatted.length === 10) {
|
|
581
|
+
const parsedDate = this.parseDateInput(formatted);
|
|
582
|
+
if (parsedDate) {
|
|
583
|
+
if (this.isDateDisabled(parsedDate)) {
|
|
584
|
+
// Está fuera de rango, dejamos el texto pero no cambiamos el valor
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
this.updateInternalState(parsedDate);
|
|
588
|
+
this.onChange(parsedDate.toISOString());
|
|
589
|
+
this.dateChange.emit(parsedDate);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
else if (formatted.trim() === '') {
|
|
593
|
+
// Si el campo queda vacío, limpiamos el valor
|
|
594
|
+
this.resetInternalState();
|
|
595
|
+
this.onChange(null);
|
|
596
|
+
this.dateChange.emit(null);
|
|
597
|
+
}
|
|
527
598
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
type: Component,
|
|
533
|
-
args: [{ selector: 'lib-pagination', standalone: true, imports: [CommonModule], template: "<div class=\"pagination-container\">\r\n <div class=\"pagination\">\r\n <!-- Bot\u00F3n doble atr\u00E1s -->\r\n <button class=\"icon-button\" (click)=\"goToPage(1)\" [disabled]=\"page === 1\">\r\n \u00AB\u00AB\r\n </button>\r\n\r\n <!-- Bot\u00F3n atr\u00E1s -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page - 1)\" [disabled]=\"page === 1\">\r\n \u00AB\r\n </button>\r\n\r\n <!-- N\u00FAmeros de p\u00E1gina -->\r\n <div class=\"pages\">\r\n <button\r\n class=\"page-btn\"\r\n *ngFor=\"let p of pages(); let idx = index\"\r\n [class.active]=\"page === idx + 1\"\r\n (click)=\"goToPage(idx + 1)\"\r\n >\r\n {{ idx + 1 }}\r\n </button>\r\n </div>\r\n\r\n <!-- Bot\u00F3n siguiente -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page + 1)\" [disabled]=\"page === totalPages()\">\r\n \u00BB\r\n </button>\r\n\r\n <!-- Bot\u00F3n doble adelante -->\r\n <button class=\"icon-button\" (click)=\"goToPage(totalPages())\" [disabled]=\"page === totalPages()\">\r\n \u00BB\u00BB\r\n </button>\r\n </div>\r\n\r\n <!-- Selector Items por p\u00E1gina -->\r\n <div *ngIf=\"showPageSizeSelector\">\r\n <div class=\"pagination-v-4\">\r\n <div class=\"label-pagination\">Items por p\u00E1gina</div>\r\n <div class=\"elements-pagination\">\r\n <div class=\"split-button\" (click)=\"togglePageSizeMenu()\">\r\n <div class=\"leading-button\">\r\n <div class=\"state-layer\">\r\n <div class=\"label\">{{ pageSizeValue() }}</div>\r\n </div>\r\n </div>\r\n <div class=\"trailing-button\">\r\n <div class=\"arrow\" [class.open]=\"isOpen()\">\r\n <svg class=\"arrow\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Men\u00FA desplegable -->\r\n <div class=\"page-size-menu\" *ngIf=\"showPageSizeMenu()\">\r\n <div\r\n class=\"menu-option\"\r\n *ngFor=\"let opt of pageSizeOptions\"\r\n [class.active]=\"opt === pageSizeValue()\"\r\n (click)=\"selectPageSize(opt)\"\r\n >\r\n {{ opt }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".pagination-container{display:flex;flex-direction:row;justify-content:center;width:100%;padding:8px 0;position:relative}.pagination{display:flex;align-items:center;gap:12px;padding:12px;justify-content:center;flex:1}.icon-button{width:40px;height:40px;border-radius:50%;background:var(--primary, #596300);color:var(--surface, #ffffff);border:none;cursor:pointer;font-size:16px;font-weight:700;display:flex;align-items:center;justify-content:center;box-shadow:0 1px 2px #00000026;transition:background .2s ease,transform .1s ease}.icon-button:disabled{background:#969696;color:var(--on-surface, #171c1f);opacity:.45;cursor:not-allowed}.pages{display:flex;gap:4px;overflow:hidden;border-radius:20px}.page-btn{background:var(--secondary-container, #dee58f);width:40px;height:40px;border:none;cursor:pointer;padding:8px 14px;font-size:14px;color:var(--schemes-on-surface, #3a3a3a);font-family:Roboto,sans-serif;border-radius:8px;transition:background .2s ease}.page-btn:hover:not(.active){background:var(--schemes-on-secondary-container, #61661f);color:var(--schemes-secondary-container, #dee58f)}.page-btn.active{background:var(--schemes-primary, #596300);color:var(--schemes-on-primary, #ffffff);font-weight:600;border-radius:20px}.pagination-v-4{display:flex;gap:10px;align-items:center;margin-left:auto}.label-pagination{font-size:14px;font-weight:600;color:var(--schemes-on-surface)}.elements-pagination{position:relative;display:flex;gap:4px;border-radius:20px}.split-button{display:flex;cursor:pointer;border-radius:20px;overflow:hidden}.leading-button{background:var(--schemes-secondary-container);border-radius:20px 4px 4px 20px;display:flex;align-items:center;height:40px}.state-layer{padding:10px 16px;background-color:#dee58f;margin-right:4px;border-radius:8px}.state-layer:open{color:#f5f5e0;background-color:#596300}.label{font-size:14px;font-weight:500;color:var(--schemes-on-secondary-container)}.trailing-button{background:var(--secondary-container, #dee58f);padding-left:12px;padding-right:12px;border:none;cursor:pointer;font-size:14px;color:var(--schemes-on-surface, #3a3a3a);font-family:Roboto,sans-serif;border-radius:8px;transition:background .2s ease;align-items:center;align-content:center}.arrow{width:20px;height:20px;color:#171c1f;transition:transform .25s ease}.arrow.open{transform:rotate(180deg)}.page-size-menu{background:#f5f5e0;position:absolute;min-width:100px;border-radius:4px;box-shadow:0 2px 8px #0003;overflow:hidden;z-index:999;bottom:50px;right:0;transform-origin:top right}.menu-option{padding:8px 12px;cursor:pointer}.menu-option:hover{background:#dee58f5b}.menu-option.active{background:#dee58f;color:#61661f}\n"] }]
|
|
534
|
-
}], propDecorators: { page: [{
|
|
535
|
-
type: Input
|
|
536
|
-
}], pageSize: [{
|
|
537
|
-
type: Input
|
|
538
|
-
}], totalItems: [{
|
|
539
|
-
type: Input
|
|
540
|
-
}], showPageSizeSelector: [{
|
|
541
|
-
type: Input
|
|
542
|
-
}], pageSizeOptions: [{
|
|
543
|
-
type: Input
|
|
544
|
-
}], pageChange: [{
|
|
545
|
-
type: Output
|
|
546
|
-
}], pageSizeChange: [{
|
|
547
|
-
type: Output
|
|
548
|
-
}] } });
|
|
549
|
-
|
|
550
|
-
const STATUS_TONE_STYLES = {
|
|
551
|
-
success: { bg: '#E6F4EA', color: '#1E8E3E' },
|
|
552
|
-
error: { bg: '#FCE8E6', color: '#D93025' },
|
|
553
|
-
warning: { bg: '#FFF4E5', color: '#E67E22' },
|
|
554
|
-
info: { bg: '#E6F4EA', color: '#0077B6' },
|
|
555
|
-
neutral: { bg: '#F4F4F4', color: '#5F6368' },
|
|
556
|
-
};
|
|
557
|
-
class Table {
|
|
558
|
-
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
559
|
-
data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
560
|
-
actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
|
|
561
|
-
showActions = input(true, ...(ngDevMode ? [{ debugName: "showActions" }] : []));
|
|
562
|
-
openedMenu = signal(null, ...(ngDevMode ? [{ debugName: "openedMenu" }] : []));
|
|
563
|
-
selectedRow = signal(null, ...(ngDevMode ? [{ debugName: "selectedRow" }] : []));
|
|
564
|
-
sortColumn = signal(null, ...(ngDevMode ? [{ debugName: "sortColumn" }] : []));
|
|
565
|
-
sortDirection = signal('desc', ...(ngDevMode ? [{ debugName: "sortDirection" }] : []));
|
|
566
|
-
optionSelected = output();
|
|
567
|
-
iconAction = output();
|
|
568
|
-
statusToneMap = input({}, ...(ngDevMode ? [{ debugName: "statusToneMap" }] : []));
|
|
569
|
-
chips;
|
|
570
|
-
ngAfterViewInit() {
|
|
571
|
-
setTimeout(() => {
|
|
572
|
-
const chipEls = this.chips.map(c => c.nativeElement);
|
|
573
|
-
const parentWidth = chipEls[0]?.parentElement.offsetWidth || 0;
|
|
574
|
-
const widths = chipEls.map(el => el.scrollWidth);
|
|
575
|
-
const maxContentWidth = Math.max(...widths);
|
|
576
|
-
const finalWidth = Math.min(maxContentWidth, parentWidth);
|
|
577
|
-
chipEls.forEach(el => {
|
|
578
|
-
el.style.width = finalWidth + 'px';
|
|
579
|
-
});
|
|
580
|
-
});
|
|
599
|
+
onInputFocus() {
|
|
600
|
+
if (this.isBlocked())
|
|
601
|
+
return;
|
|
602
|
+
this.open();
|
|
581
603
|
}
|
|
582
|
-
|
|
583
|
-
|
|
604
|
+
parseDateInput(input) {
|
|
605
|
+
if (!input || input.trim() === '')
|
|
606
|
+
return null;
|
|
607
|
+
const match = input.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
|
608
|
+
if (match) {
|
|
609
|
+
const day = parseInt(match[1], 10);
|
|
610
|
+
const month = parseInt(match[2], 10) - 1;
|
|
611
|
+
const year = parseInt(match[3], 10);
|
|
612
|
+
if (day >= 1 && day <= 31 && month >= 0 && month <= 11 && year >= 1900 && year <= 2100) {
|
|
613
|
+
const date = new Date(year, month, day);
|
|
614
|
+
if (date.getDate() === day && date.getMonth() === month && date.getFullYear() === year) {
|
|
615
|
+
return date;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return null;
|
|
584
620
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
621
|
+
formatDateForInput(date) {
|
|
622
|
+
const day = date.getDate().toString().padStart(2, '0');
|
|
623
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
624
|
+
const year = date.getFullYear();
|
|
625
|
+
return `${day}/${month}/${year}`;
|
|
588
626
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
627
|
+
updateInternalState(date) {
|
|
628
|
+
this.selectedDate.set(date);
|
|
629
|
+
this.currentMonth.set(date.getMonth());
|
|
630
|
+
this.currentYear.set(date.getFullYear());
|
|
631
|
+
this.selectedHour.set(date.getHours());
|
|
632
|
+
this.selectedMinute.set(date.getMinutes());
|
|
633
|
+
this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');
|
|
634
|
+
const formatted = this.formatDateForInput(date);
|
|
635
|
+
this.inputTextValue.set(formatted);
|
|
597
636
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
637
|
+
resetInternalState() {
|
|
638
|
+
this.selectedDate.set(null);
|
|
639
|
+
this.inputTextValue.set('');
|
|
640
|
+
this.selectedHour.set(0);
|
|
641
|
+
this.selectedMinute.set(0);
|
|
642
|
+
this.selectedAmPm.set('AM');
|
|
603
643
|
}
|
|
604
|
-
|
|
605
|
-
if (
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
case 'number':
|
|
609
|
-
case 'money':
|
|
610
|
-
case 'percentage':
|
|
611
|
-
return 'right';
|
|
612
|
-
case 'status':
|
|
613
|
-
return 'center';
|
|
614
|
-
default:
|
|
615
|
-
return 'left';
|
|
644
|
+
markAsTouched() {
|
|
645
|
+
if (!this.isTouched()) {
|
|
646
|
+
this.isTouched.set(true);
|
|
647
|
+
this.onTouched();
|
|
616
648
|
}
|
|
617
649
|
}
|
|
618
|
-
|
|
619
|
-
if (
|
|
620
|
-
|
|
621
|
-
switch (col.type) {
|
|
622
|
-
case 'money':
|
|
623
|
-
return new Intl.NumberFormat('es-CO', {
|
|
624
|
-
style: 'currency',
|
|
625
|
-
currency: 'COP',
|
|
626
|
-
minimumFractionDigits: 0
|
|
627
|
-
}).format(value);
|
|
628
|
-
case 'number':
|
|
629
|
-
return new Intl.NumberFormat('es-CO').format(value);
|
|
630
|
-
case 'percentage':
|
|
631
|
-
return `${value}%`;
|
|
632
|
-
case 'date':
|
|
633
|
-
const d = new Date(value);
|
|
634
|
-
return d.toLocaleDateString('es-CO'); // dd/mm/yyyy
|
|
635
|
-
default:
|
|
636
|
-
return String(value);
|
|
650
|
+
addDocumentListener() {
|
|
651
|
+
if (this.documentClickListener) {
|
|
652
|
+
this.removeDocumentListener();
|
|
637
653
|
}
|
|
654
|
+
this.ngZone.runOutsideAngular(() => {
|
|
655
|
+
this.documentClickListener = (event) => {
|
|
656
|
+
const target = event.target;
|
|
657
|
+
if (!this.elementRef.nativeElement.contains(target)) {
|
|
658
|
+
this.ngZone.run(() => {
|
|
659
|
+
if (this.isOpen()) {
|
|
660
|
+
this.markAsTouched();
|
|
661
|
+
this.close();
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
setTimeout(() => {
|
|
667
|
+
document.addEventListener('click', this.documentClickListener, true);
|
|
668
|
+
}, 10);
|
|
669
|
+
});
|
|
638
670
|
}
|
|
639
|
-
|
|
640
|
-
if (
|
|
641
|
-
|
|
671
|
+
removeDocumentListener() {
|
|
672
|
+
if (this.documentClickListener) {
|
|
673
|
+
document.removeEventListener('click', this.documentClickListener, true);
|
|
674
|
+
this.documentClickListener = undefined;
|
|
642
675
|
}
|
|
643
|
-
const key = this.normalizeStatus(value);
|
|
644
|
-
const tone = this.statusToneMap()?.[key] ?? 'neutral';
|
|
645
|
-
return STATUS_TONE_STYLES[tone];
|
|
646
676
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
.toLowerCase()
|
|
650
|
-
.trim()
|
|
651
|
-
.replace(/\s+/g, '_');
|
|
677
|
+
markTouched() {
|
|
678
|
+
this.markAsTouched();
|
|
652
679
|
}
|
|
653
680
|
/**
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
* que recibe la fila y retorna las acciones correspondientes.
|
|
681
|
+
* Obtiene la fecha seleccionada en formato ISO string
|
|
682
|
+
* @returns string ISO o null si no hay fecha seleccionada
|
|
657
683
|
*/
|
|
658
|
-
|
|
659
|
-
const
|
|
660
|
-
|
|
661
|
-
return [];
|
|
662
|
-
if (typeof acts === 'function') {
|
|
663
|
-
try {
|
|
664
|
-
return acts(row) ?? [];
|
|
665
|
-
}
|
|
666
|
-
catch {
|
|
667
|
-
return [];
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
return acts;
|
|
684
|
+
getISOString() {
|
|
685
|
+
const date = this.selectedDate();
|
|
686
|
+
return date ? date.toISOString() : null;
|
|
671
687
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
const
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
return dir === 'asc'
|
|
683
|
-
? new Date(x).getTime() - new Date(y).getTime()
|
|
684
|
-
: new Date(y).getTime() - new Date(x).getTime();
|
|
685
|
-
}
|
|
686
|
-
// Caso: números
|
|
687
|
-
if (!isNaN(Number(x)) && !isNaN(Number(y))) {
|
|
688
|
-
return dir === 'asc' ? Number(x) - Number(y) : Number(y) - Number(x);
|
|
688
|
+
/**
|
|
689
|
+
* Establece la fecha desde un string ISO
|
|
690
|
+
* @param isoString - Fecha en formato ISO
|
|
691
|
+
*/
|
|
692
|
+
setFromISOString(isoString) {
|
|
693
|
+
if (isoString) {
|
|
694
|
+
const date = new Date(isoString);
|
|
695
|
+
if (!isNaN(date.getTime())) {
|
|
696
|
+
this.writeValue(date);
|
|
697
|
+
this.onChange(isoString);
|
|
689
698
|
}
|
|
690
|
-
// Caso: strings
|
|
691
|
-
return dir === 'asc'
|
|
692
|
-
? x.toString().localeCompare(y.toString())
|
|
693
|
-
: y.toString().localeCompare(x.toString());
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
isDate(value) {
|
|
697
|
-
return (typeof value === 'string' &&
|
|
698
|
-
value.length > 5 &&
|
|
699
|
-
!isNaN(Date.parse(value)));
|
|
700
|
-
}
|
|
701
|
-
onSort(col) {
|
|
702
|
-
if (this.sortColumn() === col.key) {
|
|
703
|
-
// cambiar asc <-> desc
|
|
704
|
-
this.sortDirection.set(this.sortDirection() === 'asc' ? 'desc' : 'asc');
|
|
705
699
|
}
|
|
706
700
|
else {
|
|
707
|
-
|
|
708
|
-
this.sortColumn.set(col.key);
|
|
709
|
-
this.sortDirection.set('desc');
|
|
701
|
+
this.clear();
|
|
710
702
|
}
|
|
711
703
|
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Table, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
720
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: Table, isStandalone: true, selector: "lib-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, statusToneMap: { classPropertyName: "statusToneMap", publicName: "statusToneMap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionSelected: "optionSelected", iconAction: "iconAction" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "chips", predicate: ["status-chip"], descendants: true }], ngImport: i0, template: "<div class=\"table-wrapper\">\r\n <table class=\"inner-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th\r\n (click)=\"col.sortable !== false && onSort(col)\"\r\n [class.sortable]=\"col.sortable !== false\"\r\n [class]=\"getAlignment(col)\"\r\n >\r\n {{ col.label }}\r\n\r\n <!-- iconos de orden opcionales -->\r\n @if (sortColumn() === col.key) {\r\n <span class=\"sort-icon\">\r\n {{ sortDirection() === 'asc' ? '\u25B2' : '\u25BC' }}\r\n </span>\r\n }\r\n </th>\r\n }\r\n\r\n <!-- columna para acciones -->\r\n @if (showActions()) {\r\n <th></th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of sortData(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td [class]=\"getAlignment(col)\">\r\n @if (col.type === 'status') { @let style =\r\n getStatusStyle(row[col.key]);\r\n <span\r\n class=\"status-chip\"\r\n id=\"status-chip\"\r\n [style.background-color]=\"style.bg\"\r\n [style.color]=\"style.color\"\r\n >\r\n <span\r\n class=\"status-dot\"\r\n [style.background-color]=\"style.color\"\r\n ></span>\r\n\r\n {{ row[col.key]?.toString().toUpperCase() }}\r\n </span>\r\n\r\n } @else if (col.type === 'icon-button') {\r\n\r\n <button (click)=\"onIconColumnClick(col, row, $event)\">\r\n <span\r\n class=\"icon\"\r\n [class]=\"col.icon\"\r\n [style.color]=\"col.iconColor\"\r\n ></span>\r\n </button>\r\n\r\n } @else { {{ formatValue(col, row[col.key]) }} }\r\n </td>\r\n }\r\n\r\n <!-- Celda de acciones -->\r\n @if (showActions()) {\r\n <td class=\"acciones-cell\">\r\n <div class=\"menu-acciones\">\r\n <button class=\"icon-button\" (click)=\"openModal(row)\">\r\n <div class=\"content\">\r\n <div class=\"state-layer\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"more-vert\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </button>\r\n @if(selectedRow()?.['id'] === row['id']){\r\n <div class=\"modal-options\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-content\">\r\n <ul>\r\n @for (option of getActionsForRow(row); track $index) {\r\n <li\r\n class=\"option-item\"\r\n [style.color]=\"option.color\"\r\n (click)=\"onOptionClick(option, row)\"\r\n >\r\n <span class=\"icon\" [class]=\"option.icon\"></span>\r\n <span class=\"label\">{{ option.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".table-wrapper{width:100%;border-radius:20px;border:1px solid #c7c7ad}.inner-table{width:100%;border-collapse:separate;font-size:14px;border-spacing:0;border-radius:20px;background:#ebe8d6}.inner-table thead{background:#f0f0db}.inner-table thead tr th:first-child{border-top-left-radius:20px}.inner-table thead tr th:last-child{border-top-right-radius:20px}.inner-table th{text-align:left;padding:12px 16px;font-weight:600;color:#3a3a3a;text-transform:uppercase}.inner-table td{padding:12px 16px;color:#4a4a4a;border-top:1px solid #c7c7ad;table-layout:auto}.acciones-cell{text-align:center;padding:6px;position:relative}.menu-acciones{display:flex;align-items:center;justify-content:center;position:relative}button{background-color:transparent;border:none}.icon-button{background-color:var(--secondary-container, #dee58f);width:36px;height:36px;border:none;cursor:pointer;padding:0;border-radius:100%;display:flex;align-items:center;justify-content:center}.icon-button:hover{background:#0000000f}.more-vert{color:#4a4a4a;display:block}.modal-options{display:flex;justify-items:center;align-items:center;background-color:var(--surface-container-lowest, #ffffff);width:200px;border-radius:8px;position:absolute;top:100%;right:0;z-index:99}.modal-content{width:100%;border-radius:8px;border:1px solid var(--outline-variant, #c7c7ad);overflow:hidden}.option-item{display:flex;align-items:center;height:56px;padding:8px 12px;cursor:pointer}.option-item:hover{background-color:#0000001a}.option-item:active{background-color:#dee58f}.icon{margin-right:8px}.option-item .label{font-weight:500;font-size:16px}.icon-refresh,.icon-delete,.icon-edit,.icon-activate,.icon-deactivate,.icon-view,.icon-sanction,.icon-file{width:24px;height:24px;background-color:currentColor;color:currentColor;-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;mask-size:contain;mask-repeat:no-repeat;display:inline-block;cursor:pointer}.icon-refresh{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>')}.icon-delete{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>')}.icon-edit{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>')}.icon-activate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>')}.icon-deactivate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>')}.icon-view{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>')}.icon-sanction{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>')}.icon-file{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>')}th.left.sortable,th.left,td.left{text-align:left}th.right.sortable,th.right,td.right{text-align:right}th.center.sortable,th.center,td.center{text-align:center}.status-chip{display:inline-flex;align-items:center;gap:.5rem;width:100%;padding:.375rem .75rem;border-radius:8px;font-size:.875rem;font-weight:500;white-space:nowrap}.status-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.sortable:hover{opacity:.7}.sort-icon{margin-left:6px;font-size:12px;pointer-events:none}\n"] });
|
|
704
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DateTimePicker, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
705
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DateTimePicker, isStandalone: true, selector: "lib-date-time-picker", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, providers: [
|
|
706
|
+
{
|
|
707
|
+
provide: NG_VALUE_ACCESSOR,
|
|
708
|
+
useExisting: forwardRef(() => DateTimePicker),
|
|
709
|
+
multi: true,
|
|
710
|
+
},
|
|
711
|
+
], ngImport: i0, template: "<div class=\"datetime-container\">\r\n <div\r\n class=\"datetime-header\"\r\n [class.active]=\"isOpen()\"\r\n [class.disabled]=\"isBlocked()\"\r\n [class.readonly]=\"isBlocked()\"\r\n (click)=\"!isBlocked() && toggle()\"\r\n (keydown)=\"!isBlocked() && onKeyDown($event)\"\r\n tabindex=\"0\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"datetime-input\"\r\n [value]=\"displayValue()\"\r\n [placeholder]=\"placeholder()\"\r\n (input)=\"onInputChange($event)\"\r\n (focus)=\"!isBlocked() && onInputFocus()\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"isDisabled()\"\r\n [readOnly]=\"readonly()\"\r\n />\r\n\r\n <div class=\"header-icons\">\r\n @if (selectedDate()) {\r\n <span\r\n class=\"clear-icon\"\r\n (click)=\"!isBlocked() && clear(); $event.stopPropagation()\"\r\n title=\"Limpiar\"\r\n >\r\n \u00D7\r\n </span>\r\n }\r\n <span class=\"arrow\" [class.open]=\"isOpen()\"></span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (isOpen()) {\r\n<div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n del calendario -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">{{ monthName() }} {{ currentYear() }}</div>\r\n\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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 del mes -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n {{ day || '' }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Selector de tiempo (solo si mode === 'datetime') -->\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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\r\n <!-- Botones de acci\u00F3n -->\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 @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", styles: [".datetime-container{position:relative;width:100%}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:12px 15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-input{flex:1;border:none;outline:none;background:transparent;font-size:1.3rem;color:#454733;padding:0;margin:0}.datetime-input::placeholder{color:#787861}.datetime-input:disabled{cursor:not-allowed}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled,.datetime-header.readonly{pointer-events:none;opacity:.6;cursor:not-allowed}.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:20px;height:20px;background-image:url(\"data:image/svg+xml,%3csvg 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-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath 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' /%3e%3cpath d='M16 3l0 4' /%3e%3cpath d='M8 3l0 4' /%3e%3cpath d='M4 11l16 0' /%3e%3cpath d='M8 15h2v2h-2z' /%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:20px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='currentColor' class='icon icon-tabler icons-tabler-filled icon-tabler-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath d='M16 2a1 1 0 0 1 .993 .883l.007 .117v1h1a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h1v-1a1 1 0 0 1 1.993 -.117l.007 .117v1h6v-1a1 1 0 0 1 1 -1m3 7h-14v9.625c0 .705 .386 1.286 .883 1.366l.117 .009h12c.513 0 .936 -.53 .993 -1.215l.007 -.16z' /%3e%3cpath d='M8 14h2v2h-2z' /%3e%3c/svg%3e\")}.dropdown{position:absolute;top:100%;left:0;right: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}.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:10px 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"] });
|
|
721
712
|
}
|
|
722
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
713
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DateTimePicker, decorators: [{
|
|
723
714
|
type: Component,
|
|
724
|
-
args: [{ selector: 'lib-table', imports: [], standalone: true, template: "<div class=\"table-wrapper\">\r\n <table class=\"inner-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th\r\n (click)=\"col.sortable !== false && onSort(col)\"\r\n [class.sortable]=\"col.sortable !== false\"\r\n [class]=\"getAlignment(col)\"\r\n >\r\n {{ col.label }}\r\n\r\n <!-- iconos de orden opcionales -->\r\n @if (sortColumn() === col.key) {\r\n <span class=\"sort-icon\">\r\n {{ sortDirection() === 'asc' ? '\u25B2' : '\u25BC' }}\r\n </span>\r\n }\r\n </th>\r\n }\r\n\r\n <!-- columna para acciones -->\r\n @if (showActions()) {\r\n <th></th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of sortData(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td [class]=\"getAlignment(col)\">\r\n @if (col.type === 'status') { @let style =\r\n getStatusStyle(row[col.key]);\r\n <span\r\n class=\"status-chip\"\r\n id=\"status-chip\"\r\n [style.background-color]=\"style.bg\"\r\n [style.color]=\"style.color\"\r\n >\r\n <span\r\n class=\"status-dot\"\r\n [style.background-color]=\"style.color\"\r\n ></span>\r\n\r\n {{ row[col.key]?.toString().toUpperCase() }}\r\n </span>\r\n\r\n } @else if (col.type === 'icon-button') {\r\n\r\n <button (click)=\"onIconColumnClick(col, row, $event)\">\r\n <span\r\n class=\"icon\"\r\n [class]=\"col.icon\"\r\n [style.color]=\"col.iconColor\"\r\n ></span>\r\n </button>\r\n\r\n } @else { {{ formatValue(col, row[col.key]) }} }\r\n </td>\r\n }\r\n\r\n <!-- Celda de acciones -->\r\n @if (showActions()) {\r\n <td class=\"acciones-cell\">\r\n <div class=\"menu-acciones\">\r\n <button class=\"icon-button\" (click)=\"openModal(row)\">\r\n <div class=\"content\">\r\n <div class=\"state-layer\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"more-vert\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </button>\r\n @if(selectedRow()?.['id'] === row['id']){\r\n <div class=\"modal-options\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-content\">\r\n <ul>\r\n @for (option of getActionsForRow(row); track $index) {\r\n <li\r\n class=\"option-item\"\r\n [style.color]=\"option.color\"\r\n (click)=\"onOptionClick(option, row)\"\r\n >\r\n <span class=\"icon\" [class]=\"option.icon\"></span>\r\n <span class=\"label\">{{ option.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".table-wrapper{width:100%;border-radius:20px;border:1px solid #c7c7ad}.inner-table{width:100%;border-collapse:separate;font-size:14px;border-spacing:0;border-radius:20px;background:#ebe8d6}.inner-table thead{background:#f0f0db}.inner-table thead tr th:first-child{border-top-left-radius:20px}.inner-table thead tr th:last-child{border-top-right-radius:20px}.inner-table th{text-align:left;padding:12px 16px;font-weight:600;color:#3a3a3a;text-transform:uppercase}.inner-table td{padding:12px 16px;color:#4a4a4a;border-top:1px solid #c7c7ad;table-layout:auto}.acciones-cell{text-align:center;padding:6px;position:relative}.menu-acciones{display:flex;align-items:center;justify-content:center;position:relative}button{background-color:transparent;border:none}.icon-button{background-color:var(--secondary-container, #dee58f);width:36px;height:36px;border:none;cursor:pointer;padding:0;border-radius:100%;display:flex;align-items:center;justify-content:center}.icon-button:hover{background:#0000000f}.more-vert{color:#4a4a4a;display:block}.modal-options{display:flex;justify-items:center;align-items:center;background-color:var(--surface-container-lowest, #ffffff);width:200px;border-radius:8px;position:absolute;top:100%;right:0;z-index:99}.modal-content{width:100%;border-radius:8px;border:1px solid var(--outline-variant, #c7c7ad);overflow:hidden}.option-item{display:flex;align-items:center;height:56px;padding:8px 12px;cursor:pointer}.option-item:hover{background-color:#0000001a}.option-item:active{background-color:#dee58f}.icon{margin-right:8px}.option-item .label{font-weight:500;font-size:16px}.icon-refresh,.icon-delete,.icon-edit,.icon-activate,.icon-deactivate,.icon-view,.icon-sanction,.icon-file{width:24px;height:24px;background-color:currentColor;color:currentColor;-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;mask-size:contain;mask-repeat:no-repeat;display:inline-block;cursor:pointer}.icon-refresh{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4\"/><path d=\"M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4\"/></svg>')}.icon-delete{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20 6a1 1 0 0 1 .117 1.993l-.117 .007h-.081l-.919 11a3 3 0 0 1 -2.824 2.995l-.176 .005h-8c-1.598 0 -2.904 -1.249 -2.992 -2.75l-.005 -.167l-.923 -11.083h-.08a1 1 0 0 1 -.117 -1.993l.117 -.007h16z\"/><path d=\"M14 2a2 2 0 0 1 2 2a1 1 0 0 1 -1.993 .117l-.007 -.117h-4l-.007 .117a1 1 0 0 1 -1.993 -.117a2 2 0 0 1 1.85 -1.995l.15 -.005h4z\"/></svg>')}.icon-edit{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\"/><path d=\"M13.5 6.5l4 4\"/></svg>')}.icon-activate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M17 3.34a10 10 0 1 1 -14.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 14.995 -8.336zm-1.293 5.953a1 1 0 0 0 -1.32 -.083l-.094 .083l-3.293 3.292l-1.293 -1.292l-.094 -.083a1 1 0 0 0 -1.403 1.403l.083 .094l2 2l.094 .083a1 1 0 0 0 1.226 0l.094 -.083l4 -4l.083 -.094a1 1 0 0 0 -.083 -1.32z\"/></svg>')}.icon-deactivate{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M15 9l-6 6M9 9l6 6\"/></svg>')}.icon-view{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\"/><path d=\"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\"/></svg>')}.icon-sanction{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\"/><path d=\"M9 15l6 -6\"/></svg>')}.icon-file{-webkit-mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" viewBox=\"0 0 24 24\"><path d=\"M14 3v4a1 1 0 0 0 1 1h4\"/><path d=\"M5 12v-7a2 2 0 0 1 2 -2h7l5 5v4\"/><path d=\"M5 18h1.5a1.5 1.5 0 0 0 0 -3h-1.5v6\"/><path d=\"M17 18h2\"/><path d=\"M20 15h-3v6\"/><path d=\"M11 15v6h1a2 2 0 0 0 2 -2v-2a2 2 0 0 0 -2 -2h-1\"/></svg>')}th.left.sortable,th.left,td.left{text-align:left}th.right.sortable,th.right,td.right{text-align:right}th.center.sortable,th.center,td.center{text-align:center}.status-chip{display:inline-flex;align-items:center;gap:.5rem;width:100%;padding:.375rem .75rem;border-radius:8px;font-size:.875rem;font-weight:500;white-space:nowrap}.status-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.sortable:hover{opacity:.7}.sort-icon{margin-left:6px;font-size:12px;pointer-events:none}\n"] }]
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
args: ['document:click', ['$event']]
|
|
731
|
-
|
|
715
|
+
args: [{ selector: 'lib-date-time-picker', imports: [], providers: [
|
|
716
|
+
{
|
|
717
|
+
provide: NG_VALUE_ACCESSOR,
|
|
718
|
+
useExisting: forwardRef(() => DateTimePicker),
|
|
719
|
+
multi: true,
|
|
720
|
+
},
|
|
721
|
+
], template: "<div class=\"datetime-container\">\r\n <div\r\n class=\"datetime-header\"\r\n [class.active]=\"isOpen()\"\r\n [class.disabled]=\"isBlocked()\"\r\n [class.readonly]=\"isBlocked()\"\r\n (click)=\"!isBlocked() && toggle()\"\r\n (keydown)=\"!isBlocked() && onKeyDown($event)\"\r\n tabindex=\"0\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"datetime-input\"\r\n [value]=\"displayValue()\"\r\n [placeholder]=\"placeholder()\"\r\n (input)=\"onInputChange($event)\"\r\n (focus)=\"!isBlocked() && onInputFocus()\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"isDisabled()\"\r\n [readOnly]=\"readonly()\"\r\n />\r\n\r\n <div class=\"header-icons\">\r\n @if (selectedDate()) {\r\n <span\r\n class=\"clear-icon\"\r\n (click)=\"!isBlocked() && clear(); $event.stopPropagation()\"\r\n title=\"Limpiar\"\r\n >\r\n \u00D7\r\n </span>\r\n }\r\n <span class=\"arrow\" [class.open]=\"isOpen()\"></span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (isOpen()) {\r\n<div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n del calendario -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">{{ monthName() }} {{ currentYear() }}</div>\r\n\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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 del mes -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n {{ day || '' }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Selector de tiempo (solo si mode === 'datetime') -->\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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\r\n <!-- Botones de acci\u00F3n -->\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 @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", styles: [".datetime-container{position:relative;width:100%}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:12px 15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-input{flex:1;border:none;outline:none;background:transparent;font-size:1.3rem;color:#454733;padding:0;margin:0}.datetime-input::placeholder{color:#787861}.datetime-input:disabled{cursor:not-allowed}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled,.datetime-header.readonly{pointer-events:none;opacity:.6;cursor:not-allowed}.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:20px;height:20px;background-image:url(\"data:image/svg+xml,%3csvg 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-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath 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' /%3e%3cpath d='M16 3l0 4' /%3e%3cpath d='M8 3l0 4' /%3e%3cpath d='M4 11l16 0' /%3e%3cpath d='M8 15h2v2h-2z' /%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:20px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='currentColor' class='icon icon-tabler icons-tabler-filled icon-tabler-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath d='M16 2a1 1 0 0 1 .993 .883l.007 .117v1h1a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h1v-1a1 1 0 0 1 1.993 -.117l.007 .117v1h6v-1a1 1 0 0 1 1 -1m3 7h-14v9.625c0 .705 .386 1.286 .883 1.366l.117 .009h12c.513 0 .936 -.53 .993 -1.215l.007 -.16z' /%3e%3cpath d='M8 14h2v2h-2z' /%3e%3c/svg%3e\")}.dropdown{position:absolute;top:100%;left:0;right: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}.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:10px 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"] }]
|
|
722
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }] } });
|
|
732
723
|
|
|
733
|
-
class
|
|
724
|
+
class DateTimeFilter {
|
|
734
725
|
elementRef;
|
|
735
726
|
ngZone;
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
727
|
+
// Inputs
|
|
728
|
+
filters = input([], ...(ngDevMode ? [{ debugName: "filters" }] : []));
|
|
729
|
+
// Outputs
|
|
730
|
+
dateSelected = output();
|
|
740
731
|
dateChange = output();
|
|
732
|
+
// Internal State
|
|
733
|
+
activeFilterType = signal(null, ...(ngDevMode ? [{ debugName: "activeFilterType" }] : []));
|
|
741
734
|
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
742
735
|
selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : []));
|
|
736
|
+
inputTextValue = signal('', ...(ngDevMode ? [{ debugName: "inputTextValue" }] : []));
|
|
743
737
|
isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
744
738
|
isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
const
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
// Horas en formato 12h
|
|
801
|
-
hours12 = computed(() => {
|
|
802
|
-
return Array.from({ length: 12 }, (_, i) => {
|
|
803
|
-
const hour12 = i === 0 ? 12 : i;
|
|
804
|
-
return {
|
|
805
|
-
value: hour12,
|
|
806
|
-
display: hour12.toString().padStart(2, '0')
|
|
807
|
-
};
|
|
808
|
-
});
|
|
809
|
-
}, ...(ngDevMode ? [{ debugName: "hours12" }] : []));
|
|
810
|
-
// Hora seleccionada en formato 12h
|
|
811
|
-
selectedHour12 = computed(() => {
|
|
812
|
-
const hour24 = this.selectedHour();
|
|
813
|
-
if (hour24 === 0)
|
|
814
|
-
return 12;
|
|
815
|
-
if (hour24 > 12)
|
|
816
|
-
return hour24 - 12;
|
|
817
|
-
return hour24;
|
|
818
|
-
}, ...(ngDevMode ? [{ debugName: "selectedHour12" }] : []));
|
|
819
|
-
minutes = computed(() => Array.from({ length: 60 }, (_, i) => i), ...(ngDevMode ? [{ debugName: "minutes" }] : []));
|
|
820
|
-
onChange = (value) => { };
|
|
739
|
+
// Máscara visual dinámica para la guía de fecha __/__/____
|
|
740
|
+
// Devuelve un arreglo de caracteres con flag "filled" para poder dar color distinto
|
|
741
|
+
inputMask = computed(() => {
|
|
742
|
+
const raw = this.inputTextValue() || '';
|
|
743
|
+
const numbersOnly = raw.replace(/\D/g, '');
|
|
744
|
+
const template = [
|
|
745
|
+
{ char: 'd', filled: false },
|
|
746
|
+
{ char: 'd', filled: false },
|
|
747
|
+
{ char: '/', filled: false },
|
|
748
|
+
{ char: 'm', filled: false },
|
|
749
|
+
{ char: 'm', filled: false },
|
|
750
|
+
{ char: '/', filled: false },
|
|
751
|
+
{ char: 'y', filled: false },
|
|
752
|
+
{ char: 'y', filled: false },
|
|
753
|
+
{ char: 'y', filled: false },
|
|
754
|
+
{ char: 'y', filled: false },
|
|
755
|
+
];
|
|
756
|
+
let index = 0;
|
|
757
|
+
for (let i = 0; i < template.length && index < numbersOnly.length; i++) {
|
|
758
|
+
if (template[i].char === '/')
|
|
759
|
+
continue;
|
|
760
|
+
template[i] = { char: numbersOnly[index++], filled: true };
|
|
761
|
+
}
|
|
762
|
+
// Cuando se completa el segmento, el slash correspondiente pasa a "filled"
|
|
763
|
+
if (numbersOnly.length >= 2) {
|
|
764
|
+
template[2] = { char: '/', filled: true }; // después de DD
|
|
765
|
+
}
|
|
766
|
+
if (numbersOnly.length >= 4) {
|
|
767
|
+
template[5] = { char: '/', filled: true }; // después de MM
|
|
768
|
+
}
|
|
769
|
+
return template; // para usar en el template y colorear por carácter
|
|
770
|
+
}, ...(ngDevMode ? [{ debugName: "inputMask" }] : []));
|
|
771
|
+
clearTrigger = input(0, ...(ngDevMode ? [{ debugName: "clearTrigger" }] : []));
|
|
772
|
+
// Computed Properties based on active filter
|
|
773
|
+
activeFilter = computed(() => {
|
|
774
|
+
const type = this.activeFilterType();
|
|
775
|
+
return this.filters().find(f => f.value === type) || null;
|
|
776
|
+
}, ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
|
|
777
|
+
mode = computed(() => {
|
|
778
|
+
const filter = this.activeFilter();
|
|
779
|
+
return filter?.type === 'datetime' ? 'datetime' : 'date';
|
|
780
|
+
}, ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
781
|
+
placeholder = computed(() => this.activeFilter()?.placeholder || 'Seleccionar fecha', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
782
|
+
minDate = computed(() => this.activeFilter()?.minDate || null, ...(ngDevMode ? [{ debugName: "minDate" }] : []));
|
|
783
|
+
maxDate = computed(() => this.activeFilter()?.maxDate || null, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
784
|
+
filterValue = computed(() => this.activeFilter()?.value || '', ...(ngDevMode ? [{ debugName: "filterValue" }] : []));
|
|
785
|
+
// Calendar Navigation
|
|
786
|
+
currentMonth = signal(new Date().getMonth(), ...(ngDevMode ? [{ debugName: "currentMonth" }] : []));
|
|
787
|
+
currentYear = signal(new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "currentYear" }] : []));
|
|
788
|
+
// Time State
|
|
789
|
+
selectedHour = signal(0, ...(ngDevMode ? [{ debugName: "selectedHour" }] : []));
|
|
790
|
+
selectedMinute = signal(0, ...(ngDevMode ? [{ debugName: "selectedMinute" }] : []));
|
|
791
|
+
selectedAmPm = signal('AM', ...(ngDevMode ? [{ debugName: "selectedAmPm" }] : []));
|
|
792
|
+
documentClickListener;
|
|
793
|
+
onChange = () => { };
|
|
821
794
|
onTouched = () => { };
|
|
822
795
|
constructor(elementRef, ngZone) {
|
|
823
796
|
this.elementRef = elementRef;
|
|
824
797
|
this.ngZone = ngZone;
|
|
798
|
+
effect(() => {
|
|
799
|
+
const trigger = this.clearTrigger();
|
|
800
|
+
if (trigger > 0) {
|
|
801
|
+
this.clear();
|
|
802
|
+
}
|
|
803
|
+
});
|
|
825
804
|
}
|
|
826
805
|
ngOnDestroy() {
|
|
827
806
|
this.removeDocumentListener();
|
|
828
807
|
}
|
|
808
|
+
// ControlValueAccessor Implementation
|
|
829
809
|
writeValue(value) {
|
|
830
810
|
let date = null;
|
|
831
811
|
if (value instanceof Date) {
|
|
832
812
|
date = value;
|
|
833
813
|
}
|
|
834
814
|
else if (typeof value === 'string' && value) {
|
|
835
|
-
// Manejar tanto fechas ISO como otros formatos de string
|
|
836
815
|
const parsedDate = new Date(value);
|
|
837
816
|
if (!isNaN(parsedDate.getTime())) {
|
|
838
817
|
date = parsedDate;
|
|
@@ -854,24 +833,24 @@ class DateTimePicker {
|
|
|
854
833
|
setDisabledState(isDisabled) {
|
|
855
834
|
this.isDisabled.set(isDisabled);
|
|
856
835
|
}
|
|
857
|
-
|
|
858
|
-
|
|
836
|
+
// Public Methods
|
|
837
|
+
toggle(filterValue) {
|
|
838
|
+
if (this.isDisabled())
|
|
859
839
|
return;
|
|
860
|
-
this.
|
|
861
|
-
if (this.isOpen()) {
|
|
840
|
+
if (this.activeFilterType() === filterValue && this.isOpen()) {
|
|
862
841
|
this.close();
|
|
863
842
|
}
|
|
864
843
|
else {
|
|
844
|
+
this.activeFilterType.set(filterValue);
|
|
865
845
|
this.open();
|
|
866
846
|
}
|
|
867
847
|
}
|
|
868
848
|
open() {
|
|
869
|
-
if (this.
|
|
849
|
+
if (this.isDisabled())
|
|
870
850
|
return;
|
|
871
851
|
this.markAsTouched();
|
|
872
852
|
this.isOpen.set(true);
|
|
873
853
|
this.addDocumentListener();
|
|
874
|
-
// Si hay fecha seleccionada, navegar a ese mes/año
|
|
875
854
|
const selected = this.selectedDate();
|
|
876
855
|
if (selected) {
|
|
877
856
|
this.currentMonth.set(selected.getMonth());
|
|
@@ -882,9 +861,15 @@ class DateTimePicker {
|
|
|
882
861
|
this.isOpen.set(false);
|
|
883
862
|
this.removeDocumentListener();
|
|
884
863
|
this.markAsTouched();
|
|
864
|
+
// Don't clear activeFilterType here to keep the chip active if needed,
|
|
865
|
+
// or clear it if you want the chip to look inactive when closed.
|
|
866
|
+
// For now, let's keep it active only if a date is selected?
|
|
867
|
+
// Or maybe we want to close the dropdown but keep the filter "selected" in UI?
|
|
868
|
+
// Let's just close the dropdown.
|
|
885
869
|
}
|
|
870
|
+
// Calendar Logic
|
|
886
871
|
selectDay(day) {
|
|
887
|
-
if (!day || this.
|
|
872
|
+
if (!day || this.isDisabled())
|
|
888
873
|
return;
|
|
889
874
|
const newDate = new Date(this.currentYear(), this.currentMonth(), day, this.selectedHour(), this.selectedMinute());
|
|
890
875
|
if (this.isDateDisabled(newDate))
|
|
@@ -893,160 +878,42 @@ class DateTimePicker {
|
|
|
893
878
|
this.onChange(newDate.toISOString());
|
|
894
879
|
this.markAsTouched();
|
|
895
880
|
this.dateChange.emit(newDate);
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
setHour12(hour12) {
|
|
902
|
-
if (this.isBlocked())
|
|
903
|
-
return;
|
|
904
|
-
// Convertir de 12h a 24h
|
|
905
|
-
let hour24;
|
|
906
|
-
const amPm = this.selectedAmPm();
|
|
907
|
-
if (hour12 === 12) {
|
|
908
|
-
hour24 = amPm === 'AM' ? 0 : 12;
|
|
909
|
-
}
|
|
910
|
-
else {
|
|
911
|
-
hour24 = amPm === 'AM' ? hour12 : hour12 + 12;
|
|
912
|
-
}
|
|
913
|
-
this.selectedHour.set(hour24);
|
|
914
|
-
this.updateDateTime();
|
|
915
|
-
}
|
|
916
|
-
setMinute(minute) {
|
|
917
|
-
if (this.isBlocked())
|
|
918
|
-
return;
|
|
919
|
-
this.selectedMinute.set(minute);
|
|
920
|
-
this.updateDateTime();
|
|
921
|
-
}
|
|
922
|
-
setAmPm(amPm) {
|
|
923
|
-
if (this.isBlocked())
|
|
924
|
-
return;
|
|
925
|
-
const currentHour24 = this.selectedHour();
|
|
926
|
-
const currentHour12 = this.selectedHour12();
|
|
927
|
-
let newHour24;
|
|
928
|
-
if (amPm === 'AM') {
|
|
929
|
-
newHour24 = currentHour12 === 12 ? 0 : currentHour12;
|
|
930
|
-
}
|
|
931
|
-
else {
|
|
932
|
-
newHour24 = currentHour12 === 12 ? 12 : currentHour12 + 12;
|
|
933
|
-
}
|
|
934
|
-
this.selectedAmPm.set(amPm);
|
|
935
|
-
this.selectedHour.set(newHour24);
|
|
936
|
-
this.updateDateTime();
|
|
937
|
-
}
|
|
938
|
-
previousMonth() {
|
|
939
|
-
const currentMonth = this.currentMonth();
|
|
940
|
-
const currentYear = this.currentYear();
|
|
941
|
-
if (currentMonth === 0) {
|
|
942
|
-
this.currentMonth.set(11);
|
|
943
|
-
this.currentYear.set(currentYear - 1);
|
|
944
|
-
}
|
|
945
|
-
else {
|
|
946
|
-
this.currentMonth.set(currentMonth - 1);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
nextMonth() {
|
|
950
|
-
const currentMonth = this.currentMonth();
|
|
951
|
-
const currentYear = this.currentYear();
|
|
952
|
-
if (currentMonth === 11) {
|
|
953
|
-
this.currentMonth.set(0);
|
|
954
|
-
this.currentYear.set(currentYear + 1);
|
|
955
|
-
}
|
|
956
|
-
else {
|
|
957
|
-
this.currentMonth.set(currentMonth + 1);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
previousYear() {
|
|
961
|
-
this.currentYear.set(this.currentYear() - 1);
|
|
962
|
-
}
|
|
963
|
-
nextYear() {
|
|
964
|
-
this.currentYear.set(this.currentYear() + 1);
|
|
965
|
-
}
|
|
966
|
-
today() {
|
|
967
|
-
const today = new Date();
|
|
968
|
-
this.updateInternalState(today);
|
|
969
|
-
this.onChange(today.toISOString());
|
|
970
|
-
this.markAsTouched();
|
|
971
|
-
this.dateChange.emit(today);
|
|
881
|
+
this.dateSelected.emit({
|
|
882
|
+
filter: this.filterValue(),
|
|
883
|
+
value: newDate,
|
|
884
|
+
});
|
|
972
885
|
if (this.mode() === 'date') {
|
|
973
886
|
this.close();
|
|
974
887
|
}
|
|
975
888
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
this.
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
if (
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
this.markAsTouched();
|
|
991
|
-
this.close();
|
|
889
|
+
// ... (Rest of the helper methods like previousMonth, nextMonth, etc. remain largely the same)
|
|
890
|
+
displayValue = computed(() => {
|
|
891
|
+
const date = this.selectedDate();
|
|
892
|
+
if (!date)
|
|
893
|
+
return '';
|
|
894
|
+
const options = {
|
|
895
|
+
day: '2-digit',
|
|
896
|
+
month: '2-digit',
|
|
897
|
+
year: 'numeric',
|
|
898
|
+
};
|
|
899
|
+
if (this.mode() === 'datetime') {
|
|
900
|
+
options.hour = '2-digit';
|
|
901
|
+
options.minute = '2-digit';
|
|
902
|
+
options.hour12 = true;
|
|
992
903
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
if (!selected)
|
|
999
|
-
return false;
|
|
1000
|
-
return (selected.getDate() === day &&
|
|
1001
|
-
selected.getMonth() === this.currentMonth() &&
|
|
1002
|
-
selected.getFullYear() === this.currentYear());
|
|
1003
|
-
}
|
|
1004
|
-
isToday(day) {
|
|
1005
|
-
if (!day)
|
|
1006
|
-
return false;
|
|
1007
|
-
const today = new Date();
|
|
1008
|
-
return (today.getDate() === day &&
|
|
1009
|
-
today.getMonth() === this.currentMonth() &&
|
|
1010
|
-
today.getFullYear() === this.currentYear());
|
|
1011
|
-
}
|
|
1012
|
-
isDayDisabled(day) {
|
|
1013
|
-
if (!day)
|
|
1014
|
-
return true;
|
|
1015
|
-
const date = new Date(this.currentYear(), this.currentMonth(), day);
|
|
1016
|
-
return this.isDateDisabled(date);
|
|
1017
|
-
}
|
|
1018
|
-
isDateDisabled(date) {
|
|
1019
|
-
const minDate = this.minDate();
|
|
1020
|
-
const maxDate = this.maxDate();
|
|
1021
|
-
if (minDate && date < minDate)
|
|
1022
|
-
return true;
|
|
1023
|
-
if (maxDate && date > maxDate)
|
|
1024
|
-
return true;
|
|
1025
|
-
return false;
|
|
1026
|
-
}
|
|
1027
|
-
updateDateTime() {
|
|
1028
|
-
const selected = this.selectedDate();
|
|
1029
|
-
if (!selected)
|
|
1030
|
-
return;
|
|
1031
|
-
const newDate = new Date(selected);
|
|
1032
|
-
newDate.setHours(this.selectedHour());
|
|
1033
|
-
newDate.setMinutes(this.selectedMinute());
|
|
1034
|
-
this.updateInternalState(newDate);
|
|
1035
|
-
this.onChange(newDate.toISOString());
|
|
1036
|
-
this.markAsTouched();
|
|
1037
|
-
this.dateChange.emit(newDate);
|
|
1038
|
-
}
|
|
1039
|
-
// Manejo de input de texto (DD/MM/YYYY)
|
|
1040
|
-
onInputChange(event) {
|
|
1041
|
-
if (this.isBlocked())
|
|
904
|
+
return date.toLocaleDateString('es-ES', options);
|
|
905
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
906
|
+
// Input text handling
|
|
907
|
+
onInputChange(event, filterValue) {
|
|
908
|
+
if (this.isDisabled())
|
|
1042
909
|
return;
|
|
1043
910
|
const input = event.target;
|
|
1044
911
|
let value = input.value;
|
|
1045
|
-
//
|
|
912
|
+
// Remove all non-numeric characters
|
|
1046
913
|
const numbersOnly = value.replace(/\D/g, '');
|
|
1047
|
-
//
|
|
914
|
+
// Limit to 8 digits (DD/MM/YYYY)
|
|
1048
915
|
const limitedNumbers = numbersOnly.slice(0, 8);
|
|
1049
|
-
//
|
|
916
|
+
// Format with slashes: DD/MM/YYYY
|
|
1050
917
|
let formatted = '';
|
|
1051
918
|
if (limitedNumbers.length > 0) {
|
|
1052
919
|
formatted = limitedNumbers.slice(0, 2);
|
|
@@ -1057,44 +924,53 @@ class DateTimePicker {
|
|
|
1057
924
|
formatted += '/' + limitedNumbers.slice(4, 8);
|
|
1058
925
|
}
|
|
1059
926
|
}
|
|
927
|
+
// Update the input value
|
|
1060
928
|
this.inputTextValue.set(formatted);
|
|
1061
929
|
input.value = formatted;
|
|
1062
930
|
this.markAsTouched();
|
|
1063
|
-
//
|
|
931
|
+
// Only parse when we have a complete date (DD/MM/YYYY = 10 characters)
|
|
1064
932
|
if (formatted.length === 10) {
|
|
1065
933
|
const parsedDate = this.parseDateInput(formatted);
|
|
1066
934
|
if (parsedDate) {
|
|
1067
935
|
if (this.isDateDisabled(parsedDate)) {
|
|
1068
|
-
//
|
|
936
|
+
// Invalid date (out of range), but keep the text
|
|
1069
937
|
return;
|
|
1070
938
|
}
|
|
1071
939
|
this.updateInternalState(parsedDate);
|
|
1072
940
|
this.onChange(parsedDate.toISOString());
|
|
1073
941
|
this.dateChange.emit(parsedDate);
|
|
942
|
+
this.dateSelected.emit({
|
|
943
|
+
filter: filterValue,
|
|
944
|
+
value: parsedDate,
|
|
945
|
+
});
|
|
1074
946
|
}
|
|
1075
947
|
}
|
|
1076
948
|
else if (formatted.trim() === '') {
|
|
1077
|
-
//
|
|
949
|
+
// Clear if input is empty
|
|
1078
950
|
this.resetInternalState();
|
|
1079
951
|
this.onChange(null);
|
|
1080
952
|
this.dateChange.emit(null);
|
|
1081
953
|
}
|
|
1082
954
|
}
|
|
1083
|
-
onInputFocus() {
|
|
1084
|
-
if (this.
|
|
955
|
+
onInputFocus(filterValue) {
|
|
956
|
+
if (this.isDisabled())
|
|
1085
957
|
return;
|
|
958
|
+
this.activeFilterType.set(filterValue);
|
|
1086
959
|
this.open();
|
|
1087
960
|
}
|
|
1088
961
|
parseDateInput(input) {
|
|
1089
962
|
if (!input || input.trim() === '')
|
|
1090
963
|
return null;
|
|
964
|
+
// Only accept DD/MM/YYYY format
|
|
1091
965
|
const match = input.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
|
1092
966
|
if (match) {
|
|
1093
967
|
const day = parseInt(match[1], 10);
|
|
1094
968
|
const month = parseInt(match[2], 10) - 1;
|
|
1095
969
|
const year = parseInt(match[3], 10);
|
|
970
|
+
// Validate date
|
|
1096
971
|
if (day >= 1 && day <= 31 && month >= 0 && month <= 11 && year >= 1900 && year <= 2100) {
|
|
1097
972
|
const date = new Date(year, month, day);
|
|
973
|
+
// Check if date is valid (handles invalid dates like 31/02/2024)
|
|
1098
974
|
if (date.getDate() === day && date.getMonth() === month && date.getFullYear() === year) {
|
|
1099
975
|
return date;
|
|
1100
976
|
}
|
|
@@ -1102,12 +978,46 @@ class DateTimePicker {
|
|
|
1102
978
|
}
|
|
1103
979
|
return null;
|
|
1104
980
|
}
|
|
1105
|
-
|
|
1106
|
-
const
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
981
|
+
monthName = computed(() => {
|
|
982
|
+
const months = [
|
|
983
|
+
'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
|
|
984
|
+
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'
|
|
985
|
+
];
|
|
986
|
+
return months[this.currentMonth()];
|
|
987
|
+
}, ...(ngDevMode ? [{ debugName: "monthName" }] : []));
|
|
988
|
+
calendarDays = computed(() => {
|
|
989
|
+
const year = this.currentYear();
|
|
990
|
+
const month = this.currentMonth();
|
|
991
|
+
const firstDay = new Date(year, month, 1);
|
|
992
|
+
const lastDay = new Date(year, month + 1, 0);
|
|
993
|
+
const daysInMonth = lastDay.getDate();
|
|
994
|
+
const startingDayOfWeek = firstDay.getDay();
|
|
995
|
+
const days = [];
|
|
996
|
+
for (let i = 0; i < startingDayOfWeek; i++)
|
|
997
|
+
days.push(null);
|
|
998
|
+
for (let day = 1; day <= daysInMonth; day++)
|
|
999
|
+
days.push(day);
|
|
1000
|
+
return days;
|
|
1001
|
+
}, ...(ngDevMode ? [{ debugName: "calendarDays" }] : []));
|
|
1002
|
+
hours12 = computed(() => {
|
|
1003
|
+
return Array.from({ length: 12 }, (_, i) => {
|
|
1004
|
+
const hour12 = i === 0 ? 12 : i;
|
|
1005
|
+
return {
|
|
1006
|
+
value: hour12,
|
|
1007
|
+
display: hour12.toString().padStart(2, '0')
|
|
1008
|
+
};
|
|
1009
|
+
});
|
|
1010
|
+
}, ...(ngDevMode ? [{ debugName: "hours12" }] : []));
|
|
1011
|
+
selectedHour12 = computed(() => {
|
|
1012
|
+
const hour24 = this.selectedHour();
|
|
1013
|
+
if (hour24 === 0)
|
|
1014
|
+
return 12;
|
|
1015
|
+
if (hour24 > 12)
|
|
1016
|
+
return hour24 - 12;
|
|
1017
|
+
return hour24;
|
|
1018
|
+
}, ...(ngDevMode ? [{ debugName: "selectedHour12" }] : []));
|
|
1019
|
+
minutes = computed(() => Array.from({ length: 60 }, (_, i) => i), ...(ngDevMode ? [{ debugName: "minutes" }] : []));
|
|
1020
|
+
// Helper methods
|
|
1111
1021
|
updateInternalState(date) {
|
|
1112
1022
|
this.selectedDate.set(date);
|
|
1113
1023
|
this.currentMonth.set(date.getMonth());
|
|
@@ -1115,6 +1025,7 @@ class DateTimePicker {
|
|
|
1115
1025
|
this.selectedHour.set(date.getHours());
|
|
1116
1026
|
this.selectedMinute.set(date.getMinutes());
|
|
1117
1027
|
this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');
|
|
1028
|
+
// Update input text value to match the formatted date
|
|
1118
1029
|
const formatted = this.formatDateForInput(date);
|
|
1119
1030
|
this.inputTextValue.set(formatted);
|
|
1120
1031
|
}
|
|
@@ -1125,6 +1036,12 @@ class DateTimePicker {
|
|
|
1125
1036
|
this.selectedMinute.set(0);
|
|
1126
1037
|
this.selectedAmPm.set('AM');
|
|
1127
1038
|
}
|
|
1039
|
+
formatDateForInput(date) {
|
|
1040
|
+
const day = date.getDate().toString().padStart(2, '0');
|
|
1041
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
1042
|
+
const year = date.getFullYear();
|
|
1043
|
+
return `${day}/${month}/${year}`;
|
|
1044
|
+
}
|
|
1128
1045
|
markAsTouched() {
|
|
1129
1046
|
if (!this.isTouched()) {
|
|
1130
1047
|
this.isTouched.set(true);
|
|
@@ -1132,9 +1049,8 @@ class DateTimePicker {
|
|
|
1132
1049
|
}
|
|
1133
1050
|
}
|
|
1134
1051
|
addDocumentListener() {
|
|
1135
|
-
if (this.documentClickListener)
|
|
1052
|
+
if (this.documentClickListener)
|
|
1136
1053
|
this.removeDocumentListener();
|
|
1137
|
-
}
|
|
1138
1054
|
this.ngZone.runOutsideAngular(() => {
|
|
1139
1055
|
this.documentClickListener = (event) => {
|
|
1140
1056
|
const target = event.target;
|
|
@@ -1147,9 +1063,7 @@ class DateTimePicker {
|
|
|
1147
1063
|
});
|
|
1148
1064
|
}
|
|
1149
1065
|
};
|
|
1150
|
-
setTimeout(() =>
|
|
1151
|
-
document.addEventListener('click', this.documentClickListener, true);
|
|
1152
|
-
}, 10);
|
|
1066
|
+
setTimeout(() => document.addEventListener('click', this.documentClickListener, true), 10);
|
|
1153
1067
|
});
|
|
1154
1068
|
}
|
|
1155
1069
|
removeDocumentListener() {
|
|
@@ -1158,52 +1072,137 @@ class DateTimePicker {
|
|
|
1158
1072
|
this.documentClickListener = undefined;
|
|
1159
1073
|
}
|
|
1160
1074
|
}
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1075
|
+
// Navigation methods
|
|
1076
|
+
previousMonth() {
|
|
1077
|
+
const currentMonth = this.currentMonth();
|
|
1078
|
+
const currentYear = this.currentYear();
|
|
1079
|
+
if (currentMonth === 0) {
|
|
1080
|
+
this.currentMonth.set(11);
|
|
1081
|
+
this.currentYear.set(currentYear - 1);
|
|
1082
|
+
}
|
|
1083
|
+
else {
|
|
1084
|
+
this.currentMonth.set(currentMonth - 1);
|
|
1085
|
+
}
|
|
1171
1086
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
const date = new Date(isoString);
|
|
1179
|
-
if (!isNaN(date.getTime())) {
|
|
1180
|
-
this.writeValue(date);
|
|
1181
|
-
this.onChange(isoString);
|
|
1182
|
-
}
|
|
1087
|
+
nextMonth() {
|
|
1088
|
+
const currentMonth = this.currentMonth();
|
|
1089
|
+
const currentYear = this.currentYear();
|
|
1090
|
+
if (currentMonth === 11) {
|
|
1091
|
+
this.currentMonth.set(0);
|
|
1092
|
+
this.currentYear.set(currentYear + 1);
|
|
1183
1093
|
}
|
|
1184
1094
|
else {
|
|
1185
|
-
this.
|
|
1095
|
+
this.currentMonth.set(currentMonth + 1);
|
|
1186
1096
|
}
|
|
1187
1097
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1098
|
+
previousYear() { this.currentYear.set(this.currentYear() - 1); }
|
|
1099
|
+
nextYear() { this.currentYear.set(this.currentYear() + 1); }
|
|
1100
|
+
today() {
|
|
1101
|
+
const today = new Date();
|
|
1102
|
+
this.updateInternalState(today);
|
|
1103
|
+
this.onChange(today.toISOString());
|
|
1104
|
+
this.markAsTouched();
|
|
1105
|
+
this.dateChange.emit(today);
|
|
1106
|
+
this.dateSelected.emit({ filter: this.filterValue(), value: today });
|
|
1107
|
+
if (this.mode() === 'date')
|
|
1108
|
+
this.close();
|
|
1109
|
+
}
|
|
1110
|
+
clear() {
|
|
1111
|
+
this.resetInternalState();
|
|
1112
|
+
this.onChange(null);
|
|
1113
|
+
this.markAsTouched();
|
|
1114
|
+
this.dateChange.emit(null);
|
|
1115
|
+
this.close();
|
|
1116
|
+
}
|
|
1117
|
+
// Time setters
|
|
1118
|
+
setHour12(hour12) {
|
|
1119
|
+
if (this.isDisabled())
|
|
1120
|
+
return;
|
|
1121
|
+
const amPm = this.selectedAmPm();
|
|
1122
|
+
const hour24 = hour12 === 12 ? (amPm === 'AM' ? 0 : 12) : (amPm === 'AM' ? hour12 : hour12 + 12);
|
|
1123
|
+
this.selectedHour.set(hour24);
|
|
1124
|
+
this.updateDateTime();
|
|
1125
|
+
}
|
|
1126
|
+
setMinute(minute) {
|
|
1127
|
+
if (this.isDisabled())
|
|
1128
|
+
return;
|
|
1129
|
+
this.selectedMinute.set(minute);
|
|
1130
|
+
this.updateDateTime();
|
|
1131
|
+
}
|
|
1132
|
+
setAmPm(amPm) {
|
|
1133
|
+
if (this.isDisabled())
|
|
1134
|
+
return;
|
|
1135
|
+
const currentHour12 = this.selectedHour12();
|
|
1136
|
+
const newHour24 = amPm === 'AM' ? (currentHour12 === 12 ? 0 : currentHour12) : (currentHour12 === 12 ? 12 : currentHour12 + 12);
|
|
1137
|
+
this.selectedAmPm.set(amPm);
|
|
1138
|
+
this.selectedHour.set(newHour24);
|
|
1139
|
+
this.updateDateTime();
|
|
1140
|
+
}
|
|
1141
|
+
updateDateTime() {
|
|
1142
|
+
const selected = this.selectedDate();
|
|
1143
|
+
if (!selected)
|
|
1144
|
+
return;
|
|
1145
|
+
const newDate = new Date(selected);
|
|
1146
|
+
newDate.setHours(this.selectedHour());
|
|
1147
|
+
newDate.setMinutes(this.selectedMinute());
|
|
1148
|
+
this.selectedDate.set(newDate);
|
|
1149
|
+
// Update input text value
|
|
1150
|
+
const formatted = this.formatDateForInput(newDate);
|
|
1151
|
+
this.inputTextValue.set(formatted);
|
|
1152
|
+
this.onChange(newDate.toISOString());
|
|
1153
|
+
this.markAsTouched();
|
|
1154
|
+
this.dateChange.emit(newDate);
|
|
1155
|
+
this.dateSelected.emit({
|
|
1156
|
+
filter: this.filterValue(),
|
|
1157
|
+
value: newDate,
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
// Validation helpers
|
|
1161
|
+
isDaySelected(day) {
|
|
1162
|
+
if (!day)
|
|
1163
|
+
return false;
|
|
1164
|
+
const selected = this.selectedDate();
|
|
1165
|
+
return !!selected && selected.getDate() === day && selected.getMonth() === this.currentMonth() && selected.getFullYear() === this.currentYear();
|
|
1166
|
+
}
|
|
1167
|
+
isToday(day) {
|
|
1168
|
+
if (!day)
|
|
1169
|
+
return false;
|
|
1170
|
+
const today = new Date();
|
|
1171
|
+
return today.getDate() === day && today.getMonth() === this.currentMonth() && today.getFullYear() === this.currentYear();
|
|
1172
|
+
}
|
|
1173
|
+
isDayDisabled(day) {
|
|
1174
|
+
if (!day)
|
|
1175
|
+
return true;
|
|
1176
|
+
return this.isDateDisabled(new Date(this.currentYear(), this.currentMonth(), day));
|
|
1177
|
+
}
|
|
1178
|
+
isDateDisabled(date) {
|
|
1179
|
+
const minDate = this.minDate();
|
|
1180
|
+
const maxDate = this.maxDate();
|
|
1181
|
+
if (minDate && date < minDate)
|
|
1182
|
+
return true;
|
|
1183
|
+
if (maxDate && date > maxDate)
|
|
1184
|
+
return true;
|
|
1185
|
+
return false;
|
|
1186
|
+
}
|
|
1187
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DateTimeFilter, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
1188
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DateTimeFilter, isStandalone: true, selector: "lib-date-time-filter", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, clearTrigger: { classPropertyName: "clearTrigger", publicName: "clearTrigger", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateSelected: "dateSelected", dateChange: "dateChange" }, providers: [
|
|
1190
1189
|
{
|
|
1191
1190
|
provide: NG_VALUE_ACCESSOR,
|
|
1192
|
-
useExisting: forwardRef(() =>
|
|
1191
|
+
useExisting: forwardRef(() => DateTimeFilter),
|
|
1193
1192
|
multi: true,
|
|
1194
1193
|
},
|
|
1195
|
-
], ngImport: i0, template: "<div class=\"datetime-container\">\r\n <div\r\n class=\"datetime-header\"\r\n [class.active]=\"isOpen()\"\r\n [class.disabled]=\"isBlocked()\"\r\n [class.readonly]=\"isBlocked()\"\r\n (click)=\"!isBlocked() && toggle()\"\r\n (keydown)=\"!isBlocked() && onKeyDown($event)\"\r\n tabindex=\"0\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"datetime-input\"\r\n [value]=\"displayValue()\"\r\n [placeholder]=\"placeholder()\"\r\n (input)=\"onInputChange($event)\"\r\n (focus)=\"!isBlocked() && onInputFocus()\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"isDisabled()\"\r\n [readOnly]=\"readonly()\"\r\n />\r\n\r\n <div class=\"header-icons\">\r\n @if (selectedDate()) {\r\n <span\r\n class=\"clear-icon\"\r\n (click)=\"!isBlocked() && clear(); $event.stopPropagation()\"\r\n title=\"Limpiar\"\r\n >\r\n \u00D7\r\n </span>\r\n }\r\n <span class=\"arrow\" [class.open]=\"isOpen()\"></span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (isOpen()) {\r\n<div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n del calendario -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">{{ monthName() }} {{ currentYear() }}</div>\r\n\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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 del mes -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n {{ day || '' }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Selector de tiempo (solo si mode === 'datetime') -->\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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\r\n <!-- Botones de acci\u00F3n -->\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 @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", styles: [".datetime-container{position:relative;width:100%}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:12px 15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-input{flex:1;border:none;outline:none;background:transparent;font-size:1.3rem;color:#454733;padding:0;margin:0}.datetime-input::placeholder{color:#787861}.datetime-input:disabled{cursor:not-allowed}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled,.datetime-header.readonly{pointer-events:none;opacity:.6;cursor:not-allowed}.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:20px;height:20px;background-image:url(\"data:image/svg+xml,%3csvg 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-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath 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' /%3e%3cpath d='M16 3l0 4' /%3e%3cpath d='M8 3l0 4' /%3e%3cpath d='M4 11l16 0' /%3e%3cpath d='M8 15h2v2h-2z' /%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:20px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='currentColor' class='icon icon-tabler icons-tabler-filled icon-tabler-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath d='M16 2a1 1 0 0 1 .993 .883l.007 .117v1h1a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h1v-1a1 1 0 0 1 1.993 -.117l.007 .117v1h6v-1a1 1 0 0 1 1 -1m3 7h-14v9.625c0 .705 .386 1.286 .883 1.366l.117 .009h12c.513 0 .936 -.53 .993 -1.215l.007 -.16z' /%3e%3cpath d='M8 14h2v2h-2z' /%3e%3c/svg%3e\")}.dropdown{position:absolute;top:100%;left:0;right: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}.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:10px 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"] });
|
|
1194
|
+
], ngImport: i0, template: "<div class=\"datetime-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div\r\n class=\"chip-input-wrapper\"\r\n [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\"\r\n >\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\r\n class=\"mask-char\"\r\n [class.mask-char-filled]=\"part.filled\"\r\n [class.mask-char-placeholder]=\"!part.filled\"\r\n >\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input\r\n type=\"text\"\r\n [value]=\"inputTextValue()\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\"\r\n [placeholder]=\"''\"\r\n class=\"chip-input\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n\r\n <button\r\n type=\"button\"\r\n class=\"calendar-icon-button\"\r\n (click)=\"toggle(item.value)\"\r\n title=\"Abrir calendario\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\"\r\n >\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path\r\n 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 />\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\">\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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>\r\n</div>\r\n", styles: [".datetime-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;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;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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip-input-wrapper.has-value .floating-label{opacity:.6}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 16px;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, 14px);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}.chip-input:disabled{cursor:not-allowed;opacity:.6}.chip-input-mask{position:absolute;left:16px;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);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);z-index:1;display:flex}.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:1}.calendar-icon-button:hover{background-color:#7878611a;color:var(--schemes-on-surface-variant, #454733)}.calendar-icon-button:active{background-color:#78786133}.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;right: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}.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 }] });
|
|
1196
1195
|
}
|
|
1197
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1196
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DateTimeFilter, decorators: [{
|
|
1198
1197
|
type: Component,
|
|
1199
|
-
args: [{ selector: 'lib-date-time-
|
|
1198
|
+
args: [{ selector: 'lib-date-time-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule], providers: [
|
|
1200
1199
|
{
|
|
1201
1200
|
provide: NG_VALUE_ACCESSOR,
|
|
1202
|
-
useExisting: forwardRef(() =>
|
|
1201
|
+
useExisting: forwardRef(() => DateTimeFilter),
|
|
1203
1202
|
multi: true,
|
|
1204
1203
|
},
|
|
1205
|
-
], template: "<div class=\"datetime-container\">\r\n <div\r\n class=\"datetime-header\"\r\n [class.active]=\"isOpen()\"\r\n [class.disabled]=\"isBlocked()\"\r\n [class.readonly]=\"isBlocked()\"\r\n (click)=\"!isBlocked() && toggle()\"\r\n (keydown)=\"!isBlocked() && onKeyDown($event)\"\r\n tabindex=\"0\"\r\n >\r\n <input\r\n type=\"text\"\r\n class=\"datetime-input\"\r\n [value]=\"displayValue()\"\r\n [placeholder]=\"placeholder()\"\r\n (input)=\"onInputChange($event)\"\r\n (focus)=\"!isBlocked() && onInputFocus()\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"isDisabled()\"\r\n [readOnly]=\"readonly()\"\r\n />\r\n\r\n <div class=\"header-icons\">\r\n @if (selectedDate()) {\r\n <span\r\n class=\"clear-icon\"\r\n (click)=\"!isBlocked() && clear(); $event.stopPropagation()\"\r\n title=\"Limpiar\"\r\n >\r\n \u00D7\r\n </span>\r\n }\r\n <span class=\"arrow\" [class.open]=\"isOpen()\"></span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (isOpen()) {\r\n<div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n del calendario -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">{{ monthName() }} {{ currentYear() }}</div>\r\n\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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 del mes -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n {{ day || '' }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Selector de tiempo (solo si mode === 'datetime') -->\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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\r\n <!-- Botones de acci\u00F3n -->\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 @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", styles: [".datetime-container{position:relative;width:100%}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:12px 15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-input{flex:1;border:none;outline:none;background:transparent;font-size:1.3rem;color:#454733;padding:0;margin:0}.datetime-input::placeholder{color:#787861}.datetime-input:disabled{cursor:not-allowed}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled,.datetime-header.readonly{pointer-events:none;opacity:.6;cursor:not-allowed}.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:20px;height:20px;background-image:url(\"data:image/svg+xml,%3csvg 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-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath 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' /%3e%3cpath d='M16 3l0 4' /%3e%3cpath d='M8 3l0 4' /%3e%3cpath d='M4 11l16 0' /%3e%3cpath d='M8 15h2v2h-2z' /%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:20px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='currentColor' class='icon icon-tabler icons-tabler-filled icon-tabler-calendar-event'%3e%3cpath stroke='none' d='M0 0h24v24H0z' fill='none'/%3e%3cpath d='M16 2a1 1 0 0 1 .993 .883l.007 .117v1h1a3 3 0 0 1 2.995 2.824l.005 .176v12a3 3 0 0 1 -2.824 2.995l-.176 .005h-12a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-12a3 3 0 0 1 2.824 -2.995l.176 -.005h1v-1a1 1 0 0 1 1.993 -.117l.007 .117v1h6v-1a1 1 0 0 1 1 -1m3 7h-14v9.625c0 .705 .386 1.286 .883 1.366l.117 .009h12c.513 0 .936 -.53 .993 -1.215l.007 -.16z' /%3e%3cpath d='M8 14h2v2h-2z' /%3e%3c/svg%3e\")}.dropdown{position:absolute;top:100%;left:0;right: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}.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:10px 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"] }]
|
|
1206
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: {
|
|
1204
|
+
], template: "<div class=\"datetime-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div\r\n class=\"chip-input-wrapper\"\r\n [class.has-value]=\"selectedDate() || inputTextValue()\"\r\n [class.active]=\"activeFilterType() === item.value\"\r\n >\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\r\n class=\"mask-char\"\r\n [class.mask-char-filled]=\"part.filled\"\r\n [class.mask-char-placeholder]=\"!part.filled\"\r\n >\r\n {{ part.char }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <input\r\n type=\"text\"\r\n [value]=\"inputTextValue()\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n (focus)=\"onInputFocus(item.value)\"\r\n [placeholder]=\"''\"\r\n class=\"chip-input\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n\r\n <button\r\n type=\"button\"\r\n class=\"calendar-icon-button\"\r\n (click)=\"toggle(item.value)\"\r\n title=\"Abrir calendario\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-calendar-event\"\r\n >\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path\r\n 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 />\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\">\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\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\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\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\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\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\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\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>\r\n</div>\r\n", styles: [".datetime-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;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;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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip-input-wrapper.has-value .floating-label{opacity:.6}.chip-input{border:none;outline:none;background:transparent;padding:6px 40px 6px 16px;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, 14px);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}.chip-input:disabled{cursor:not-allowed;opacity:.6}.chip-input-mask{position:absolute;left:16px;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);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);z-index:1;display:flex}.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:1}.calendar-icon-button:hover{background-color:#7878611a;color:var(--schemes-on-surface-variant, #454733)}.calendar-icon-button:active{background-color:#78786133}.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;right: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}.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"] }]
|
|
1205
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }], clearTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTrigger", required: false }] }] } });
|
|
1207
1206
|
|
|
1208
1207
|
class InputNumberFilter {
|
|
1209
1208
|
// Inputs
|
|
@@ -1273,8 +1272,8 @@ class InputNumberFilter {
|
|
|
1273
1272
|
this.onTouched();
|
|
1274
1273
|
}
|
|
1275
1274
|
}
|
|
1276
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1277
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1275
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputNumberFilter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1276
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: InputNumberFilter, isStandalone: true, selector: "lib-input-number-filter", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, clearTrigger: { classPropertyName: "clearTrigger", publicName: "clearTrigger", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterSelected: "filterSelected", valueChange: "valueChange" }, providers: [
|
|
1278
1277
|
{
|
|
1279
1278
|
provide: NG_VALUE_ACCESSOR,
|
|
1280
1279
|
useExisting: forwardRef(() => InputNumberFilter),
|
|
@@ -1282,7 +1281,7 @@ class InputNumberFilter {
|
|
|
1282
1281
|
},
|
|
1283
1282
|
], ngImport: i0, template: "<div class=\"input-filter-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip-input-wrapper\" [class.has-value]=\"filterValues()[item.value]\">\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || 'Escribir N\u00FAmero' }}</label>\r\n <input\r\n type=\"number\"\r\n [value]=\"filterValues()[item.value] || ''\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n [placeholder]=\"filterValues()[item.value] ? '' : (item.placeholder || item.label || 'Escribir N\u00FAmero')\"\r\n class=\"chip-input\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".input-filter-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;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;height:32px;flex-shrink:0;transition:.2s ease;background-color:transparent}.chip-input-wrapper:hover{background-color:#ececcf}.chip-input-wrapper:focus-within{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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip-input-wrapper.has-value .floating-label{opacity:.6}.chip-input{border:none;outline:none;background:transparent;padding:6px 30px 6px 16px;height:100%;width:100%;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, 14px);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;-moz-appearance:textfield;appearance:textfield}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6}.chip-input:disabled{cursor:not-allowed;opacity:.6}.chip-input::-webkit-inner-spin-button{opacity:1;cursor:pointer;background-color:transparent;height:100%;width:20px;margin:0;padding:0;position:absolute;right:0;top:0}.chip-input::-webkit-outer-spin-button{background-color:transparent;opacity:1;cursor:pointer;height:100%;width:20px;margin:0;padding:0;position:absolute;right:0;top:0}.icon.icon-tabler-abc{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.action-buttons{display:flex;justify-content:flex-end;gap:10px}.action-btn{padding:8px 16px;border:none;border-radius:3px;cursor:pointer;font-size:.9rem;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}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }] });
|
|
1284
1283
|
}
|
|
1285
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1284
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputNumberFilter, decorators: [{
|
|
1286
1285
|
type: Component,
|
|
1287
1286
|
args: [{ selector: 'lib-input-number-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule], providers: [
|
|
1288
1287
|
{
|
|
@@ -1487,8 +1486,8 @@ class InputSelectFilter {
|
|
|
1487
1486
|
this.documentClickListener = undefined;
|
|
1488
1487
|
}
|
|
1489
1488
|
}
|
|
1490
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1491
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1489
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputSelectFilter, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
1490
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: InputSelectFilter, isStandalone: true, selector: "lib-input-select-filter", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, clearTrigger: { classPropertyName: "clearTrigger", publicName: "clearTrigger", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterSelected: "filterSelected", valueChange: "valueChange" }, providers: [
|
|
1492
1491
|
{
|
|
1493
1492
|
provide: NG_VALUE_ACCESSOR,
|
|
1494
1493
|
useExisting: forwardRef(() => InputSelectFilter),
|
|
@@ -1496,7 +1495,7 @@ class InputSelectFilter {
|
|
|
1496
1495
|
},
|
|
1497
1496
|
], ngImport: i0, template: "<div class=\"input-filter-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip\" [class.active]=\"activeFilterType() === item.value\" [class.has-value]=\"filterValues()[item.value]\">\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || 'Seleccionar' }}</label>\r\n <div class=\"content-chip\">\r\n <input\r\n type=\"text\"\r\n class=\"chip-input\"\r\n [value]=\"filterValues()[item.value] || ''\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n (focus)=\"onFocusFilter(item.value)\"\r\n (click)=\"$event.stopPropagation()\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [placeholder]=\"filterValues()[item.value] ? '' : (item.placeholder || item.label || 'Seleccionar')\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" 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-list\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\r\n <path d=\"M9 6l11 0\" />\r\n <path d=\"M9 12l11 0\" />\r\n <path d=\"M9 18l11 0\" />\r\n <path d=\"M5 6l0 .01\" />\r\n <path d=\"M5 12l0 .01\" />\r\n <path d=\"M5 18l0 .01\" />\r\n </svg>\r\n </div>\r\n\r\n @if (isOpen() && activeFilterType() === item.value) {\r\n <div class=\"dropdown\">\r\n <div class=\"options-list\">\r\n @for (option of filteredOptions(); track option.value) {\r\n <div class=\"option-item\" (click)=\"selectOption(option)\">\r\n {{ option.label }}\r\n </div>\r\n }\r\n @if (filteredOptions().length === 0) {\r\n <div class=\"no-options\">No hay opciones</div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".input-filter-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;border-radius:12px;position:relative}.chip{border-radius:8px;border-style:solid;border-color:var(--schemes-outline-variant, #c0c7cd);border-width:1px;display:flex;flex-direction:row;align-items:center;justify-content:center;flex-shrink:0;height:32px;cursor:pointer;transition:.2s ease;position:relative}.chip:hover{background-color:#ececcf}.chip.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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip.has-value .floating-label{opacity:.6}.content-chip{padding:0 8px;display:flex;flex-direction:row;gap:8px;align-items:center;justify-items:center;height:32px}.label-text{display:none}.chip-input{border:none;outline:none;background:transparent;height:100%;width:100%;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, 14px);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)}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6}.chip-input:disabled{cursor:not-allowed;opacity:.6}.icon{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.dropdown{position:absolute;top:100%;left:0;right: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:200px;padding:0;overflow:hidden}.options-list{display:flex;flex-direction:column;max-height:200px;overflow-y:auto}.option-item{padding:10px 15px;cursor:pointer;color:#454733;font-size:.9rem;transition:background-color .2s}.option-item:hover{background-color:#7878611a}.no-options{padding:10px 15px;color:#787861;font-size:.9rem;font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }] });
|
|
1498
1497
|
}
|
|
1499
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1498
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputSelectFilter, decorators: [{
|
|
1500
1499
|
type: Component,
|
|
1501
1500
|
args: [{ selector: 'lib-input-select-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule], providers: [
|
|
1502
1501
|
{
|
|
@@ -1593,8 +1592,8 @@ class InputTextFilter {
|
|
|
1593
1592
|
this.onTouched();
|
|
1594
1593
|
}
|
|
1595
1594
|
}
|
|
1596
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1597
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1595
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputTextFilter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1596
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: InputTextFilter, isStandalone: true, selector: "lib-input-text-filter", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, clearTrigger: { classPropertyName: "clearTrigger", publicName: "clearTrigger", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterSelected: "filterSelected", valueChange: "valueChange" }, providers: [
|
|
1598
1597
|
{
|
|
1599
1598
|
provide: NG_VALUE_ACCESSOR,
|
|
1600
1599
|
useExisting: forwardRef(() => InputTextFilter),
|
|
@@ -1602,7 +1601,7 @@ class InputTextFilter {
|
|
|
1602
1601
|
},
|
|
1603
1602
|
], ngImport: i0, template: "<div class=\"input-filter-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip-input-wrapper\" [class.has-value]=\"filterValues()[item.value]\">\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || 'Escribir' }}</label>\r\n <input\r\n type=\"text\"\r\n [value]=\"filterValues()[item.value] || ''\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n [placeholder]=\"filterValues()[item.value] ? '' : (item.placeholder || item.label || 'Escribir')\"\r\n class=\"chip-input\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n @if (filterValues()[item.value]) {\r\n <button\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"clearFilter(item.value)\"\r\n title=\"Limpiar\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M18 6l-12 12\" />\r\n <path d=\"M6 6l12 12\" />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".input-filter-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;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;height:32px;flex-shrink:0;transition:.2s ease;background-color:transparent}.chip-input-wrapper:hover{background-color:#ececcf}.chip-input-wrapper:focus-within{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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip-input-wrapper.has-value .floating-label{opacity:.6}.chip-input{border:none;outline:none;background:transparent;padding:6px 35px 6px 16px;height:100%;width:100%;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, 14px);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}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6}.chip-input:disabled{cursor:not-allowed;opacity:.6}.icon.icon-tabler-abc{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.clear-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:1}.clear-button:hover{background-color:#7878611a;color:var(--schemes-on-surface-variant, #454733)}.clear-button:active{background-color:#78786133}.clear-button svg{width:16px;height:16px}.action-buttons{display:flex;justify-content:flex-end;gap:10px}.action-btn{padding:8px 16px;border:none;border-radius:3px;cursor:pointer;font-size:.9rem;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}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }] });
|
|
1604
1603
|
}
|
|
1605
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputTextFilter, decorators: [{
|
|
1606
1605
|
type: Component,
|
|
1607
1606
|
args: [{ selector: 'lib-input-text-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule], providers: [
|
|
1608
1607
|
{
|
|
@@ -1613,6 +1612,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
1613
1612
|
], template: "<div class=\"input-filter-container\">\r\n <div class=\"filter-chips\">\r\n @for (item of filters(); track item.value) {\r\n <div class=\"chip-input-wrapper\" [class.has-value]=\"filterValues()[item.value]\">\r\n <label class=\"floating-label\">{{ item.placeholder || item.label || 'Escribir' }}</label>\r\n <input\r\n type=\"text\"\r\n [value]=\"filterValues()[item.value] || ''\"\r\n (input)=\"onInputChange($event, item.value)\"\r\n [placeholder]=\"filterValues()[item.value] ? '' : (item.placeholder || item.label || 'Escribir')\"\r\n class=\"chip-input\"\r\n [disabled]=\"isDisabled()\"\r\n />\r\n @if (filterValues()[item.value]) {\r\n <button\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"clearFilter(item.value)\"\r\n title=\"Limpiar\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\r\n <path d=\"M18 6l-12 12\" />\r\n <path d=\"M6 6l12 12\" />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".input-filter-container{position:relative;width:100%}.filter-chips{display:flex;gap:10px;padding:8px;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;height:32px;flex-shrink:0;transition:.2s ease;background-color:transparent}.chip-input-wrapper:hover{background-color:#ececcf}.chip-input-wrapper:focus-within{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:11px;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:#ebeccf;padding:0 4px;border-radius:2px}.chip-input-wrapper.has-value .floating-label{opacity:.6}.chip-input{border:none;outline:none;background:transparent;padding:6px 35px 6px 16px;height:100%;width:100%;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, 14px);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}.chip-input::placeholder{color:var(--schemes-on-surface-variant, #454733);opacity:.6}.chip-input:disabled{cursor:not-allowed;opacity:.6}.icon.icon-tabler-abc{width:18px;height:18px;color:var(--on-surface-variant, #40484c)}.clear-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:1}.clear-button:hover{background-color:#7878611a;color:var(--schemes-on-surface-variant, #454733)}.clear-button:active{background-color:#78786133}.clear-button svg{width:16px;height:16px}.action-buttons{display:flex;justify-content:flex-end;gap:10px}.action-btn{padding:8px 16px;border:none;border-radius:3px;cursor:pointer;font-size:.9rem;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}\n"] }]
|
|
1614
1613
|
}], ctorParameters: () => [], propDecorators: { filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }], clearTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTrigger", required: false }] }], filterSelected: [{ type: i0.Output, args: ["filterSelected"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
1615
1614
|
|
|
1615
|
+
class Input {
|
|
1616
|
+
placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : []));
|
|
1617
|
+
type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
1618
|
+
value = model('', ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
1619
|
+
valueChange = output();
|
|
1620
|
+
onSearch = output();
|
|
1621
|
+
onClear = output();
|
|
1622
|
+
clear() {
|
|
1623
|
+
this.value.set('');
|
|
1624
|
+
this.valueChange.emit('');
|
|
1625
|
+
this.onClear.emit();
|
|
1626
|
+
}
|
|
1627
|
+
search() {
|
|
1628
|
+
this.onSearch.emit(this.value());
|
|
1629
|
+
}
|
|
1630
|
+
handleInput(event) {
|
|
1631
|
+
const target = event.target;
|
|
1632
|
+
let inputValue = target.value;
|
|
1633
|
+
if (this.type() === 'number') {
|
|
1634
|
+
inputValue = inputValue.replace(/[^0-9]/g, '');
|
|
1635
|
+
target.value = inputValue;
|
|
1636
|
+
}
|
|
1637
|
+
this.value.set(inputValue);
|
|
1638
|
+
this.valueChange.emit(inputValue);
|
|
1639
|
+
}
|
|
1640
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Input, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1641
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: Input, isStandalone: true, selector: "lib-input", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange", onSearch: "onSearch", onClear: "onClear" }, ngImport: i0, template: "<div class=\"input-wrapper\">\r\n <input\r\n [type]=\"type()\"\r\n [placeholder]=\"placeholder()\"\r\n class=\"custom-input\"\r\n [value]=\"value()\"\r\n (input)=\"handleInput($event)\"\r\n (keyup.enter)=\"search()\"\r\n />\r\n\r\n @if (value()) {\r\n <button class=\"clear-btn\" (click)=\"clear()\" type=\"button\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"M18 6l-12 12\" />\r\n <path d=\"M6 6l12 12\" />\r\n </svg>\r\n </button>\r\n }\r\n\r\n <button class=\"search-btn\" (click)=\"search()\" type=\"button\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"56\"\r\n height=\"56\"\r\n fill=\"none\"\r\n viewBox=\"0 0 56 56\"\r\n >\r\n <g clip-path=\"url(#clip0_190_2403)\">\r\n <path\r\n fill=\"#454733\"\r\n d=\"M31.755 30.255h-.79l-.28-.27a6.47 6.47 0 0 0 1.57-4.23 6.5 6.5 0 1 0-6.5 6.5c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99 1.49-1.49zm-6 0c-2.49 0-4.5-2.01-4.5-4.5s2.01-4.5 4.5-4.5 4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5\"\r\n />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_190_2403\">\r\n <rect width=\"56\" height=\"56\" fill=\"#fff\" rx=\"28\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </button>\r\n</div>\r\n", styles: [".input-wrapper{position:relative;width:100%}.custom-input{width:100%;padding:20px 50px 20px 20px;border-radius:32px;font-size:16px;background-color:#fff;border:none}custom-input::placeholder{color:#40484c;opacity:1}.custom-input:focus{outline:none;box-shadow:0 0 0 3px #8bc34a1a}.custom-input:hover{background-color:#d8dfe4;transform:translateY(-1px)}.clear-btn{position:absolute;right:55px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;font-size:10px;color:#596300;padding:5px}.clear-btn svg{height:50px;pointer-events:none;transition:filter .2s ease}.clear-btn:hover{color:red}.clear-btn:hover svg{filter:brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%)}.search-btn{position:absolute;right:5px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;font-size:18px;border-radius:50%;background-color:#596300;display:flex;justify-content:center;align-items:center;width:50px;height:50px}.search-btn svg{filter:brightness(0) invert(1)}.search-btn:hover{background:#7cb342}input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] });
|
|
1642
|
+
}
|
|
1643
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Input, decorators: [{
|
|
1644
|
+
type: Component,
|
|
1645
|
+
args: [{ selector: 'lib-input', standalone: true, imports: [], template: "<div class=\"input-wrapper\">\r\n <input\r\n [type]=\"type()\"\r\n [placeholder]=\"placeholder()\"\r\n class=\"custom-input\"\r\n [value]=\"value()\"\r\n (input)=\"handleInput($event)\"\r\n (keyup.enter)=\"search()\"\r\n />\r\n\r\n @if (value()) {\r\n <button class=\"clear-btn\" (click)=\"clear()\" type=\"button\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"M18 6l-12 12\" />\r\n <path d=\"M6 6l12 12\" />\r\n </svg>\r\n </button>\r\n }\r\n\r\n <button class=\"search-btn\" (click)=\"search()\" type=\"button\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"56\"\r\n height=\"56\"\r\n fill=\"none\"\r\n viewBox=\"0 0 56 56\"\r\n >\r\n <g clip-path=\"url(#clip0_190_2403)\">\r\n <path\r\n fill=\"#454733\"\r\n d=\"M31.755 30.255h-.79l-.28-.27a6.47 6.47 0 0 0 1.57-4.23 6.5 6.5 0 1 0-6.5 6.5c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99 1.49-1.49zm-6 0c-2.49 0-4.5-2.01-4.5-4.5s2.01-4.5 4.5-4.5 4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5\"\r\n />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_190_2403\">\r\n <rect width=\"56\" height=\"56\" fill=\"#fff\" rx=\"28\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </button>\r\n</div>\r\n", styles: [".input-wrapper{position:relative;width:100%}.custom-input{width:100%;padding:20px 50px 20px 20px;border-radius:32px;font-size:16px;background-color:#fff;border:none}custom-input::placeholder{color:#40484c;opacity:1}.custom-input:focus{outline:none;box-shadow:0 0 0 3px #8bc34a1a}.custom-input:hover{background-color:#d8dfe4;transform:translateY(-1px)}.clear-btn{position:absolute;right:55px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;font-size:10px;color:#596300;padding:5px}.clear-btn svg{height:50px;pointer-events:none;transition:filter .2s ease}.clear-btn:hover{color:red}.clear-btn:hover svg{filter:brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%)}.search-btn{position:absolute;right:5px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;font-size:18px;border-radius:50%;background-color:#596300;display:flex;justify-content:center;align-items:center;width:50px;height:50px}.search-btn svg{filter:brightness(0) invert(1)}.search-btn:hover{background:#7cb342}input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] }]
|
|
1646
|
+
}], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], onSearch: [{ type: i0.Output, args: ["onSearch"] }], onClear: [{ type: i0.Output, args: ["onClear"] }] } });
|
|
1647
|
+
|
|
1616
1648
|
class SelectCustomSearch {
|
|
1617
1649
|
elementRef;
|
|
1618
1650
|
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
@@ -1711,8 +1743,8 @@ class SelectCustomSearch {
|
|
|
1711
1743
|
this.close();
|
|
1712
1744
|
}
|
|
1713
1745
|
}
|
|
1714
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1715
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1746
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SelectCustomSearch, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1747
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: SelectCustomSearch, isStandalone: true, selector: "lib-select-custom-search", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [
|
|
1716
1748
|
{
|
|
1717
1749
|
provide: NG_VALUE_ACCESSOR,
|
|
1718
1750
|
useExisting: forwardRef(() => SelectCustomSearch),
|
|
@@ -1720,7 +1752,7 @@ class SelectCustomSearch {
|
|
|
1720
1752
|
},
|
|
1721
1753
|
], ngImport: i0, template: "<div class=\"select-container\">\r\n <div\r\n class=\"select-header\"\r\n [class.active]=\"isOpen()\"\r\n [class.disabled]=\"isBlocked()\"\r\n [class.readonly]=\"isBlocked()\"\r\n (click)=\"!isBlocked() && toggle()\"\r\n (keydown)=\"!isBlocked() && onKeyDown($event)\"\r\n tabindex=\"0\"\r\n >\r\n <span class=\"selected-text\" [class.placeholder]=\"!selectedOption()\">\r\n {{ selectedOption()?.label || placeholder() }}\r\n </span>\r\n\r\n <span class=\"arrow\" [class.open]=\"isOpen()\"></span>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div class=\"dropdown\">\r\n <input\r\n type=\"text\"\r\n class=\"search-input\"\r\n [value]=\"searchTerm()\"\r\n placeholder=\"Buscar...\"\r\n (input)=\"!isBlocked() &&onSearch($event)\"\r\n (keydown)=\"!isBlocked() && onKeyDown($event)\"\r\n />\r\n\r\n @if (filteredOptions().length > 0) {\r\n <div class=\"options\">\r\n @for (option of filteredOptions(); track option.value) {\r\n <div\r\n class=\"option\"\r\n [class.selected]=\"option.value === selectedValue()\"\r\n (click)=\"!isBlocked() && selectOption(option)\"\r\n [attr.disabled]=\"isBlocked()\"\r\n >\r\n {{ option.label }}\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"no-results\">No se encontraron resultados</div>\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".select-container{position:relative;width:100%}.select-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}.select-header:hover,.select-header:focus{outline:none;border-color:#a9a97f}.select-header.active{border-color:#a9a97f;outline:none}.select-header.disabled,.select-header.readonly{cursor:not-allowed;opacity:.6;pointer-events:none}.selected-text{color:#454733;font-size:1.3rem}.selected-text.placeholder{color:#787861}.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;right:0;background:#e3e3d1;border:1px solid #787861;border-top:none;border-radius:0 0 5px 5px;max-height:250px;overflow:hidden;z-index:1000;box-shadow:0 2px 8px #0000001a}.search-input{width:100%;border:none;border-bottom:1px solid #787861;border-radius:0;padding:15px;background-color:transparent;outline:none;font-size:inherit;color:#454733;font-size:1.3rem}.search-input::placeholder{color:#787861}.search-input:focus{outline:none;border-bottom-color:#a9a97f}.options{max-height:180px;overflow-y:auto;background:#e3e3d1}.option{padding:15px;cursor:pointer;border-bottom:1px solid rgba(120,120,97,.2);color:#454733;background:#e3e3d1;font-size:1.3rem}.option:hover{background-color:#a9a97f1a;color:#454733}.option.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.option:last-child{border-bottom:none}.no-results{padding:15px;text-align:center;color:#787861;font-style:italic;background:#e3e3d1;font-size:1.3rem}.options::-webkit-scrollbar{width:6px}.options::-webkit-scrollbar-track{background:#7878611a}.options::-webkit-scrollbar-thumb{background:#787861;border-radius:3px}.options::-webkit-scrollbar-thumb:hover{background:#a9a97f}@media (max-width: 768px){.select-header,.search-input,.option{padding:12px 15px}}\n"] });
|
|
1722
1754
|
}
|
|
1723
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1755
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SelectCustomSearch, decorators: [{
|
|
1724
1756
|
type: Component,
|
|
1725
1757
|
args: [{ selector: 'lib-select-custom-search', imports: [], providers: [
|
|
1726
1758
|
{
|
|
@@ -1840,12 +1872,12 @@ class DynamicFormFields {
|
|
|
1840
1872
|
}
|
|
1841
1873
|
onCancel() {
|
|
1842
1874
|
}
|
|
1843
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1844
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1875
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormFields, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1876
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DynamicFormFields, isStandalone: true, selector: "lib-dynamic-form-fields", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (form()) {\r\n<form class=\"form\" [formGroup]=\"form()\" [class.form--compact]=\"compact()\">\r\n @for (sec of sections(); track $index) {\r\n <section class=\"section\">\r\n @if (sec.title) {\r\n <h3 class=\"section-title\">{{ sec.title }}</h3>\r\n } @if (sec.description) {\r\n <p class=\"section-desc\">{{ sec.description }}</p>\r\n }\r\n\r\n <div class=\"grid\">\r\n @for (f of sec.fields; track f.key) {\r\n <div class=\"col\" [style.--col-span]=\"f.col || 6\">\r\n @if(f.label) {\r\n <label\r\n [class.label-radio]=\"f.type === 'radio'\"\r\n [class.label-checkbox]=\"f.type === 'checkbox'\"\r\n [class.label-disabled]=\"f.readonly || f.disabled\"\r\n class=\"label\"\r\n >\r\n {{ f.label }} </label\r\n >} @if (['text','number','email', 'password', 'time'].includes(f.type))\r\n {\r\n <input\r\n class=\"input\"\r\n [type]=\"f.type\"\r\n [placeholder]=\"f.placeholder\"\r\n [formControlName]=\"f.key\"\r\n [disabled]=\"f.disabled || false\"\r\n [readonly]=\"f.readonly || false\"\r\n />\r\n } @if (['date', 'datetime-local'].includes(f.type)) {\r\n <lib-date-time-picker\r\n [mode]=\"getDatePickerMode(f.type)\"\r\n [placeholder]=\"\r\n f.placeholder ||\r\n (f.type === 'date'\r\n ? 'Seleccionar fecha'\r\n : 'Seleccionar fecha y hora')\r\n \"\r\n [formControlName]=\"f.key\"\r\n [minDate]=\"f.minDate || null\"\r\n [maxDate]=\"f.maxDate || null\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n />\r\n } @if (f.type === 'textarea') {\r\n <textarea\r\n class=\"input textarea\"\r\n [placeholder]=\"f.placeholder\"\r\n [formControlName]=\"f.key\"\r\n rows=\"6\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n ></textarea>\r\n }@if (f.type === 'select') {\r\n\r\n <lib-select-custom-search\r\n [options]=\"f.options ?? []\"\r\n [placeholder]=\"f.placeholder || 'Seleccionar...'\"\r\n [formControlName]=\"f.key\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n />\r\n } @if (f.type === 'radio') {\r\n <div class=\"radio-group\">\r\n @for (o of f.options ?? []; track o.value) {\r\n <label class=\"radio\">\r\n {{ o.label }}\r\n <input type=\"radio\" [value]=\"o.value\" [formControlName]=\"f.key\" [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\" />\r\n </label>\r\n }\r\n </div>\r\n } @if (f.type === 'checkbox') {\r\n <div class=\"checkbox-group\">\r\n @for (o of f.options ?? []; track o.value; let i = $index) {\r\n <label class=\"checkbox\">\r\n {{ o.label }}\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"getCheckboxArray(f.key).at(i).value\"\r\n (change)=\"onCheckboxChange($event, f.key, i)\"\r\n />\r\n </label>\r\n }\r\n </div>\r\n } @if (f.type === 'disabled') {\r\n <label class=\"label\">{{ f.label }}</label>\r\n <input\r\n class=\"input input--disabled\"\r\n [placeholder]=\"f.placeholder || 'Autom\u00E1tico'\"\r\n disabled\r\n />\r\n } @if (ctrl(f.key)?.touched && ctrl(f.key)?.invalid) {\r\n <div class=\"error\">\r\n @if (ctrl(f.key)?.errors?.['required']) {\r\n <span>Campo requerido</span>\r\n } @if (ctrl(f.key)?.errors?.['email']) {\r\n <span>Correo inv\u00E1lido</span>\r\n } @if (ctrl(f.key)?.errors?.['pattern']) {\r\n <span>\r\n @switch (f.patternType) { @case ('numbers') { Solo se permiten\r\n n\u00FAmeros } @case ('phone') { Formato de tel\u00E9fono inv\u00E1lido } @case\r\n ('text') { Solo se permiten letras y espacios } @case ('username') {\r\n Solo se permiten letras, n\u00FAmeros, puntos y guiones bajos (no al\r\n inicio ni al final) } @case ('alphanumeric') { Solo se permiten\r\n letras y n\u00FAmeros } @default { Formato inv\u00E1lido } }\r\n </span>\r\n } @if (ctrl(f.key)?.errors?.['notMatching']) {\r\n <span>Las contrase\u00F1as no coinciden</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </section>\r\n }\r\n</form>\r\n}\r\n", styles: [".form{width:100%}.form{display:grid}.section{padding:20px 0 0}.section-title{font-size:1.6rem;font-weight:700;margin-bottom:30px}.section-desc{margin:0 0 .75rem;color:#666}.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:16px}.col{grid-column:span var(--col-span, 6);min-width:0;width:100%;position:relative;padding-bottom:20px}.label{position:absolute;top:-8px;left:12px;font-size:1.2rem;color:#454733;background-color:var(--surface-container-high, #ebe8d6);padding:0 4px;font-weight:500;z-index:1}.input{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent}input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=date]::-webkit-calendar-picker-indicator{position:absolute;inset:0;width:auto;height:auto;color:transparent;background:transparent}.input:focus{outline:none;border-color:#a9a97f}.input--disabled{color:#888}.label-radio{font-size:1.4rem;position:static;padding-left:0}.radio-group{display:flex;gap:1rem;padding:.5rem 0}.radio{font-size:1.4rem;display:flex;align-items:center;gap:10px;color:#1c1c12;margin-top:20px}.error{position:absolute;bottom:0;left:0;font-size:1.2rem;color:#b00020;width:100%;height:15px;display:none}.col:has(.error) .error{display:block}.textarea{resize:vertical;min-height:100px;max-height:300px;line-height:1.5}select{appearance:none;-webkit-appearance:none;-moz-appearance:none;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:right 15px center;cursor:pointer}select:invalid{color:#787861}select.placeholder-selected{color:#787861}select:not(.placeholder-selected){color:#000}select option{color:#454733;cursor:pointer}input[type=date]{color:#787861!important}input[type=date]:valid{color:#454733!important}.label-disabled{color:#1c1c1266}.input:disabled,.input--disabled,.input.disabled,.input[readonly]{border:1px solid #a9a97f;color:#a9a97f;cursor:not-allowed;pointer-events:none}@media (max-width: 768px){.grid{grid-template-columns:1fr}.col{grid-column:span 1!important}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: SelectCustomSearch, selector: "lib-select-custom-search", inputs: ["options", "placeholder", "readonly"], outputs: ["selectionChange"] }, { kind: "component", type: DateTimePicker, selector: "lib-date-time-picker", inputs: ["mode", "placeholder", "minDate", "maxDate", "readonly"], outputs: ["dateChange"] }] });
|
|
1845
1877
|
}
|
|
1846
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1878
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DynamicFormFields, decorators: [{
|
|
1847
1879
|
type: Component,
|
|
1848
|
-
args: [{ selector: 'lib-dynamic-form-fields', standalone: true, imports: [ReactiveFormsModule, SelectCustomSearch, DateTimePicker], template: "@if (form()) {\r\n<form class=\"form\" [formGroup]=\"form()\" [class.form--compact]=\"compact()\">\r\n @for (sec of sections(); track $index) {\r\n <section class=\"section\">\r\n @if (sec.title) {\r\n <h3 class=\"section-title\">{{ sec.title }}</h3>\r\n } @if (sec.description) {\r\n <p class=\"section-desc\">{{ sec.description }}</p>\r\n }\r\n\r\n <div class=\"grid\">\r\n @for (f of sec.fields; track f.key) {\r\n <div class=\"col\" [style.--col-span]=\"f.col || 6\">\r\n @if(f.label) {\r\n <label\r\n [class.label-radio]=\"f.type === 'radio'\"\r\n [class.label-checkbox]=\"f.type === 'checkbox'\"\r\n [class.label-disabled]=\"f.readonly || f.disabled\"\r\n class=\"label\"\r\n >\r\n {{ f.label }} </label\r\n >} @if (['text','number','email', 'password', 'time'].includes(f.type))\r\n {\r\n <input\r\n class=\"input\"\r\n [type]=\"f.type\"\r\n [placeholder]=\"f.placeholder\"\r\n [formControlName]=\"f.key\"\r\n [disabled]=\"f.disabled || false\"\r\n [readonly]=\"f.readonly || false\"\r\n />\r\n } @if (['date', 'datetime-local'].includes(f.type)) {\r\n <lib-date-time-picker\r\n [mode]=\"getDatePickerMode(f.type)\"\r\n [placeholder]=\"\r\n f.placeholder ||\r\n (f.type === 'date'\r\n ? 'Seleccionar fecha'\r\n : 'Seleccionar fecha y hora')\r\n \"\r\n [formControlName]=\"f.key\"\r\n [minDate]=\"f.minDate || null\"\r\n [maxDate]=\"f.maxDate || null\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n />\r\n } @if (f.type === 'textarea') {\r\n <textarea\r\n class=\"input textarea\"\r\n [placeholder]=\"f.placeholder\"\r\n [formControlName]=\"f.key\"\r\n rows=\"6\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n ></textarea>\r\n }@if (f.type === 'select') {\r\n\r\n <lib-select-custom-search\r\n [options]=\"f.options ?? []\"\r\n [placeholder]=\"f.placeholder || 'Seleccionar...'\"\r\n [formControlName]=\"f.key\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n />\r\n } @if (f.type === 'radio') {\r\n <div class=\"radio-group\">\r\n @for (o of f.options ?? []; track o.value) {\r\n <label class=\"radio\">\r\n {{ o.label }}\r\n <input type=\"radio\" [value]=\"o.value\" [formControlName]=\"f.key\" [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\" />\r\n </label>\r\n }\r\n </div>\r\n } @if (f.type === 'checkbox') {\r\n <div class=\"checkbox-group\">\r\n @for (o of f.options ?? []; track o.value; let i = $index) {\r\n <label class=\"checkbox\">\r\n {{ o.label }}\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"getCheckboxArray(f.key).at(i).value\"\r\n (change)=\"onCheckboxChange($event, f.key, i)\"\r\n />\r\n </label>\r\n }\r\n </div>\r\n } @if (f.type === 'disabled') {\r\n <label class=\"label\">{{ f.label }}</label>\r\n <input\r\n class=\"input input--disabled\"\r\n [placeholder]=\"f.placeholder || 'Autom\u00E1tico'\"\r\n disabled\r\n />\r\n } @if (ctrl(f.key)?.touched && ctrl(f.key)?.invalid) {\r\n <div class=\"error\">\r\n @if (ctrl(f.key)?.errors?.['required']) {\r\n <span>Campo requerido</span>\r\n } @if (ctrl(f.key)?.errors?.['email']) {\r\n <span>Correo inv\u00E1lido</span>\r\n } @if (ctrl(f.key)?.errors?.['pattern']) {\r\n <span>\r\n @switch (f.patternType) { @case ('numbers') { Solo se permiten\r\n n\u00FAmeros } @case ('phone') { Formato de tel\u00E9fono inv\u00E1lido } @case\r\n ('text') { Solo se permiten letras y espacios } @case ('username') {\r\n Solo se permiten letras, n\u00FAmeros, puntos y guiones bajos (no al\r\n inicio ni al final) } @case ('alphanumeric') { Solo se permiten\r\n letras y n\u00FAmeros } @default { Formato inv\u00E1lido } }\r\n </span>\r\n } @if (ctrl(f.key)?.errors?.['notMatching']) {\r\n <span>Las contrase\u00F1as no coinciden</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </section>\r\n }\r\n</form>\r\n}\r\n", styles: [".form{width:100%}.form{display:grid}.section{padding:20px 0 0}.section-title{font-size:1.6rem;font-weight:700;margin-bottom:30px}.section-desc{margin:0 0 .75rem;color:#666}.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:16px}.col{grid-column:span var(--col-span, 6);min-width:0;width:100%;position:relative;padding-bottom:20px}.label{position:absolute;top:-8px;left:12px;font-size:1.2rem;color:#454733;background-color:var(--surface-container-high, #ebe8d6);padding:0 4px;font-weight:500;z-index:1}.input{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent}input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=date]::-webkit-calendar-picker-indicator{position:absolute;inset:0;width:auto;height:auto;color:transparent;background:transparent}.input:focus{outline:none;border-color:#a9a97f}.input--disabled{color:#888}.label-radio{font-size:1.4rem;position:static;padding-left:0}.radio-group{display:flex;gap:1rem;padding:.5rem 0}.radio{font-size:1.4rem;display:flex;align-items:center;gap:10px;color:#1c1c12;margin-top:20px}.error{position:absolute;bottom:0;left:0;font-size:1.2rem;color:#b00020;width:100%;height:15px;display:none}.col:has(.error) .error{display:block}.textarea{resize:vertical;min-height:100px;line-height:1.5}select{appearance:none;-webkit-appearance:none;-moz-appearance:none;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:right 15px center;cursor:pointer}select:invalid{color:#787861}select.placeholder-selected{color:#787861}select:not(.placeholder-selected){color:#000}select option{color:#454733;cursor:pointer}input[type=date]{color:#787861!important}input[type=date]:valid{color:#454733!important}.label-disabled{color:#1c1c1266}.input:disabled,.input--disabled,.input.disabled,.input[readonly]{border:1px solid #a9a97f;color:#a9a97f;cursor:not-allowed;pointer-events:none}@media (max-width: 768px){.grid{grid-template-columns:1fr}.col{grid-column:span 1!important}}\n"] }]
|
|
1880
|
+
args: [{ selector: 'lib-dynamic-form-fields', standalone: true, imports: [ReactiveFormsModule, SelectCustomSearch, DateTimePicker], template: "@if (form()) {\r\n<form class=\"form\" [formGroup]=\"form()\" [class.form--compact]=\"compact()\">\r\n @for (sec of sections(); track $index) {\r\n <section class=\"section\">\r\n @if (sec.title) {\r\n <h3 class=\"section-title\">{{ sec.title }}</h3>\r\n } @if (sec.description) {\r\n <p class=\"section-desc\">{{ sec.description }}</p>\r\n }\r\n\r\n <div class=\"grid\">\r\n @for (f of sec.fields; track f.key) {\r\n <div class=\"col\" [style.--col-span]=\"f.col || 6\">\r\n @if(f.label) {\r\n <label\r\n [class.label-radio]=\"f.type === 'radio'\"\r\n [class.label-checkbox]=\"f.type === 'checkbox'\"\r\n [class.label-disabled]=\"f.readonly || f.disabled\"\r\n class=\"label\"\r\n >\r\n {{ f.label }} </label\r\n >} @if (['text','number','email', 'password', 'time'].includes(f.type))\r\n {\r\n <input\r\n class=\"input\"\r\n [type]=\"f.type\"\r\n [placeholder]=\"f.placeholder\"\r\n [formControlName]=\"f.key\"\r\n [disabled]=\"f.disabled || false\"\r\n [readonly]=\"f.readonly || false\"\r\n />\r\n } @if (['date', 'datetime-local'].includes(f.type)) {\r\n <lib-date-time-picker\r\n [mode]=\"getDatePickerMode(f.type)\"\r\n [placeholder]=\"\r\n f.placeholder ||\r\n (f.type === 'date'\r\n ? 'Seleccionar fecha'\r\n : 'Seleccionar fecha y hora')\r\n \"\r\n [formControlName]=\"f.key\"\r\n [minDate]=\"f.minDate || null\"\r\n [maxDate]=\"f.maxDate || null\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n />\r\n } @if (f.type === 'textarea') {\r\n <textarea\r\n class=\"input textarea\"\r\n [placeholder]=\"f.placeholder\"\r\n [formControlName]=\"f.key\"\r\n rows=\"6\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n ></textarea>\r\n }@if (f.type === 'select') {\r\n\r\n <lib-select-custom-search\r\n [options]=\"f.options ?? []\"\r\n [placeholder]=\"f.placeholder || 'Seleccionar...'\"\r\n [formControlName]=\"f.key\"\r\n [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\"\r\n />\r\n } @if (f.type === 'radio') {\r\n <div class=\"radio-group\">\r\n @for (o of f.options ?? []; track o.value) {\r\n <label class=\"radio\">\r\n {{ o.label }}\r\n <input type=\"radio\" [value]=\"o.value\" [formControlName]=\"f.key\" [readonly]=\"f.readonly || false\"\r\n [disabled]=\"f.disabled || false\" />\r\n </label>\r\n }\r\n </div>\r\n } @if (f.type === 'checkbox') {\r\n <div class=\"checkbox-group\">\r\n @for (o of f.options ?? []; track o.value; let i = $index) {\r\n <label class=\"checkbox\">\r\n {{ o.label }}\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"getCheckboxArray(f.key).at(i).value\"\r\n (change)=\"onCheckboxChange($event, f.key, i)\"\r\n />\r\n </label>\r\n }\r\n </div>\r\n } @if (f.type === 'disabled') {\r\n <label class=\"label\">{{ f.label }}</label>\r\n <input\r\n class=\"input input--disabled\"\r\n [placeholder]=\"f.placeholder || 'Autom\u00E1tico'\"\r\n disabled\r\n />\r\n } @if (ctrl(f.key)?.touched && ctrl(f.key)?.invalid) {\r\n <div class=\"error\">\r\n @if (ctrl(f.key)?.errors?.['required']) {\r\n <span>Campo requerido</span>\r\n } @if (ctrl(f.key)?.errors?.['email']) {\r\n <span>Correo inv\u00E1lido</span>\r\n } @if (ctrl(f.key)?.errors?.['pattern']) {\r\n <span>\r\n @switch (f.patternType) { @case ('numbers') { Solo se permiten\r\n n\u00FAmeros } @case ('phone') { Formato de tel\u00E9fono inv\u00E1lido } @case\r\n ('text') { Solo se permiten letras y espacios } @case ('username') {\r\n Solo se permiten letras, n\u00FAmeros, puntos y guiones bajos (no al\r\n inicio ni al final) } @case ('alphanumeric') { Solo se permiten\r\n letras y n\u00FAmeros } @default { Formato inv\u00E1lido } }\r\n </span>\r\n } @if (ctrl(f.key)?.errors?.['notMatching']) {\r\n <span>Las contrase\u00F1as no coinciden</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </section>\r\n }\r\n</form>\r\n}\r\n", styles: [".form{width:100%}.form{display:grid}.section{padding:20px 0 0}.section-title{font-size:1.6rem;font-weight:700;margin-bottom:30px}.section-desc{margin:0 0 .75rem;color:#666}.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:16px}.col{grid-column:span var(--col-span, 6);min-width:0;width:100%;position:relative;padding-bottom:20px}.label{position:absolute;top:-8px;left:12px;font-size:1.2rem;color:#454733;background-color:var(--surface-container-high, #ebe8d6);padding:0 4px;font-weight:500;z-index:1}.input{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent}input[type=number]::-webkit-outer-spin-button,input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=date]::-webkit-calendar-picker-indicator{position:absolute;inset:0;width:auto;height:auto;color:transparent;background:transparent}.input:focus{outline:none;border-color:#a9a97f}.input--disabled{color:#888}.label-radio{font-size:1.4rem;position:static;padding-left:0}.radio-group{display:flex;gap:1rem;padding:.5rem 0}.radio{font-size:1.4rem;display:flex;align-items:center;gap:10px;color:#1c1c12;margin-top:20px}.error{position:absolute;bottom:0;left:0;font-size:1.2rem;color:#b00020;width:100%;height:15px;display:none}.col:has(.error) .error{display:block}.textarea{resize:vertical;min-height:100px;max-height:300px;line-height:1.5}select{appearance:none;-webkit-appearance:none;-moz-appearance:none;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:right 15px center;cursor:pointer}select:invalid{color:#787861}select.placeholder-selected{color:#787861}select:not(.placeholder-selected){color:#000}select option{color:#454733;cursor:pointer}input[type=date]{color:#787861!important}input[type=date]:valid{color:#454733!important}.label-disabled{color:#1c1c1266}.input:disabled,.input--disabled,.input.disabled,.input[readonly]{border:1px solid #a9a97f;color:#a9a97f;cursor:not-allowed;pointer-events:none}@media (max-width: 768px){.grid{grid-template-columns:1fr}.col{grid-column:span 1!important}}\n"] }]
|
|
1849
1881
|
}], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }], sections: [{ type: i0.Input, args: [{ isSignal: true, alias: "sections", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }] } });
|
|
1850
1882
|
|
|
1851
1883
|
class WizardForm {
|
|
@@ -1883,10 +1915,10 @@ class WizardForm {
|
|
|
1883
1915
|
const index = this.currentStep() - 1;
|
|
1884
1916
|
return this.steps()[index].component;
|
|
1885
1917
|
}, ...(ngDevMode ? [{ debugName: "currentGroupComponent" }] : []));
|
|
1886
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1887
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1918
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WizardForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1919
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: WizardForm, isStandalone: true, selector: "lib-wizard-form", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, currentStep: { classPropertyName: "currentStep", publicName: "currentStep", isSignal: true, isRequired: false, transformFunction: null }, steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { canContinue: "canContinue" }, ngImport: i0, template: "<ng-container>\r\n\r\n @if (currentGroup()) {\r\n <ng-container\r\n *ngComponentOutlet=\"currentGroupComponent(); inputs: { group: currentGroup() }\"\r\n ></ng-container>\r\n }\r\n\r\n</ng-container>\r\n", styles: [".actions{display:flex;gap:10px;justify-content:flex-end;position:fixed;bottom:50px;right:50px;z-index:9999}.btn,.btn--ghost{width:100px;font-size:1.4rem;border:0;border-radius:40px;padding:15px;background-color:#596300;color:#fff;cursor:pointer;margin:0;transition:background-color .3s ease}.btn--ghost{background-color:#dee58f;color:#61661f}.btn:hover{background-color:#6b7400}.btn--ghost:hover{background-color:#c9d171}@media (max-width: 768px){.actions{bottom:10px;right:10px}.btn,.btn--ghost{font-size:1.2rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] });
|
|
1888
1920
|
}
|
|
1889
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1921
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: WizardForm, decorators: [{
|
|
1890
1922
|
type: Component,
|
|
1891
1923
|
args: [{ selector: 'lib-wizard-form', standalone: true, imports: [CommonModule], template: "<ng-container>\r\n\r\n @if (currentGroup()) {\r\n <ng-container\r\n *ngComponentOutlet=\"currentGroupComponent(); inputs: { group: currentGroup() }\"\r\n ></ng-container>\r\n }\r\n\r\n</ng-container>\r\n", styles: [".actions{display:flex;gap:10px;justify-content:flex-end;position:fixed;bottom:50px;right:50px;z-index:9999}.btn,.btn--ghost{width:100px;font-size:1.4rem;border:0;border-radius:40px;padding:15px;background-color:#596300;color:#fff;cursor:pointer;margin:0;transition:background-color .3s ease}.btn--ghost{background-color:#dee58f;color:#61661f}.btn:hover{background-color:#6b7400}.btn--ghost:hover{background-color:#c9d171}@media (max-width: 768px){.actions{bottom:10px;right:10px}.btn,.btn--ghost{font-size:1.2rem}}\n"] }]
|
|
1892
1924
|
}], ctorParameters: () => [], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], currentStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentStep", required: false }] }], steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: false }] }], canContinue: [{ type: i0.Output, args: ["canContinue"] }] } });
|
|
@@ -1923,12 +1955,12 @@ class ModalForm {
|
|
|
1923
1955
|
submitForm() {
|
|
1924
1956
|
this.onSubmit.emit(this.form()?.value);
|
|
1925
1957
|
}
|
|
1926
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1927
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1958
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModalForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1959
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ModalForm, isStandalone: true, selector: "lib-modal-form", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, submitLabel: { classPropertyName: "submitLabel", publicName: "submitLabel", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSubmit: "onSubmit", onCancel: "onCancel" }, ngImport: i0, template: "<div class=\"modal-form-container\">\r\n <div class=\"header-content\">\r\n <h1>{{ title() }}</h1>\r\n </div>\r\n\r\n @if (steps() && steps().length > 1) {\r\n <div class=\"steps\">\r\n @for (step of steps(); track $index) {\r\n <div\r\n class=\"step\"\r\n [class.step-active]=\"currentStep() === $index + 1\"\r\n [class.step-completed]=\"currentStep() > $index + 1\"\r\n >\r\n @if (currentStep() > $index + 1) {\r\n <span class=\"check-icon\">\u2714</span>\r\n }\r\n <span>Paso {{ $index + 1 }}: {{ step.label }}</span>\r\n </div>\r\n\r\n @if ($index < steps().length - 1) {\r\n <span class=\"separator\">\u203A</span>\r\n } }\r\n </div>\r\n }\r\n\r\n <div class=\"divider\"></div>\r\n\r\n <div class=\"body-content\">\r\n @if (!steps() || !steps().length) {\r\n <ng-content></ng-content>\r\n } @else {\r\n <!-- Render din\u00E1mico del paso actual -->\r\n <lib-wizard-form\r\n [form]=\"form()\"\r\n [currentStep]=\"currentStep()\"\r\n [steps]=\"steps()\"\r\n (canContinue)=\"canContinue.set($event)\"\r\n ></lib-wizard-form>\r\n }\r\n </div>\r\n\r\n <div class=\"actions\">\r\n @if (!steps() || steps().length <= 1) {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"onCancel.emit()\">\r\n Cancelar\r\n </button>\r\n } @else if (currentStep() === 1) {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"onCancel.emit()\">\r\n Cancelar\r\n </button>\r\n } @else {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"prevStep()\">\r\n Volver\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"btn\"\r\n (click)=\"!steps() || !steps().length ? submitForm() :\r\n currentStep() === steps().length ? submitForm() : nextStep()\"\r\n [disabled]=\"!canContinue()\"\r\n >\r\n {{ !steps() || !steps().length ? submitLabel() : currentStep() ===\r\n steps().length ? submitLabel() : 'Continuar' }}\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [":host{position:fixed;inset:0;background:#0006;display:flex;justify-content:center;align-items:center;z-index:9999;padding:16px;box-sizing:border-box}.modal-form-container{background-color:#ebe8d6;width:100%;max-width:1200px;max-height:80dvh;display:flex;flex-direction:column;align-items:stretch;padding:24px 48px;border-radius:24px;box-shadow:0 10px 25px #00000026}.header-content{padding-top:16px;padding-bottom:16px}.body-content{flex:1;overflow-y:auto;padding-right:6px}.body-content::-webkit-scrollbar{width:6px;background:transparent}.body-content::-webkit-scrollbar-track{background:transparent}.body-content::-webkit-scrollbar-thumb{background:#00000059;border-radius:6px}.body-content::-webkit-scrollbar-thumb:hover{background:#00000080}.steps{display:flex;flex-direction:row;gap:16px;justify-content:flex-start;align-items:center}.step{padding:12px;font-size:1.4rem;font-weight:600;text-align:center;border-radius:8px;height:32px;display:flex;align-items:center;justify-content:center;color:#40484c;border:1px solid #c7c7ad;box-shadow:none;transition:box-shadow .3s ease,background-color .3s ease,border-color .3s ease;position:relative}.separator{font-size:1.6rem;color:#61661f}.step-active{box-shadow:0 2px 4px #0003;background-color:#f5f5e0;border-color:#a3a375;border:none}.step-completed{box-shadow:none;background-color:#dee58f;border:none;color:#61661f;justify-content:center;gap:8px}.check-icon{align-content:center;justify-content:center;color:#61661f}.divider{width:calc(100% + 100px);margin-left:-52px;height:1px;background-color:#7878612c;margin-top:24px;margin-bottom:16px}.actions{display:flex;gap:10px;justify-content:flex-end;width:100%;margin-top:24px}.btn,.btn--ghost{font-size:1.4rem;border:0;border-radius:40px;padding:15px 24px;background-color:#596300;color:#fff;cursor:pointer;margin:0;transition:background-color .3s ease}.btn--ghost{background-color:#dee58f;color:#61661f}.btn:hover{background-color:#6b7400}.btn:disabled{background-color:#0000001a;color:#00000043;cursor:default}.btn--ghost:hover{background-color:#c9d171}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WizardForm, selector: "lib-wizard-form", inputs: ["form", "currentStep", "steps"], outputs: ["canContinue"] }] });
|
|
1928
1960
|
}
|
|
1929
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1961
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModalForm, decorators: [{
|
|
1930
1962
|
type: Component,
|
|
1931
|
-
args: [{ selector: 'lib-modal-form', standalone: true, imports: [CommonModule, WizardForm], template: "<div class=\"modal-form-container\">\r\n <div class=\"header-content\">\r\n <h1>{{ title() }}</h1>\r\n </div>\r\n\r\n @if (steps() && steps().length > 1) {\r\n <div class=\"steps\">\r\n @for (step of steps(); track $index) {\r\n <div\r\n class=\"step\"\r\n [class.step-active]=\"currentStep() === $index + 1\"\r\n [class.step-completed]=\"currentStep() > $index + 1\"\r\n >\r\n @if (currentStep() > $index + 1) {\r\n <span class=\"check-icon\">\u2714</span>\r\n }\r\n <span>Paso {{ $index + 1 }}: {{ step.label }}</span>\r\n </div>\r\n\r\n @if ($index < steps().length - 1) {\r\n <span class=\"separator\">\u203A</span>\r\n } }\r\n </div>\r\n }\r\n\r\n <div class=\"divider\"></div>\r\n\r\n <div class=\"body-content\">\r\n @if (!steps() || !steps().length) {\r\n <ng-content></ng-content>\r\n } @else {\r\n <!-- Render din\u00E1mico del paso actual -->\r\n <lib-wizard-form\r\n [form]=\"form()\"\r\n [currentStep]=\"currentStep()\"\r\n [steps]=\"steps()\"\r\n (canContinue)=\"canContinue.set($event)\"\r\n ></lib-wizard-form>\r\n }\r\n </div>\r\n\r\n <div class=\"actions\">\r\n @if (!steps() || steps().length <= 1) {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"onCancel.emit()\">\r\n Cancelar\r\n </button>\r\n } @else if (currentStep() === 1) {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"onCancel.emit()\">\r\n Cancelar\r\n </button>\r\n } @else {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"prevStep()\">\r\n Volver\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"btn\"\r\n (click)=\"!steps() || !steps().length ? submitForm() :\r\n currentStep() === steps().length ? submitForm() : nextStep()\"\r\n [disabled]=\"!canContinue()\"\r\n >\r\n {{ !steps() || !steps().length ? submitLabel() : currentStep() ===\r\n steps().length ? submitLabel() : 'Continuar' }}\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [":host{position:fixed;inset:0;background:#0006;display:flex;justify-content:center;align-items:center;z-index:9999;padding:16px;box-sizing:border-box}.modal-form-container{background-color:#ebe8d6;width:100%;max-width:1200px;max-height:
|
|
1963
|
+
args: [{ selector: 'lib-modal-form', standalone: true, imports: [CommonModule, WizardForm], template: "<div class=\"modal-form-container\">\r\n <div class=\"header-content\">\r\n <h1>{{ title() }}</h1>\r\n </div>\r\n\r\n @if (steps() && steps().length > 1) {\r\n <div class=\"steps\">\r\n @for (step of steps(); track $index) {\r\n <div\r\n class=\"step\"\r\n [class.step-active]=\"currentStep() === $index + 1\"\r\n [class.step-completed]=\"currentStep() > $index + 1\"\r\n >\r\n @if (currentStep() > $index + 1) {\r\n <span class=\"check-icon\">\u2714</span>\r\n }\r\n <span>Paso {{ $index + 1 }}: {{ step.label }}</span>\r\n </div>\r\n\r\n @if ($index < steps().length - 1) {\r\n <span class=\"separator\">\u203A</span>\r\n } }\r\n </div>\r\n }\r\n\r\n <div class=\"divider\"></div>\r\n\r\n <div class=\"body-content\">\r\n @if (!steps() || !steps().length) {\r\n <ng-content></ng-content>\r\n } @else {\r\n <!-- Render din\u00E1mico del paso actual -->\r\n <lib-wizard-form\r\n [form]=\"form()\"\r\n [currentStep]=\"currentStep()\"\r\n [steps]=\"steps()\"\r\n (canContinue)=\"canContinue.set($event)\"\r\n ></lib-wizard-form>\r\n }\r\n </div>\r\n\r\n <div class=\"actions\">\r\n @if (!steps() || steps().length <= 1) {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"onCancel.emit()\">\r\n Cancelar\r\n </button>\r\n } @else if (currentStep() === 1) {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"onCancel.emit()\">\r\n Cancelar\r\n </button>\r\n } @else {\r\n <button type=\"button\" class=\"btn--ghost\" (click)=\"prevStep()\">\r\n Volver\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"btn\"\r\n (click)=\"!steps() || !steps().length ? submitForm() :\r\n currentStep() === steps().length ? submitForm() : nextStep()\"\r\n [disabled]=\"!canContinue()\"\r\n >\r\n {{ !steps() || !steps().length ? submitLabel() : currentStep() ===\r\n steps().length ? submitLabel() : 'Continuar' }}\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [":host{position:fixed;inset:0;background:#0006;display:flex;justify-content:center;align-items:center;z-index:9999;padding:16px;box-sizing:border-box}.modal-form-container{background-color:#ebe8d6;width:100%;max-width:1200px;max-height:80dvh;display:flex;flex-direction:column;align-items:stretch;padding:24px 48px;border-radius:24px;box-shadow:0 10px 25px #00000026}.header-content{padding-top:16px;padding-bottom:16px}.body-content{flex:1;overflow-y:auto;padding-right:6px}.body-content::-webkit-scrollbar{width:6px;background:transparent}.body-content::-webkit-scrollbar-track{background:transparent}.body-content::-webkit-scrollbar-thumb{background:#00000059;border-radius:6px}.body-content::-webkit-scrollbar-thumb:hover{background:#00000080}.steps{display:flex;flex-direction:row;gap:16px;justify-content:flex-start;align-items:center}.step{padding:12px;font-size:1.4rem;font-weight:600;text-align:center;border-radius:8px;height:32px;display:flex;align-items:center;justify-content:center;color:#40484c;border:1px solid #c7c7ad;box-shadow:none;transition:box-shadow .3s ease,background-color .3s ease,border-color .3s ease;position:relative}.separator{font-size:1.6rem;color:#61661f}.step-active{box-shadow:0 2px 4px #0003;background-color:#f5f5e0;border-color:#a3a375;border:none}.step-completed{box-shadow:none;background-color:#dee58f;border:none;color:#61661f;justify-content:center;gap:8px}.check-icon{align-content:center;justify-content:center;color:#61661f}.divider{width:calc(100% + 100px);margin-left:-52px;height:1px;background-color:#7878612c;margin-top:24px;margin-bottom:16px}.actions{display:flex;gap:10px;justify-content:flex-end;width:100%;margin-top:24px}.btn,.btn--ghost{font-size:1.4rem;border:0;border-radius:40px;padding:15px 24px;background-color:#596300;color:#fff;cursor:pointer;margin:0;transition:background-color .3s ease}.btn--ghost{background-color:#dee58f;color:#61661f}.btn:hover{background-color:#6b7400}.btn:disabled{background-color:#0000001a;color:#00000043;cursor:default}.btn--ghost:hover{background-color:#c9d171}\n"] }]
|
|
1932
1964
|
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], submitLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitLabel", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: false }] }], onSubmit: [{ type: i0.Output, args: ["onSubmit"] }], onCancel: [{ type: i0.Output, args: ["onCancel"] }] } });
|
|
1933
1965
|
|
|
1934
1966
|
class DialogAlertComponent {
|
|
@@ -2012,30 +2044,30 @@ class DialogAlertComponent {
|
|
|
2012
2044
|
onCancel() {
|
|
2013
2045
|
this.close.emit(false);
|
|
2014
2046
|
}
|
|
2015
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2016
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
2047
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DialogAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2048
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DialogAlertComponent, isStandalone: true, selector: "lib-dialog-alert-component", inputs: { title: "title", message: "message", type: "type", action: "action", showReason: "showReason", confirm: "confirm", confirmLabel: "confirmLabel", reasonOptions: "reasonOptions" }, outputs: { close: "close", confirmReason: "confirmReason" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"modal-backdrop\">\r\n <div class=\"modal-card\" [class.modal-card-compact]=\"!isReasonNeeded\">\r\n <div class=\"modal-header\">\r\n <h2>{{ title }}</h2>\r\n </div>\r\n <div class=\"modal-body\">\r\n <p>{{ message }}</p>\r\n <lib-dynamic-form-fields [form]=\"form\" [sections]=\"sections\"></lib-dynamic-form-fields>\r\n </div>\r\n <div class=\"modal-footer\">\r\n @if (confirm) {\r\n <button class=\"btn cancel\" (click)=\"onCancel()\">Cancelar</button>\r\n <button class=\"btn confirm\" [ngClass]=\"type\" (click)=\"onConfirm()\">{{ confirmLabel }}</button>\r\n } @else {\r\n <button class=\"btn confirm\" [ngClass]=\"type\" (click)=\"onConfirm()\">{{ confirmLabel }}</button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".modal-backdrop{position:fixed;inset:0;background:#00000073;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10000}.modal-card{width:30%;max-width:50%;max-height:80dvh;background:#ebe8d6;border-radius:14px;padding:32px 48px;animation:fadeIn .25s ease;border:1px solid rgba(255,255,255,.07);box-shadow:0 8px 20px #0003;overflow:hidden;box-sizing:border-box}.modal-card-compact{width:100%;max-width:25%;padding:24px 32px}.modal-header{display:flex;align-items:center;gap:12px;color:#0c0c0c;justify-content:center}.modal-header h2{font-weight:700;font-size:24px;margin:0;text-transform:uppercase}.modal-body{text-align:center;max-height:400px;overflow:hidden;box-sizing:border-box}.modal-body p{color:#555;margin:0;font-size:14px;line-height:1.5;padding-top:21px}.modal-footer{margin-top:25px;display:flex;justify-content:center;gap:10px}.btn{padding:10px 16px;border-radius:99px;font-weight:700;cursor:pointer;border:none}.btn:hover{background-color:#61661f}.btn.cancel{background:transparent;border:1px solid #454733;color:#454733}.btn.cancel:hover{background-color:#454733;color:#fff}.btn.confirm{background:#596300;color:#fff}@keyframes fadeIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.btn.confirm.warning,.btn.confirm.error{background-color:#ba1a1a;color:#fff}.btn.confirm.info{background-color:#063546;color:#fff}.btn.confirm.success{background-color:#596300;color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: DynamicFormFields, selector: "lib-dynamic-form-fields", inputs: ["form", "sections", "compact"] }] });
|
|
2017
2049
|
}
|
|
2018
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2050
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DialogAlertComponent, decorators: [{
|
|
2019
2051
|
type: Component,
|
|
2020
|
-
args: [{ selector: 'lib-dialog-alert-component', standalone: true, imports: [CommonModule, ReactiveFormsModule, DynamicFormFields], template: "<div class=\"modal-backdrop\">\r\n <div class=\"modal-card\" [class.modal-card-compact]=\"!isReasonNeeded\">\r\n <div class=\"modal-header\">\r\n <h2>{{ title }}</h2>\r\n </div>\r\n <div class=\"modal-body\">\r\n <p>{{ message }}</p>\r\n <lib-dynamic-form-fields [form]=\"form\" [sections]=\"sections\"></lib-dynamic-form-fields>\r\n </div>\r\n <div class=\"modal-footer\">\r\n @if (confirm) {\r\n <button class=\"btn cancel\" (click)=\"onCancel()\">Cancelar</button>\r\n <button class=\"btn confirm\" [ngClass]=\"type\" (click)=\"onConfirm()\">{{ confirmLabel }}</button>\r\n } @else {\r\n <button class=\"btn confirm\" [ngClass]=\"type\" (click)=\"onConfirm()\">{{ confirmLabel }}</button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".modal-backdrop{position:fixed;inset:0;background:#00000073;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10000}.modal-card{width:30%;max-width:50%;background:#ebe8d6;border-radius:14px;padding:32px 48px;animation:fadeIn .25s ease;border:1px solid rgba(255,255,255,.07);box-shadow:0 8px 20px #0003}.modal-card-compact{width:100%;max-width:25%;padding:24px 32px}.modal-header{display:flex;align-items:center;gap:12px;color:#0c0c0c;justify-content:center}.modal-header h2{font-weight:700;font-size:24px;margin:0;text-transform:uppercase}.modal-body{text-align:center}.modal-body p{color:#555;margin:0;font-size:14px;line-height:1.5;padding-top:21px}.modal-footer{margin-top:25px;display:flex;justify-content:center;gap:10px}.btn{padding:10px 16px;border-radius:99px;font-weight:700;cursor:pointer;border:none}.btn:hover{background-color:#61661f}.btn.cancel{background:transparent;border:1px solid #454733;color:#454733}.btn.cancel:hover{background-color:#454733;color:#fff}.btn.confirm{background:#596300;color:#fff}@keyframes fadeIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.btn.confirm.warning,.btn.confirm.error{background-color:#ba1a1a;color:#fff}.btn.confirm.info{background-color:#063546;color:#fff}.btn.confirm.success{background-color:#596300;color:#fff}\n"] }]
|
|
2052
|
+
args: [{ selector: 'lib-dialog-alert-component', standalone: true, imports: [CommonModule, ReactiveFormsModule, DynamicFormFields], template: "<div class=\"modal-backdrop\">\r\n <div class=\"modal-card\" [class.modal-card-compact]=\"!isReasonNeeded\">\r\n <div class=\"modal-header\">\r\n <h2>{{ title }}</h2>\r\n </div>\r\n <div class=\"modal-body\">\r\n <p>{{ message }}</p>\r\n <lib-dynamic-form-fields [form]=\"form\" [sections]=\"sections\"></lib-dynamic-form-fields>\r\n </div>\r\n <div class=\"modal-footer\">\r\n @if (confirm) {\r\n <button class=\"btn cancel\" (click)=\"onCancel()\">Cancelar</button>\r\n <button class=\"btn confirm\" [ngClass]=\"type\" (click)=\"onConfirm()\">{{ confirmLabel }}</button>\r\n } @else {\r\n <button class=\"btn confirm\" [ngClass]=\"type\" (click)=\"onConfirm()\">{{ confirmLabel }}</button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".modal-backdrop{position:fixed;inset:0;background:#00000073;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10000}.modal-card{width:30%;max-width:50%;max-height:80dvh;background:#ebe8d6;border-radius:14px;padding:32px 48px;animation:fadeIn .25s ease;border:1px solid rgba(255,255,255,.07);box-shadow:0 8px 20px #0003;overflow:hidden;box-sizing:border-box}.modal-card-compact{width:100%;max-width:25%;padding:24px 32px}.modal-header{display:flex;align-items:center;gap:12px;color:#0c0c0c;justify-content:center}.modal-header h2{font-weight:700;font-size:24px;margin:0;text-transform:uppercase}.modal-body{text-align:center;max-height:400px;overflow:hidden;box-sizing:border-box}.modal-body p{color:#555;margin:0;font-size:14px;line-height:1.5;padding-top:21px}.modal-footer{margin-top:25px;display:flex;justify-content:center;gap:10px}.btn{padding:10px 16px;border-radius:99px;font-weight:700;cursor:pointer;border:none}.btn:hover{background-color:#61661f}.btn.cancel{background:transparent;border:1px solid #454733;color:#454733}.btn.cancel:hover{background-color:#454733;color:#fff}.btn.confirm{background:#596300;color:#fff}@keyframes fadeIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.btn.confirm.warning,.btn.confirm.error{background-color:#ba1a1a;color:#fff}.btn.confirm.info{background-color:#063546;color:#fff}.btn.confirm.success{background-color:#596300;color:#fff}\n"] }]
|
|
2021
2053
|
}], propDecorators: { title: [{
|
|
2022
|
-
type: Input
|
|
2054
|
+
type: Input$1
|
|
2023
2055
|
}], message: [{
|
|
2024
|
-
type: Input
|
|
2056
|
+
type: Input$1
|
|
2025
2057
|
}], type: [{
|
|
2026
|
-
type: Input
|
|
2058
|
+
type: Input$1
|
|
2027
2059
|
}], action: [{
|
|
2028
|
-
type: Input
|
|
2060
|
+
type: Input$1
|
|
2029
2061
|
}], showReason: [{
|
|
2030
|
-
type: Input
|
|
2062
|
+
type: Input$1
|
|
2031
2063
|
}], confirm: [{
|
|
2032
|
-
type: Input
|
|
2064
|
+
type: Input$1
|
|
2033
2065
|
}], confirmLabel: [{
|
|
2034
|
-
type: Input
|
|
2066
|
+
type: Input$1
|
|
2035
2067
|
}], close: [{
|
|
2036
2068
|
type: Output
|
|
2037
2069
|
}], reasonOptions: [{
|
|
2038
|
-
type: Input
|
|
2070
|
+
type: Input$1
|
|
2039
2071
|
}], confirmReason: [{
|
|
2040
2072
|
type: Output
|
|
2041
2073
|
}] } });
|
|
@@ -2057,24 +2089,195 @@ class DialogConfirmation {
|
|
|
2057
2089
|
onCancel() {
|
|
2058
2090
|
this.close.emit(false);
|
|
2059
2091
|
}
|
|
2060
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2061
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
2092
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DialogConfirmation, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2093
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DialogConfirmation, isStandalone: true, selector: "lib-dialog-confirmation", inputs: { title: "title", confirm: "confirm", confirmLabel: "confirmLabel", items: "items" }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"modal-backdrop\">\r\n <div class=\"modal-card\">\r\n <div class=\"modal-header\">\r\n <h2>{{ title }}</h2>\r\n <button class=\"close-btn\" (click)=\"onCancel()\" aria-label=\"Cerrar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6l-12 12\" />\r\n <path d=\"M6 6l12 12\" />\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"info-container\" [class.expanded]=\"expandedIndex !== null\">\r\n @for (item of items; track item.key; let i = $index) {\r\n\r\n <div class=\"info-item\">\r\n <div\r\n class=\"info-main\"\r\n [class.info-main-expanded]=\"item.expandible\"\r\n (click)=\"item.expandible && toggle(i)\"\r\n >\r\n <span class=\"label\"\r\n >{{ item.label }} @if (item.expandible) {\r\n <span class=\"arrow\"> {{ expandedIndex === i ? '\u25B2' : '\u25BC' }} </span>\r\n }\r\n </span>\r\n <span class=\"value\"> {{ item.value }} </span>\r\n </div>\r\n\r\n @if (expandedIndex === i && item.children?.length) {\r\n <div class=\"info-children\">\r\n @for (child of item.children; track child.key) {\r\n <div class=\"info-item child-item\">\r\n <div class=\"info-main\">\r\n <span class=\"label\">{{ child.label }}</span>\r\n <span class=\"value\">{{ child.value }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n }\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n @if (confirm) {\r\n <button class=\"btn cancel\" (click)=\"onCancel()\">Cancelar</button>\r\n <button class=\"btn confirm\" (click)=\"onConfirm()\">\r\n {{ confirmLabel }}\r\n </button>\r\n } @else {\r\n <button class=\"btn confirm\" (click)=\"onConfirm()\">\r\n {{ confirmLabel }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".modal-backdrop{position:fixed;inset:0;background:#00000073;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10000}.modal-card{width:35%;max-width:50%;max-height:90%;background:#ebe8d6;border-radius:28px;padding:32px 48px;animation:fadeIn .25s ease;border:1px solid rgba(255,255,255,.07);box-shadow:0 8px 20px #0003;overflow:hidden;display:flex;flex-direction:column;transition:max-height .35s cubic-bezier(.4,0,.2,1)}.modal-header{position:relative;display:flex;align-items:center;gap:12px;color:#0c0c0c;justify-content:center}.modal-header h2{font-weight:700;font-size:24px;margin:0;text-transform:uppercase}.close-btn{position:absolute;right:-36px;top:-24px;width:36px;height:36px;border-radius:50%;background:#ebe8d6;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#333;transition:background .2s ease,transform .2s ease}.close-btn:hover{background:#d8d6c0;transform:scale(1.05)}.close-btn svg{width:18px;height:18px}.modal-body{position:relative;margin-top:16px;text-align:center;flex:1;overflow:hidden;display:flex;flex-direction:column;transition:all .35s cubic-bezier(.4,0,.2,1)}.modal-body p{color:#555;margin:0;font-size:14px;line-height:1.5;padding-top:21px}.modal-footer{margin-top:25px;display:flex;justify-content:center;gap:10px;flex-shrink:0}button{background-color:transparent;border:none}.btn{padding:10px 16px;border-radius:99px;font-weight:700;cursor:pointer;border:none}.btn:hover{background-color:#61661f}.btn.cancel{background:transparent;border:1px solid #454733;color:#454733}.btn.cancel:hover{background-color:#454733;color:#fff}.btn.confirm{background:#596300;color:#fff}@keyframes fadeIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.btn.confirm.warning,.btn.confirm.error{background-color:#ba1a1a;color:#fff}.btn.confirm.info{background-color:#063546;color:#fff}.btn.confirm.success{background-color:#596300;color:#fff}.info-container{max-height:400;background:#e3e3d1;border-radius:20px;padding:24px;flex:1;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.35) transparent;transition:max-height .35s cubic-bezier(.4,0,.2,1)}.info-container.expanded{max-height:600px}.info-container::-webkit-scrollbar{width:6px;background:transparent}.info-container::-webkit-scrollbar-track{background:transparent}.info-container::-webkit-scrollbar-thumb{background:#00000059;border-radius:6px}.info-container::-webkit-scrollbar-thumb:hover{background:#00000080}.info-item{border-bottom:1px solid rgba(0,0,0,.05);padding:16px 0}.info-item:last-child{border-bottom:none}.info-main{display:flex;flex-direction:column;text-align:center}.info-main-expanded{cursor:pointer}.info-children{margin-top:12px}.child-item{padding:16px 0;border-bottom:1px solid rgba(0,0,0,.05);margin:0 16px}.child-item:first-child{border-top:1px solid rgba(0,0,0,.05)}.child-item:last-child{border-bottom:none}.label{font-size:16px;color:#555;text-transform:uppercase}.value{font-size:16px;font-weight:700;display:flex;justify-content:center;gap:6px;align-items:center}.arrow{font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
2062
2094
|
}
|
|
2063
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2095
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DialogConfirmation, decorators: [{
|
|
2064
2096
|
type: Component,
|
|
2065
|
-
args: [{ selector: 'lib-dialog-confirmation', imports: [CommonModule], template: "<div class=\"modal-backdrop\">\r\n <div class=\"modal-card\">\r\n <div class=\"modal-header\">\r\n <h2>{{ title }}</h2>\r\n <button class=\"close-btn\" (click)=\"onCancel()\" aria-label=\"Cerrar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6l-12 12\" />\r\n <path d=\"M6 6l12 12\" />\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"info-container\" [class.expanded]=\"expandedIndex !== null\">\r\n @for (item of items; track item.key; let i = $index) {\r\n\r\n <div class=\"info-item\">\r\n <div\r\n class=\"info-main\"\r\n [class.info-main-expanded]=\"item.expandible\"\r\n (click)=\"item.expandible && toggle(i)\"\r\n >\r\n <span class=\"label\"\r\n >{{ item.label }} @if (item.expandible) {\r\n <span class=\"arrow\"> {{ expandedIndex === i ? '\u25B2' : '\u25BC' }} </span>\r\n }\r\n </span>\r\n <span class=\"value\"> {{ item.value }} </span>\r\n </div>\r\n\r\n @if (expandedIndex === i && item.children?.length) {\r\n <div class=\"info-children\">\r\n @for (child of item.children; track child.key) {\r\n <div class=\"info-item child-item\">\r\n <div class=\"info-main\">\r\n <span class=\"label\">{{ child.label }}</span>\r\n <span class=\"value\">{{ child.value }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n }\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n @if (confirm) {\r\n <button class=\"btn cancel\" (click)=\"onCancel()\">Cancelar</button>\r\n <button class=\"btn confirm\" (click)=\"onConfirm()\">\r\n {{ confirmLabel }}\r\n </button>\r\n } @else {\r\n <button class=\"btn confirm\" (click)=\"onConfirm()\">\r\n {{ confirmLabel }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".modal-backdrop{position:fixed;inset:0;background:#00000073;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10000}.modal-card{width:
|
|
2097
|
+
args: [{ selector: 'lib-dialog-confirmation', imports: [CommonModule], template: "<div class=\"modal-backdrop\">\r\n <div class=\"modal-card\">\r\n <div class=\"modal-header\">\r\n <h2>{{ title }}</h2>\r\n <button class=\"close-btn\" (click)=\"onCancel()\" aria-label=\"Cerrar\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M18 6l-12 12\" />\r\n <path d=\"M6 6l12 12\" />\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"info-container\" [class.expanded]=\"expandedIndex !== null\">\r\n @for (item of items; track item.key; let i = $index) {\r\n\r\n <div class=\"info-item\">\r\n <div\r\n class=\"info-main\"\r\n [class.info-main-expanded]=\"item.expandible\"\r\n (click)=\"item.expandible && toggle(i)\"\r\n >\r\n <span class=\"label\"\r\n >{{ item.label }} @if (item.expandible) {\r\n <span class=\"arrow\"> {{ expandedIndex === i ? '\u25B2' : '\u25BC' }} </span>\r\n }\r\n </span>\r\n <span class=\"value\"> {{ item.value }} </span>\r\n </div>\r\n\r\n @if (expandedIndex === i && item.children?.length) {\r\n <div class=\"info-children\">\r\n @for (child of item.children; track child.key) {\r\n <div class=\"info-item child-item\">\r\n <div class=\"info-main\">\r\n <span class=\"label\">{{ child.label }}</span>\r\n <span class=\"value\">{{ child.value }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n }\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n @if (confirm) {\r\n <button class=\"btn cancel\" (click)=\"onCancel()\">Cancelar</button>\r\n <button class=\"btn confirm\" (click)=\"onConfirm()\">\r\n {{ confirmLabel }}\r\n </button>\r\n } @else {\r\n <button class=\"btn confirm\" (click)=\"onConfirm()\">\r\n {{ confirmLabel }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".modal-backdrop{position:fixed;inset:0;background:#00000073;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10000}.modal-card{width:35%;max-width:50%;max-height:90%;background:#ebe8d6;border-radius:28px;padding:32px 48px;animation:fadeIn .25s ease;border:1px solid rgba(255,255,255,.07);box-shadow:0 8px 20px #0003;overflow:hidden;display:flex;flex-direction:column;transition:max-height .35s cubic-bezier(.4,0,.2,1)}.modal-header{position:relative;display:flex;align-items:center;gap:12px;color:#0c0c0c;justify-content:center}.modal-header h2{font-weight:700;font-size:24px;margin:0;text-transform:uppercase}.close-btn{position:absolute;right:-36px;top:-24px;width:36px;height:36px;border-radius:50%;background:#ebe8d6;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#333;transition:background .2s ease,transform .2s ease}.close-btn:hover{background:#d8d6c0;transform:scale(1.05)}.close-btn svg{width:18px;height:18px}.modal-body{position:relative;margin-top:16px;text-align:center;flex:1;overflow:hidden;display:flex;flex-direction:column;transition:all .35s cubic-bezier(.4,0,.2,1)}.modal-body p{color:#555;margin:0;font-size:14px;line-height:1.5;padding-top:21px}.modal-footer{margin-top:25px;display:flex;justify-content:center;gap:10px;flex-shrink:0}button{background-color:transparent;border:none}.btn{padding:10px 16px;border-radius:99px;font-weight:700;cursor:pointer;border:none}.btn:hover{background-color:#61661f}.btn.cancel{background:transparent;border:1px solid #454733;color:#454733}.btn.cancel:hover{background-color:#454733;color:#fff}.btn.confirm{background:#596300;color:#fff}@keyframes fadeIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.btn.confirm.warning,.btn.confirm.error{background-color:#ba1a1a;color:#fff}.btn.confirm.info{background-color:#063546;color:#fff}.btn.confirm.success{background-color:#596300;color:#fff}.info-container{max-height:400;background:#e3e3d1;border-radius:20px;padding:24px;flex:1;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.35) transparent;transition:max-height .35s cubic-bezier(.4,0,.2,1)}.info-container.expanded{max-height:600px}.info-container::-webkit-scrollbar{width:6px;background:transparent}.info-container::-webkit-scrollbar-track{background:transparent}.info-container::-webkit-scrollbar-thumb{background:#00000059;border-radius:6px}.info-container::-webkit-scrollbar-thumb:hover{background:#00000080}.info-item{border-bottom:1px solid rgba(0,0,0,.05);padding:16px 0}.info-item:last-child{border-bottom:none}.info-main{display:flex;flex-direction:column;text-align:center}.info-main-expanded{cursor:pointer}.info-children{margin-top:12px}.child-item{padding:16px 0;border-bottom:1px solid rgba(0,0,0,.05);margin:0 16px}.child-item:first-child{border-top:1px solid rgba(0,0,0,.05)}.child-item:last-child{border-bottom:none}.label{font-size:16px;color:#555;text-transform:uppercase}.value{font-size:16px;font-weight:700;display:flex;justify-content:center;gap:6px;align-items:center}.arrow{font-size:12px}\n"] }]
|
|
2066
2098
|
}], propDecorators: { title: [{
|
|
2067
|
-
type: Input
|
|
2099
|
+
type: Input$1
|
|
2068
2100
|
}], confirm: [{
|
|
2069
|
-
type: Input
|
|
2101
|
+
type: Input$1
|
|
2070
2102
|
}], confirmLabel: [{
|
|
2071
|
-
type: Input
|
|
2103
|
+
type: Input$1
|
|
2072
2104
|
}], items: [{
|
|
2073
|
-
type: Input
|
|
2105
|
+
type: Input$1
|
|
2074
2106
|
}], close: [{
|
|
2075
2107
|
type: Output
|
|
2076
2108
|
}] } });
|
|
2077
2109
|
|
|
2110
|
+
const TOAST_EVENTS = {
|
|
2111
|
+
SHOW_TOAST: 'SHOW_TOAST',
|
|
2112
|
+
SHOW_TOAST_WITH_ACTION: 'SHOW_TOAST_WITH_ACTION',
|
|
2113
|
+
HIDE_TOAST: 'HIDE_TOAST',
|
|
2114
|
+
};
|
|
2115
|
+
class ToastHelper {
|
|
2116
|
+
static show(description, duration) {
|
|
2117
|
+
PubSub.publish(TOAST_EVENTS.SHOW_TOAST, {
|
|
2118
|
+
description,
|
|
2119
|
+
duration,
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
2122
|
+
static showWithAction(description, buttonText, action, duration) {
|
|
2123
|
+
PubSub.publish(TOAST_EVENTS.SHOW_TOAST_WITH_ACTION, {
|
|
2124
|
+
description,
|
|
2125
|
+
buttonText,
|
|
2126
|
+
action,
|
|
2127
|
+
duration,
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
static success(message, duration) {
|
|
2131
|
+
this.show(`${message}`, duration);
|
|
2132
|
+
}
|
|
2133
|
+
static error(message, duration) {
|
|
2134
|
+
this.show(`${message}`, duration || 6000);
|
|
2135
|
+
}
|
|
2136
|
+
static warning(message, duration) {
|
|
2137
|
+
this.show(`${message}`, duration);
|
|
2138
|
+
}
|
|
2139
|
+
static info(message, duration) {
|
|
2140
|
+
this.show(`ℹ${message}`, duration);
|
|
2141
|
+
}
|
|
2142
|
+
static hide() {
|
|
2143
|
+
PubSub.publish(TOAST_EVENTS.HIDE_TOAST);
|
|
2144
|
+
}
|
|
2145
|
+
static showUndo(message, undoAction, duration = 8000) {
|
|
2146
|
+
this.showWithAction(message, 'Deshacer', undoAction, duration);
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
class NotFoundModal {
|
|
2151
|
+
isVisible = input(false, ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
|
|
2152
|
+
title = input('Documento no encontrado', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
2153
|
+
message = input('No encontrado', ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
2154
|
+
onClose = output();
|
|
2155
|
+
onOverlayClick(event) {
|
|
2156
|
+
if (event.target === event.currentTarget) {
|
|
2157
|
+
this.onClose.emit();
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
onAccept() {
|
|
2161
|
+
this.onClose.emit();
|
|
2162
|
+
}
|
|
2163
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotFoundModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2164
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: NotFoundModal, isStandalone: true, selector: "lib-not-found-modal", inputs: { isVisible: { classPropertyName: "isVisible", publicName: "isVisible", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose" }, ngImport: i0, template: "<div\r\n class=\"modal-overlay\"\r\n (click)=\"onOverlayClick($event)\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n>\r\n <div class=\"modal-content\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-header\">\r\n <div class=\"icon-container\">\r\n <svg\r\n width=\"48\"\r\n height=\"48\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"error-icon\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"#ef4444\" stroke-width=\"2\" />\r\n <path\r\n d=\"M15 9l-6 6\"\r\n stroke=\"#ef4444\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M9 9l6 6\"\r\n stroke=\"#ef4444\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n <h2 class=\"modal-title\">{{ title() }}</h2>\r\n </div>\r\n\r\n <div class=\"modal-body\">\r\n <p class=\"modal-message\">{{ message() }}</p>\r\n </div>\r\n\r\n <div class=\"modal-footer\">\r\n <button\r\n class=\"btn-primary\"\r\n (click)=\"onAccept()\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Cerrar modal de documento no encontrado'\"\r\n >\r\n Aceptar\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n", styles: [".modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#0006;display:flex;justify-content:center;align-items:center;z-index:10000;animation:fadeIn .3s ease-out;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.modal-content{background:#fff;border-radius:16px;box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a,0 0 0 1px #0000000d;max-width:500px;width:90%;max-height:90vh;overflow:auto;animation:slideIn .3s cubic-bezier(.34,1.56,.64,1);position:relative;padding:10px}.modal-header{padding:32px 32px 24px;text-align:center;border-bottom:1px solid #f3f4f6;position:relative}.icon-container{margin-bottom:16px;display:flex;justify-content:center}.icon-container svg{width:50px;height:50px}.error-icon{animation:shake .6s ease-in-out;filter:drop-shadow(0 2px 4px rgba(239,68,68,.1))}.modal-title{font-size:3.2rem;font-weight:600;color:#111827;margin:0}.modal-message{font-size:1.6rem;color:#111827;line-height:1.6;margin:0;text-align:center}.modal-footer{padding:24px 32px 32px;display:flex;justify-content:center;border-top:1px solid #f3f4f6}.btn-primary{padding:14px;border-radius:8px;font-weight:600;font-size:1.4rem;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);border:none;font-family:system-ui,-apple-system,Segoe UI,sans-serif;min-width:120px;position:relative;overflow:hidden}.btn-primary{background-color:#3b82f6;color:#fff;box-shadow:0 1px 2px #0000000d}.btn-primary:hover{background-color:#2563eb;transform:translateY(-1px);box-shadow:0 4px 8px #3b82f64d}.btn-primary:active{transform:translateY(0);box-shadow:0 1px 2px #0000000d}.btn-primary:focus,.btn-secondary:focus{outline:2px solid #3b82f6;outline-offset:2px}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-3px)}20%,40%,60%,80%{transform:translate(3px)}}@media (max-width: 640px){.modal-content{width:95%;margin:20px;border-radius:12px}.modal-header,.modal-body,.modal-footer{padding-left:20px;padding-right:20px}.modal-header{padding-top:24px;padding-bottom:20px}.modal-body{padding-top:20px;padding-bottom:20px}.modal-footer{flex-direction:column-reverse;padding-top:20px;padding-bottom:24px}.btn-primary,.btn-secondary{width:100%;min-width:unset}.modal-title{font-size:20px}.modal-message{font-size:14px}}@media (max-width: 480px){.modal-content{width:100%;margin:10px;border-radius:8px}}\n"] });
|
|
2165
|
+
}
|
|
2166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotFoundModal, decorators: [{
|
|
2167
|
+
type: Component,
|
|
2168
|
+
args: [{ selector: 'lib-not-found-modal', standalone: true, imports: [], template: "<div\r\n class=\"modal-overlay\"\r\n (click)=\"onOverlayClick($event)\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n>\r\n <div class=\"modal-content\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"modal-header\">\r\n <div class=\"icon-container\">\r\n <svg\r\n width=\"48\"\r\n height=\"48\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"error-icon\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"#ef4444\" stroke-width=\"2\" />\r\n <path\r\n d=\"M15 9l-6 6\"\r\n stroke=\"#ef4444\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n <path\r\n d=\"M9 9l6 6\"\r\n stroke=\"#ef4444\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n <h2 class=\"modal-title\">{{ title() }}</h2>\r\n </div>\r\n\r\n <div class=\"modal-body\">\r\n <p class=\"modal-message\">{{ message() }}</p>\r\n </div>\r\n\r\n <div class=\"modal-footer\">\r\n <button\r\n class=\"btn-primary\"\r\n (click)=\"onAccept()\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Cerrar modal de documento no encontrado'\"\r\n >\r\n Aceptar\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n", styles: [".modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#0006;display:flex;justify-content:center;align-items:center;z-index:10000;animation:fadeIn .3s ease-out;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.modal-content{background:#fff;border-radius:16px;box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a,0 0 0 1px #0000000d;max-width:500px;width:90%;max-height:90vh;overflow:auto;animation:slideIn .3s cubic-bezier(.34,1.56,.64,1);position:relative;padding:10px}.modal-header{padding:32px 32px 24px;text-align:center;border-bottom:1px solid #f3f4f6;position:relative}.icon-container{margin-bottom:16px;display:flex;justify-content:center}.icon-container svg{width:50px;height:50px}.error-icon{animation:shake .6s ease-in-out;filter:drop-shadow(0 2px 4px rgba(239,68,68,.1))}.modal-title{font-size:3.2rem;font-weight:600;color:#111827;margin:0}.modal-message{font-size:1.6rem;color:#111827;line-height:1.6;margin:0;text-align:center}.modal-footer{padding:24px 32px 32px;display:flex;justify-content:center;border-top:1px solid #f3f4f6}.btn-primary{padding:14px;border-radius:8px;font-weight:600;font-size:1.4rem;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);border:none;font-family:system-ui,-apple-system,Segoe UI,sans-serif;min-width:120px;position:relative;overflow:hidden}.btn-primary{background-color:#3b82f6;color:#fff;box-shadow:0 1px 2px #0000000d}.btn-primary:hover{background-color:#2563eb;transform:translateY(-1px);box-shadow:0 4px 8px #3b82f64d}.btn-primary:active{transform:translateY(0);box-shadow:0 1px 2px #0000000d}.btn-primary:focus,.btn-secondary:focus{outline:2px solid #3b82f6;outline-offset:2px}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes shake{0%,to{transform:translate(0)}10%,30%,50%,70%,90%{transform:translate(-3px)}20%,40%,60%,80%{transform:translate(3px)}}@media (max-width: 640px){.modal-content{width:95%;margin:20px;border-radius:12px}.modal-header,.modal-body,.modal-footer{padding-left:20px;padding-right:20px}.modal-header{padding-top:24px;padding-bottom:20px}.modal-body{padding-top:20px;padding-bottom:20px}.modal-footer{flex-direction:column-reverse;padding-top:20px;padding-bottom:24px}.btn-primary,.btn-secondary{width:100%;min-width:unset}.modal-title{font-size:20px}.modal-message{font-size:14px}}@media (max-width: 480px){.modal-content{width:100%;margin:10px;border-radius:8px}}\n"] }]
|
|
2169
|
+
}], propDecorators: { isVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVisible", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], onClose: [{ type: i0.Output, args: ["onClose"] }] } });
|
|
2170
|
+
|
|
2171
|
+
class Loader {
|
|
2172
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Loader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2173
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: Loader, isStandalone: true, selector: "lib-loader", ngImport: i0, template: "<div class=\"loader-overlay\">\r\n <div class=\"loader\"></div>\r\n</div>\r\n", styles: [".loader-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0006;display:flex;align-items:center;justify-content:center;z-index:99999}.loader{width:40px;height:40px;--c: no-repeat linear-gradient(#596300 0 0);background:var(--c),var(--c),var(--c),var(--c);background-size:21px 21px;animation:l5 1.5s infinite cubic-bezier(.3,1,0,1)}@keyframes l5{0%{background-position:0 0,100% 0,100% 100%,0 100%}33%{background-position:0 0,100% 0,100% 100%,0 100%;width:60px;height:60px}66%{background-position:100% 0,100% 100%,0 100%,0 0;width:60px;height:60px}to{background-position:100% 0,100% 100%,0 100%,0 0}}\n"] });
|
|
2174
|
+
}
|
|
2175
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: Loader, decorators: [{
|
|
2176
|
+
type: Component,
|
|
2177
|
+
args: [{ selector: 'lib-loader', imports: [], template: "<div class=\"loader-overlay\">\r\n <div class=\"loader\"></div>\r\n</div>\r\n", styles: [".loader-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0006;display:flex;align-items:center;justify-content:center;z-index:99999}.loader{width:40px;height:40px;--c: no-repeat linear-gradient(#596300 0 0);background:var(--c),var(--c),var(--c),var(--c);background-size:21px 21px;animation:l5 1.5s infinite cubic-bezier(.3,1,0,1)}@keyframes l5{0%{background-position:0 0,100% 0,100% 100%,0 100%}33%{background-position:0 0,100% 0,100% 100%,0 100%;width:60px;height:60px}66%{background-position:100% 0,100% 100%,0 100%,0 0;width:60px;height:60px}to{background-position:100% 0,100% 100%,0 100%,0 0}}\n"] }]
|
|
2178
|
+
}] });
|
|
2179
|
+
|
|
2180
|
+
class ProgressFormService {
|
|
2181
|
+
currentPage = signal(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
|
|
2182
|
+
totalPages = signal(6, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
|
|
2183
|
+
stepsConfig = {
|
|
2184
|
+
1: { title: 'Paso 1', key: 'step1' },
|
|
2185
|
+
2: { title: 'Paso 2', key: 'step2' },
|
|
2186
|
+
};
|
|
2187
|
+
resetData() {
|
|
2188
|
+
this.currentPage.set(1);
|
|
2189
|
+
}
|
|
2190
|
+
getProgressText() {
|
|
2191
|
+
return `${this.currentPage()}/${this.totalPages()}`;
|
|
2192
|
+
}
|
|
2193
|
+
getCurrentPageTitle() {
|
|
2194
|
+
const currentPage = this.currentPage();
|
|
2195
|
+
return this.stepsConfig[currentPage]?.title || `Página ${currentPage}`;
|
|
2196
|
+
}
|
|
2197
|
+
nextPage() {
|
|
2198
|
+
const current = this.currentPage();
|
|
2199
|
+
if (current < this.totalPages()) {
|
|
2200
|
+
this.currentPage.set(current + 1);
|
|
2201
|
+
return true;
|
|
2202
|
+
}
|
|
2203
|
+
return false;
|
|
2204
|
+
}
|
|
2205
|
+
prevPage() {
|
|
2206
|
+
const current = this.currentPage();
|
|
2207
|
+
if (current > 1) {
|
|
2208
|
+
this.currentPage.set(current - 1);
|
|
2209
|
+
return true;
|
|
2210
|
+
}
|
|
2211
|
+
return false;
|
|
2212
|
+
}
|
|
2213
|
+
getProgressPercentage() {
|
|
2214
|
+
const current = this.currentPage();
|
|
2215
|
+
const total = this.totalPages();
|
|
2216
|
+
return Math.round((current / total) * 100);
|
|
2217
|
+
}
|
|
2218
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProgressFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2219
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProgressFormService, providedIn: 'root' });
|
|
2220
|
+
}
|
|
2221
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProgressFormService, decorators: [{
|
|
2222
|
+
type: Injectable,
|
|
2223
|
+
args: [{
|
|
2224
|
+
providedIn: 'root',
|
|
2225
|
+
}]
|
|
2226
|
+
}] });
|
|
2227
|
+
|
|
2228
|
+
class ProgressBar {
|
|
2229
|
+
progress;
|
|
2230
|
+
constructor(progress) {
|
|
2231
|
+
this.progress = progress;
|
|
2232
|
+
}
|
|
2233
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
2234
|
+
current = input(1, ...(ngDevMode ? [{ debugName: "current" }] : []));
|
|
2235
|
+
total = input(1, ...(ngDevMode ? [{ debugName: "total" }] : []));
|
|
2236
|
+
get percentage() {
|
|
2237
|
+
return Math.round((this.current() / this.total()) * 100);
|
|
2238
|
+
}
|
|
2239
|
+
get text() {
|
|
2240
|
+
return `Paso ${this.current()} de ${this.total()}`;
|
|
2241
|
+
}
|
|
2242
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProgressBar, deps: [{ token: ProgressFormService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2243
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: ProgressBar, isStandalone: true, selector: "lib-progress-bar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, current: { classPropertyName: "current", publicName: "current", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"progress-container\">\r\n <div class=\"progress-header\">\r\n <span class=\"progress-title\">{{ title() }}</span>\r\n <span class=\"progress-fraction\">{{ text }}</span>\r\n </div>\r\n\r\n <div class=\"progress-bar\">\r\n <div\r\n class=\"progress-fill\"\r\n [style.width.%]=\"percentage\"\r\n ></div>\r\n </div>\r\n</div>\r\n", styles: [".progress-container{width:100%}.progress-header{display:flex;justify-content:center;align-items:center;margin-bottom:7px;gap:4px}.progress-title{color:#454733;font-size:1rem;font-size:400}.progress-fraction{font-size:1rem;color:#454733;font-size:400}.progress-bar{width:100%;height:8px;background-color:#dee58f;border-radius:4px;overflow:hidden;margin-bottom:8px}.progress-fill{height:100%;background-color:#596300;border-radius:4px;transition:width .4s ease-in-out}.progress-percentage{text-align:center;font-size:12px;color:#6c757d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
2244
|
+
}
|
|
2245
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProgressBar, decorators: [{
|
|
2246
|
+
type: Component,
|
|
2247
|
+
args: [{ selector: 'lib-progress-bar', standalone: true, imports: [CommonModule], template: "<div class=\"progress-container\">\r\n <div class=\"progress-header\">\r\n <span class=\"progress-title\">{{ title() }}</span>\r\n <span class=\"progress-fraction\">{{ text }}</span>\r\n </div>\r\n\r\n <div class=\"progress-bar\">\r\n <div\r\n class=\"progress-fill\"\r\n [style.width.%]=\"percentage\"\r\n ></div>\r\n </div>\r\n</div>\r\n", styles: [".progress-container{width:100%}.progress-header{display:flex;justify-content:center;align-items:center;margin-bottom:7px;gap:4px}.progress-title{color:#454733;font-size:1rem;font-size:400}.progress-fraction{font-size:1rem;color:#454733;font-size:400}.progress-bar{width:100%;height:8px;background-color:#dee58f;border-radius:4px;overflow:hidden;margin-bottom:8px}.progress-fill{height:100%;background-color:#596300;border-radius:4px;transition:width .4s ease-in-out}.progress-percentage{text-align:center;font-size:12px;color:#6c757d}\n"] }]
|
|
2248
|
+
}], ctorParameters: () => [{ type: ProgressFormService }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], current: [{ type: i0.Input, args: [{ isSignal: true, alias: "current", required: false }] }], total: [{ type: i0.Input, args: [{ isSignal: true, alias: "total", required: false }] }] } });
|
|
2249
|
+
|
|
2250
|
+
class ProcessingOverlay {
|
|
2251
|
+
loadingText = input('', ...(ngDevMode ? [{ debugName: "loadingText" }] : []));
|
|
2252
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProcessingOverlay, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2253
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: ProcessingOverlay, isStandalone: true, selector: "lib-processing-overlay", inputs: { loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"loading-container\">\r\n <div class=\"loading-content\">\r\n <figure>\r\n <svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M58.8943 10.1325C61.244 6.40017 66.7559 6.40017 69.1056 10.1325L74.7379 19.079C76.2827 21.5328 79.399 22.5304 82.1127 21.4398L92.0068 17.4636C96.1345 15.8048 100.594 18.9967 100.268 23.3769L99.487 33.8765C99.2728 36.7562 101.199 39.368 104.045 40.0572L114.422 42.57C118.751 43.6183 120.454 48.783 117.577 52.138L110.681 60.18C108.79 62.3857 108.79 65.6141 110.681 67.8198L117.577 75.8619C120.454 79.2169 118.751 84.3816 114.422 85.4298L104.045 87.9427C101.199 88.6319 99.2728 91.2436 99.487 94.1234L100.268 104.623C100.594 109.003 96.1345 112.195 92.0069 110.536L82.1127 106.56C79.399 105.469 76.2827 106.467 74.7379 108.921L69.1056 117.867C66.756 121.6 61.244 121.6 58.8943 117.867L53.2621 108.921C51.7173 106.467 48.6009 105.469 45.8872 106.56L35.9931 110.536C31.8655 112.195 27.4062 109.003 27.732 104.623L28.5129 94.1234C28.7271 91.2436 26.8011 88.6319 23.955 87.9427L13.5783 85.4299C9.24928 84.3816 7.546 79.2169 10.4228 75.8619L17.3186 67.8198C19.21 65.6141 19.21 62.3857 17.3186 60.18L10.4228 52.138C7.546 48.783 9.24928 43.6183 13.5783 42.57L23.955 40.0572C26.8011 39.368 28.7271 36.7562 28.5129 33.8765L27.732 23.3769C27.4062 18.9967 31.8655 15.8048 35.9931 17.4636L45.8872 21.4398C48.6009 22.5304 51.7173 21.5328 53.2621 19.079L58.8943 10.1325Z\" fill=\"#BFD100\"/>\r\n </svg> \r\n </figure>\r\n <p class=\"loading-text\">{{ loadingText() }}</p>\r\n </div>\r\n</div>\r\n", styles: [".loading-container{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#00000076;display:flex;justify-content:center;align-items:center;z-index:9999}.loading-content{display:flex;flex-direction:column;align-items:center;gap:20px}.loading-content figure{margin:0;display:flex;justify-content:center;align-items:center}.loading-content figure svg{width:80px;height:80px;animation:svgSpin 2s linear infinite}@keyframes svgSpin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes svgPulse{0%{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(1.1)}to{opacity:1;transform:scale(1)}}@keyframes svgBounce{0%,20%,50%,80%,to{transform:translateY(0)}40%{transform:translateY(-10px)}60%{transform:translateY(-5px)}}.loading-text{color:#fafae8;font-size:18px;font-weight:500;margin:0;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}\n"] });
|
|
2254
|
+
}
|
|
2255
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ProcessingOverlay, decorators: [{
|
|
2256
|
+
type: Component,
|
|
2257
|
+
args: [{ selector: 'lib-processing-overlay', imports: [], template: "<div class=\"loading-container\">\r\n <div class=\"loading-content\">\r\n <figure>\r\n <svg width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M58.8943 10.1325C61.244 6.40017 66.7559 6.40017 69.1056 10.1325L74.7379 19.079C76.2827 21.5328 79.399 22.5304 82.1127 21.4398L92.0068 17.4636C96.1345 15.8048 100.594 18.9967 100.268 23.3769L99.487 33.8765C99.2728 36.7562 101.199 39.368 104.045 40.0572L114.422 42.57C118.751 43.6183 120.454 48.783 117.577 52.138L110.681 60.18C108.79 62.3857 108.79 65.6141 110.681 67.8198L117.577 75.8619C120.454 79.2169 118.751 84.3816 114.422 85.4298L104.045 87.9427C101.199 88.6319 99.2728 91.2436 99.487 94.1234L100.268 104.623C100.594 109.003 96.1345 112.195 92.0069 110.536L82.1127 106.56C79.399 105.469 76.2827 106.467 74.7379 108.921L69.1056 117.867C66.756 121.6 61.244 121.6 58.8943 117.867L53.2621 108.921C51.7173 106.467 48.6009 105.469 45.8872 106.56L35.9931 110.536C31.8655 112.195 27.4062 109.003 27.732 104.623L28.5129 94.1234C28.7271 91.2436 26.8011 88.6319 23.955 87.9427L13.5783 85.4299C9.24928 84.3816 7.546 79.2169 10.4228 75.8619L17.3186 67.8198C19.21 65.6141 19.21 62.3857 17.3186 60.18L10.4228 52.138C7.546 48.783 9.24928 43.6183 13.5783 42.57L23.955 40.0572C26.8011 39.368 28.7271 36.7562 28.5129 33.8765L27.732 23.3769C27.4062 18.9967 31.8655 15.8048 35.9931 17.4636L45.8872 21.4398C48.6009 22.5304 51.7173 21.5328 53.2621 19.079L58.8943 10.1325Z\" fill=\"#BFD100\"/>\r\n </svg> \r\n </figure>\r\n <p class=\"loading-text\">{{ loadingText() }}</p>\r\n </div>\r\n</div>\r\n", styles: [".loading-container{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#00000076;display:flex;justify-content:center;align-items:center;z-index:9999}.loading-content{display:flex;flex-direction:column;align-items:center;gap:20px}.loading-content figure{margin:0;display:flex;justify-content:center;align-items:center}.loading-content figure svg{width:80px;height:80px;animation:svgSpin 2s linear infinite}@keyframes svgSpin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes svgPulse{0%{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(1.1)}to{opacity:1;transform:scale(1)}}@keyframes svgBounce{0%,20%,50%,80%,to{transform:translateY(0)}40%{transform:translateY(-10px)}60%{transform:translateY(-5px)}}.loading-text{color:#fafae8;font-size:18px;font-weight:500;margin:0;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}\n"] }]
|
|
2258
|
+
}], propDecorators: { loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }] } });
|
|
2259
|
+
|
|
2260
|
+
class InfoGroup {
|
|
2261
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
2262
|
+
title = input(null, ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
2263
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InfoGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2264
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: InfoGroup, isStandalone: true, selector: "lib-info-group", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"info-card\">\r\n @if (title()) {\r\n <h3 class=\"info-title\">{{ title() }}</h3>\r\n }\r\n\r\n <div class=\"info-grid\">\r\n @for (item of items(); track item.label) {\r\n <div class=\"info-row\">\r\n <span class=\"info-label\">{{ item.label }}</span>\r\n <span class=\"info-value\">\r\n {{\r\n item.value === true ? \"S\u00CD\" :\r\n item.value === false ? \"NO\" :\r\n item.value || \"-\"\r\n }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".info-card{background:#f7f6e3;border-radius:18px;padding:20px 24px;width:100%}.info-title{font-size:14px;font-weight:700;color:#40484c;margin-bottom:16px}.info-grid{display:grid;grid-template-columns:1fr 1fr;column-gap:32px;row-gap:14px}.info-row{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid rgba(64,72,76,.15);padding-bottom:14px}.info-label{font-size:13px;color:#40484c;font-weight:500}.info-value{font-size:13px;color:#40484c;font-weight:600}@media (max-width: 768px){.info-grid{grid-template-columns:1fr}}\n"] });
|
|
2265
|
+
}
|
|
2266
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InfoGroup, decorators: [{
|
|
2267
|
+
type: Component,
|
|
2268
|
+
args: [{ selector: 'lib-info-group', imports: [], template: "<div class=\"info-card\">\r\n @if (title()) {\r\n <h3 class=\"info-title\">{{ title() }}</h3>\r\n }\r\n\r\n <div class=\"info-grid\">\r\n @for (item of items(); track item.label) {\r\n <div class=\"info-row\">\r\n <span class=\"info-label\">{{ item.label }}</span>\r\n <span class=\"info-value\">\r\n {{\r\n item.value === true ? \"S\u00CD\" :\r\n item.value === false ? \"NO\" :\r\n item.value || \"-\"\r\n }}\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".info-card{background:#f7f6e3;border-radius:18px;padding:20px 24px;width:100%}.info-title{font-size:14px;font-weight:700;color:#40484c;margin-bottom:16px}.info-grid{display:grid;grid-template-columns:1fr 1fr;column-gap:32px;row-gap:14px}.info-row{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid rgba(64,72,76,.15);padding-bottom:14px}.info-label{font-size:13px;color:#40484c;font-weight:500}.info-value{font-size:13px;color:#40484c;font-weight:600}@media (max-width: 768px){.info-grid{grid-template-columns:1fr}}\n"] }]
|
|
2269
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
|
|
2270
|
+
|
|
2271
|
+
class FeatureCard {
|
|
2272
|
+
feature = input(...(ngDevMode ? [undefined, { debugName: "feature" }] : []));
|
|
2273
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FeatureCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2274
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: FeatureCard, isStandalone: true, selector: "lib-feature-card", inputs: { feature: { classPropertyName: "feature", publicName: "feature", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"feature-card\">\r\n <div class=\"feature-icon\">\r\n <img [src]=\"feature()?.icon\" alt=\"{{ feature()?.title }}\" />\r\n </div>\r\n <div>\r\n <h3>{{ feature()?.title }}</h3>\r\n <p>{{ feature()?.description }}</p>\r\n </div>\r\n</div>\r\n\r\n", styles: [".feature-card{position:relative;flex:1;padding:8px;display:flex;align-items:center;gap:8px;border-radius:8px}.feature-icon{flex:0 0 50px;height:50px;border-radius:50%;display:flex;align-items:center;justify-content:center;background-color:#dee58f;margin-right:10px}.feature-icon img{width:28px;height:28px;color:#61661f}.feature-content{flex:1;display:flex;flex-direction:column}.feature-card h3{margin:0 0 5px;font-size:1.6rem;font-weight:600;color:#171c1f;transition:color .3s ease}.feature-card p{margin:0;color:#171c1f;font-weight:400;line-height:1.6;font-size:1.4rem}@media (max-width: 768px){.feature-card{padding:12px;gap:12px}.feature-icon{flex:0 0 48px;height:48px;margin-right:8px}.feature-icon img{width:28px;height:28px}.feature-card h3{font-size:1.5rem}.feature-card p{font-size:1.3rem}}@media (max-width: 640px){.feature-card{flex-direction:column;align-items:center;text-align:center;padding:16px 12px;gap:12px;min-height:140px}.feature-icon{flex:none;margin-right:0;margin-bottom:8px;width:56px;height:56px}.feature-icon img{width:32px;height:32px}.feature-content{align-items:center;text-align:center}.feature-card h3{margin-bottom:8px;font-size:1.4rem;line-height:1.3}.feature-card p{font-size:1.2rem;line-height:1.5;max-width:200px}}@media (max-width: 480px){.feature-card{padding:14px 10px;min-height:130px;gap:10px}.feature-icon{width:52px;height:52px;margin-bottom:6px}.feature-icon img{width:30px;height:30px}.feature-card h3{font-size:1.3rem;margin-bottom:6px}.feature-card p{font-size:1.1rem;line-height:1.4;max-width:180px}}@media (max-width: 360px){.feature-card{padding:12px 8px;min-height:120px;gap:8px}.feature-icon{width:48px;height:48px;margin-bottom:4px}.feature-icon img{width:28px;height:28px}.feature-card h3{font-size:1.2rem;margin-bottom:4px;line-height:1.2}.feature-card p{font-size:1rem;line-height:1.3;max-width:160px}}.features-grid{display:flex;gap:16px;flex-wrap:wrap}\n"] });
|
|
2275
|
+
}
|
|
2276
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: FeatureCard, decorators: [{
|
|
2277
|
+
type: Component,
|
|
2278
|
+
args: [{ selector: 'lib-feature-card', standalone: true, template: "<div class=\"feature-card\">\r\n <div class=\"feature-icon\">\r\n <img [src]=\"feature()?.icon\" alt=\"{{ feature()?.title }}\" />\r\n </div>\r\n <div>\r\n <h3>{{ feature()?.title }}</h3>\r\n <p>{{ feature()?.description }}</p>\r\n </div>\r\n</div>\r\n\r\n", styles: [".feature-card{position:relative;flex:1;padding:8px;display:flex;align-items:center;gap:8px;border-radius:8px}.feature-icon{flex:0 0 50px;height:50px;border-radius:50%;display:flex;align-items:center;justify-content:center;background-color:#dee58f;margin-right:10px}.feature-icon img{width:28px;height:28px;color:#61661f}.feature-content{flex:1;display:flex;flex-direction:column}.feature-card h3{margin:0 0 5px;font-size:1.6rem;font-weight:600;color:#171c1f;transition:color .3s ease}.feature-card p{margin:0;color:#171c1f;font-weight:400;line-height:1.6;font-size:1.4rem}@media (max-width: 768px){.feature-card{padding:12px;gap:12px}.feature-icon{flex:0 0 48px;height:48px;margin-right:8px}.feature-icon img{width:28px;height:28px}.feature-card h3{font-size:1.5rem}.feature-card p{font-size:1.3rem}}@media (max-width: 640px){.feature-card{flex-direction:column;align-items:center;text-align:center;padding:16px 12px;gap:12px;min-height:140px}.feature-icon{flex:none;margin-right:0;margin-bottom:8px;width:56px;height:56px}.feature-icon img{width:32px;height:32px}.feature-content{align-items:center;text-align:center}.feature-card h3{margin-bottom:8px;font-size:1.4rem;line-height:1.3}.feature-card p{font-size:1.2rem;line-height:1.5;max-width:200px}}@media (max-width: 480px){.feature-card{padding:14px 10px;min-height:130px;gap:10px}.feature-icon{width:52px;height:52px;margin-bottom:6px}.feature-icon img{width:30px;height:30px}.feature-card h3{font-size:1.3rem;margin-bottom:6px}.feature-card p{font-size:1.1rem;line-height:1.4;max-width:180px}}@media (max-width: 360px){.feature-card{padding:12px 8px;min-height:120px;gap:8px}.feature-icon{width:48px;height:48px;margin-bottom:4px}.feature-icon img{width:28px;height:28px}.feature-card h3{font-size:1.2rem;margin-bottom:4px;line-height:1.2}.feature-card p{font-size:1rem;line-height:1.3;max-width:160px}}.features-grid{display:flex;gap:16px;flex-wrap:wrap}\n"] }]
|
|
2279
|
+
}], propDecorators: { feature: [{ type: i0.Input, args: [{ isSignal: true, alias: "feature", required: false }] }] } });
|
|
2280
|
+
|
|
2078
2281
|
// src/app/components/public-api.ts
|
|
2079
2282
|
// Exportar el componente
|
|
2080
2283
|
|
|
@@ -2082,5 +2285,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
2082
2285
|
* Generated bundle index. Do not edit.
|
|
2083
2286
|
*/
|
|
2084
2287
|
|
|
2085
|
-
export { DateTimeFilter, DateTimePicker, DialogAlertComponent, DialogConfirmation, DynamicFormFields, InputNumberFilter, InputSelectFilter, InputTextFilter, ModalForm, PaginationComponent, STATUS_TONE_STYLES, SelectCustomSearch, Table, WizardForm };
|
|
2288
|
+
export { DateTimeFilter, DateTimePicker, DialogAlertComponent, DialogConfirmation, DynamicFormFields, FeatureCard, InfoGroup, Input, InputNumberFilter, InputSelectFilter, InputTextFilter, Loader, ModalForm, NotFoundModal, PaginationComponent, ProcessingOverlay, ProgressBar, ProgressFormService, STATUS_TONE_STYLES, SelectCustomSearch, TOAST_EVENTS, Table, ToastHelper, WizardForm };
|
|
2086
2289
|
//# sourceMappingURL=sapenlinea-components.mjs.map
|