sapenlinea-components 0.0.26 → 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 +1119 -895
- package/fesm2022/sapenlinea-components.mjs.map +1 -1
- package/index.d.ts +229 -114
- 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
|
-
this.dateSelected.emit({
|
|
227
|
-
filter: filterValue,
|
|
228
|
-
value: parsedDate,
|
|
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();
|
|
230
201
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
202
|
+
// Caso: números
|
|
203
|
+
if (!isNaN(Number(x)) && !isNaN(Number(y))) {
|
|
204
|
+
return dir === 'asc' ? Number(x) - Number(y) : Number(y) - Number(x);
|
|
205
|
+
}
|
|
206
|
+
// Caso: strings
|
|
207
|
+
return dir === 'asc'
|
|
208
|
+
? x.toString().localeCompare(y.toString())
|
|
209
|
+
: y.toString().localeCompare(x.toString());
|
|
210
|
+
});
|
|
238
211
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.open();
|
|
212
|
+
isDate(value) {
|
|
213
|
+
return (typeof value === 'string' &&
|
|
214
|
+
value.length > 5 &&
|
|
215
|
+
!isNaN(Date.parse(value)));
|
|
244
216
|
}
|
|
245
|
-
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const match = input.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
|
250
|
-
if (match) {
|
|
251
|
-
const day = parseInt(match[1], 10);
|
|
252
|
-
const month = parseInt(match[2], 10) - 1;
|
|
253
|
-
const year = parseInt(match[3], 10);
|
|
254
|
-
// Validate date
|
|
255
|
-
if (day >= 1 && day <= 31 && month >= 0 && month <= 11 && year >= 1900 && year <= 2100) {
|
|
256
|
-
const date = new Date(year, month, day);
|
|
257
|
-
// Check if date is valid (handles invalid dates like 31/02/2024)
|
|
258
|
-
if (date.getDate() === day && date.getMonth() === month && date.getFullYear() === year) {
|
|
259
|
-
return date;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
217
|
+
onSort(col) {
|
|
218
|
+
if (this.sortColumn() === col.key) {
|
|
219
|
+
// cambiar asc <-> desc
|
|
220
|
+
this.sortDirection.set(this.sortDirection() === 'asc' ? 'desc' : 'asc');
|
|
262
221
|
}
|
|
263
|
-
|
|
222
|
+
else {
|
|
223
|
+
// nueva columna → empieza en desc (más reciente primero)
|
|
224
|
+
this.sortColumn.set(col.key);
|
|
225
|
+
this.sortDirection.set('desc');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
onIconColumnClick(col, row, event) {
|
|
229
|
+
event.stopPropagation();
|
|
230
|
+
this.iconAction.emit({
|
|
231
|
+
action: col.iconKey ?? col.key,
|
|
232
|
+
row
|
|
233
|
+
});
|
|
264
234
|
}
|
|
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;
|
|
282
|
+
}
|
|
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
|
-
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();
|
|
487
|
+
this.dateChange.emit(today);
|
|
488
|
+
if (this.mode() === 'date') {
|
|
489
|
+
this.close();
|
|
490
|
+
}
|
|
415
491
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
this.
|
|
422
|
-
this.selectedHour.set(newHour24);
|
|
423
|
-
this.updateDateTime();
|
|
492
|
+
clear() {
|
|
493
|
+
this.resetInternalState();
|
|
494
|
+
this.onChange(null);
|
|
495
|
+
this.markAsTouched();
|
|
496
|
+
this.dateChange.emit(null);
|
|
497
|
+
this.close();
|
|
424
498
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if (!selected)
|
|
499
|
+
onKeyDown(event) {
|
|
500
|
+
if (this.isBlocked())
|
|
428
501
|
return;
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
this.onChange(newDate.toISOString());
|
|
437
|
-
this.markAsTouched();
|
|
438
|
-
this.dateChange.emit(newDate);
|
|
439
|
-
this.dateSelected.emit({
|
|
440
|
-
filter: this.filterValue(),
|
|
441
|
-
value: newDate,
|
|
442
|
-
});
|
|
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,353 +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.
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
this.pageSizeValue.set(size);
|
|
524
|
-
this.pageSizeChange.emit(size);
|
|
525
|
-
this.showPageSizeMenu.set(false);
|
|
526
|
-
this.isOpen.set(false);
|
|
527
|
-
}
|
|
528
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
529
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", 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"] }] });
|
|
530
|
-
}
|
|
531
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PaginationComponent, decorators: [{
|
|
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
|
-
toggleMenu(index) {
|
|
570
|
-
this.openedMenu.set(this.openedMenu() === index ? null : index);
|
|
571
|
-
}
|
|
572
|
-
onOptionClick(option, row) {
|
|
573
|
-
this.optionSelected.emit({ action: option.label, row });
|
|
574
|
-
this.openedMenu.set(null);
|
|
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);
|
|
575
554
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
if (this.
|
|
579
|
-
|
|
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
|
+
}
|
|
580
575
|
}
|
|
581
|
-
|
|
582
|
-
|
|
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);
|
|
583
597
|
}
|
|
584
598
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
599
|
+
onInputFocus() {
|
|
600
|
+
if (this.isBlocked())
|
|
601
|
+
return;
|
|
602
|
+
this.open();
|
|
603
|
+
}
|
|
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
|
+
}
|
|
589
618
|
}
|
|
619
|
+
return null;
|
|
590
620
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
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}`;
|
|
626
|
+
}
|
|
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);
|
|
636
|
+
}
|
|
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');
|
|
643
|
+
}
|
|
644
|
+
markAsTouched() {
|
|
645
|
+
if (!this.isTouched()) {
|
|
646
|
+
this.isTouched.set(true);
|
|
647
|
+
this.onTouched();
|
|
603
648
|
}
|
|
604
649
|
}
|
|
605
|
-
|
|
606
|
-
if (
|
|
607
|
-
|
|
608
|
-
switch (col.type) {
|
|
609
|
-
case 'money':
|
|
610
|
-
return new Intl.NumberFormat('es-CO', {
|
|
611
|
-
style: 'currency',
|
|
612
|
-
currency: 'COP',
|
|
613
|
-
minimumFractionDigits: 0
|
|
614
|
-
}).format(value);
|
|
615
|
-
case 'number':
|
|
616
|
-
return new Intl.NumberFormat('es-CO').format(value);
|
|
617
|
-
case 'percentage':
|
|
618
|
-
return `${value}%`;
|
|
619
|
-
case 'date':
|
|
620
|
-
const d = new Date(value);
|
|
621
|
-
return d.toLocaleDateString('es-CO'); // dd/mm/yyyy
|
|
622
|
-
default:
|
|
623
|
-
return String(value);
|
|
650
|
+
addDocumentListener() {
|
|
651
|
+
if (this.documentClickListener) {
|
|
652
|
+
this.removeDocumentListener();
|
|
624
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
|
+
});
|
|
625
670
|
}
|
|
626
|
-
|
|
627
|
-
if (
|
|
628
|
-
|
|
671
|
+
removeDocumentListener() {
|
|
672
|
+
if (this.documentClickListener) {
|
|
673
|
+
document.removeEventListener('click', this.documentClickListener, true);
|
|
674
|
+
this.documentClickListener = undefined;
|
|
629
675
|
}
|
|
630
|
-
const key = this.normalizeStatus(value);
|
|
631
|
-
const tone = this.statusToneMap()?.[key] ?? 'neutral';
|
|
632
|
-
return STATUS_TONE_STYLES[tone];
|
|
633
676
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
.toLowerCase()
|
|
637
|
-
.trim()
|
|
638
|
-
.replace(/\s+/g, '_');
|
|
677
|
+
markTouched() {
|
|
678
|
+
this.markAsTouched();
|
|
639
679
|
}
|
|
640
680
|
/**
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
* 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
|
|
644
683
|
*/
|
|
645
|
-
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
return [];
|
|
649
|
-
if (typeof acts === 'function') {
|
|
650
|
-
try {
|
|
651
|
-
return acts(row) ?? [];
|
|
652
|
-
}
|
|
653
|
-
catch {
|
|
654
|
-
return [];
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
return acts;
|
|
684
|
+
getISOString() {
|
|
685
|
+
const date = this.selectedDate();
|
|
686
|
+
return date ? date.toISOString() : null;
|
|
658
687
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
return dir === 'asc'
|
|
670
|
-
? new Date(x).getTime() - new Date(y).getTime()
|
|
671
|
-
: new Date(y).getTime() - new Date(x).getTime();
|
|
672
|
-
}
|
|
673
|
-
// Caso: números
|
|
674
|
-
if (!isNaN(Number(x)) && !isNaN(Number(y))) {
|
|
675
|
-
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);
|
|
676
698
|
}
|
|
677
|
-
// Caso: strings
|
|
678
|
-
return dir === 'asc'
|
|
679
|
-
? x.toString().localeCompare(y.toString())
|
|
680
|
-
: y.toString().localeCompare(x.toString());
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
isDate(value) {
|
|
684
|
-
return (typeof value === 'string' &&
|
|
685
|
-
value.length > 5 &&
|
|
686
|
-
!isNaN(Date.parse(value)));
|
|
687
|
-
}
|
|
688
|
-
onSort(col) {
|
|
689
|
-
if (this.sortColumn() === col.key) {
|
|
690
|
-
// cambiar asc <-> desc
|
|
691
|
-
this.sortDirection.set(this.sortDirection() === 'asc' ? 'desc' : 'asc');
|
|
692
699
|
}
|
|
693
700
|
else {
|
|
694
|
-
|
|
695
|
-
this.sortColumn.set(col.key);
|
|
696
|
-
this.sortDirection.set('desc');
|
|
701
|
+
this.clear();
|
|
697
702
|
}
|
|
698
703
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: Table, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
707
|
-
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)" } }, 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 [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 } @else if (col.type === 'icon-button') {\r\n\r\n <button\r\n (click)=\"onIconColumnClick(col, row, $event)\"\r\n >\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}.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{position:relative;display:inline-flex;align-items:center;width:100%;max-width:80%;gap:6px;padding:4px 10px;border-radius:8px;font-size:13px;font-weight:500;white-space:nowrap;text-overflow:ellipsis}.status-dot{width:8px;height:8px;border-radius:50%;display:inline-block;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"] });
|
|
708
712
|
}
|
|
709
|
-
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: [{
|
|
710
714
|
type: Component,
|
|
711
|
-
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 [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 } @else if (col.type === 'icon-button') {\r\n\r\n <button\r\n (click)=\"onIconColumnClick(col, row, $event)\"\r\n >\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}.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{position:relative;display:inline-flex;align-items:center;width:100%;max-width:80%;gap:6px;padding:4px 10px;border-radius:8px;font-size:13px;font-weight:500;white-space:nowrap;text-overflow:ellipsis}.status-dot{width:8px;height:8px;border-radius:50%;display:inline-block;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"] }]
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
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 }] }] } });
|
|
716
723
|
|
|
717
|
-
class
|
|
724
|
+
class DateTimeFilter {
|
|
718
725
|
elementRef;
|
|
719
726
|
ngZone;
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
727
|
+
// Inputs
|
|
728
|
+
filters = input([], ...(ngDevMode ? [{ debugName: "filters" }] : []));
|
|
729
|
+
// Outputs
|
|
730
|
+
dateSelected = output();
|
|
724
731
|
dateChange = output();
|
|
732
|
+
// Internal State
|
|
733
|
+
activeFilterType = signal(null, ...(ngDevMode ? [{ debugName: "activeFilterType" }] : []));
|
|
725
734
|
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
726
735
|
selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : []));
|
|
736
|
+
inputTextValue = signal('', ...(ngDevMode ? [{ debugName: "inputTextValue" }] : []));
|
|
727
737
|
isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
728
738
|
isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
|
|
729
|
-
//
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
return Array.from({ length: 12 }, (_, i) => {
|
|
785
|
-
const hour12 = i === 0 ? 12 : i;
|
|
786
|
-
return {
|
|
787
|
-
value: hour12,
|
|
788
|
-
display: hour12.toString().padStart(2, '0')
|
|
789
|
-
};
|
|
790
|
-
});
|
|
791
|
-
}, ...(ngDevMode ? [{ debugName: "hours12" }] : []));
|
|
792
|
-
// Hora seleccionada en formato 12h
|
|
793
|
-
selectedHour12 = computed(() => {
|
|
794
|
-
const hour24 = this.selectedHour();
|
|
795
|
-
if (hour24 === 0)
|
|
796
|
-
return 12;
|
|
797
|
-
if (hour24 > 12)
|
|
798
|
-
return hour24 - 12;
|
|
799
|
-
return hour24;
|
|
800
|
-
}, ...(ngDevMode ? [{ debugName: "selectedHour12" }] : []));
|
|
801
|
-
minutes = computed(() => Array.from({ length: 60 }, (_, i) => i), ...(ngDevMode ? [{ debugName: "minutes" }] : []));
|
|
802
|
-
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 = () => { };
|
|
803
794
|
onTouched = () => { };
|
|
804
795
|
constructor(elementRef, ngZone) {
|
|
805
796
|
this.elementRef = elementRef;
|
|
806
797
|
this.ngZone = ngZone;
|
|
798
|
+
effect(() => {
|
|
799
|
+
const trigger = this.clearTrigger();
|
|
800
|
+
if (trigger > 0) {
|
|
801
|
+
this.clear();
|
|
802
|
+
}
|
|
803
|
+
});
|
|
807
804
|
}
|
|
808
805
|
ngOnDestroy() {
|
|
809
806
|
this.removeDocumentListener();
|
|
810
807
|
}
|
|
808
|
+
// ControlValueAccessor Implementation
|
|
811
809
|
writeValue(value) {
|
|
812
810
|
let date = null;
|
|
813
811
|
if (value instanceof Date) {
|
|
814
812
|
date = value;
|
|
815
813
|
}
|
|
816
814
|
else if (typeof value === 'string' && value) {
|
|
817
|
-
// Manejar tanto fechas ISO como otros formatos de string
|
|
818
815
|
const parsedDate = new Date(value);
|
|
819
816
|
if (!isNaN(parsedDate.getTime())) {
|
|
820
817
|
date = parsedDate;
|
|
@@ -836,14 +833,15 @@ class DateTimePicker {
|
|
|
836
833
|
setDisabledState(isDisabled) {
|
|
837
834
|
this.isDisabled.set(isDisabled);
|
|
838
835
|
}
|
|
839
|
-
|
|
836
|
+
// Public Methods
|
|
837
|
+
toggle(filterValue) {
|
|
840
838
|
if (this.isDisabled())
|
|
841
839
|
return;
|
|
842
|
-
this.
|
|
843
|
-
if (this.isOpen()) {
|
|
840
|
+
if (this.activeFilterType() === filterValue && this.isOpen()) {
|
|
844
841
|
this.close();
|
|
845
842
|
}
|
|
846
843
|
else {
|
|
844
|
+
this.activeFilterType.set(filterValue);
|
|
847
845
|
this.open();
|
|
848
846
|
}
|
|
849
847
|
}
|
|
@@ -853,7 +851,6 @@ class DateTimePicker {
|
|
|
853
851
|
this.markAsTouched();
|
|
854
852
|
this.isOpen.set(true);
|
|
855
853
|
this.addDocumentListener();
|
|
856
|
-
// Si hay fecha seleccionada, navegar a ese mes/año
|
|
857
854
|
const selected = this.selectedDate();
|
|
858
855
|
if (selected) {
|
|
859
856
|
this.currentMonth.set(selected.getMonth());
|
|
@@ -864,7 +861,13 @@ class DateTimePicker {
|
|
|
864
861
|
this.isOpen.set(false);
|
|
865
862
|
this.removeDocumentListener();
|
|
866
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.
|
|
867
869
|
}
|
|
870
|
+
// Calendar Logic
|
|
868
871
|
selectDay(day) {
|
|
869
872
|
if (!day || this.isDisabled())
|
|
870
873
|
return;
|
|
@@ -875,160 +878,42 @@ class DateTimePicker {
|
|
|
875
878
|
this.onChange(newDate.toISOString());
|
|
876
879
|
this.markAsTouched();
|
|
877
880
|
this.dateChange.emit(newDate);
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
setHour12(hour12) {
|
|
884
|
-
if (this.isDisabled())
|
|
885
|
-
return;
|
|
886
|
-
// Convertir de 12h a 24h
|
|
887
|
-
let hour24;
|
|
888
|
-
const amPm = this.selectedAmPm();
|
|
889
|
-
if (hour12 === 12) {
|
|
890
|
-
hour24 = amPm === 'AM' ? 0 : 12;
|
|
891
|
-
}
|
|
892
|
-
else {
|
|
893
|
-
hour24 = amPm === 'AM' ? hour12 : hour12 + 12;
|
|
894
|
-
}
|
|
895
|
-
this.selectedHour.set(hour24);
|
|
896
|
-
this.updateDateTime();
|
|
897
|
-
}
|
|
898
|
-
setMinute(minute) {
|
|
899
|
-
if (this.isDisabled())
|
|
900
|
-
return;
|
|
901
|
-
this.selectedMinute.set(minute);
|
|
902
|
-
this.updateDateTime();
|
|
903
|
-
}
|
|
904
|
-
setAmPm(amPm) {
|
|
905
|
-
if (this.isDisabled())
|
|
906
|
-
return;
|
|
907
|
-
const currentHour24 = this.selectedHour();
|
|
908
|
-
const currentHour12 = this.selectedHour12();
|
|
909
|
-
let newHour24;
|
|
910
|
-
if (amPm === 'AM') {
|
|
911
|
-
newHour24 = currentHour12 === 12 ? 0 : currentHour12;
|
|
912
|
-
}
|
|
913
|
-
else {
|
|
914
|
-
newHour24 = currentHour12 === 12 ? 12 : currentHour12 + 12;
|
|
915
|
-
}
|
|
916
|
-
this.selectedAmPm.set(amPm);
|
|
917
|
-
this.selectedHour.set(newHour24);
|
|
918
|
-
this.updateDateTime();
|
|
919
|
-
}
|
|
920
|
-
previousMonth() {
|
|
921
|
-
const currentMonth = this.currentMonth();
|
|
922
|
-
const currentYear = this.currentYear();
|
|
923
|
-
if (currentMonth === 0) {
|
|
924
|
-
this.currentMonth.set(11);
|
|
925
|
-
this.currentYear.set(currentYear - 1);
|
|
926
|
-
}
|
|
927
|
-
else {
|
|
928
|
-
this.currentMonth.set(currentMonth - 1);
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
nextMonth() {
|
|
932
|
-
const currentMonth = this.currentMonth();
|
|
933
|
-
const currentYear = this.currentYear();
|
|
934
|
-
if (currentMonth === 11) {
|
|
935
|
-
this.currentMonth.set(0);
|
|
936
|
-
this.currentYear.set(currentYear + 1);
|
|
937
|
-
}
|
|
938
|
-
else {
|
|
939
|
-
this.currentMonth.set(currentMonth + 1);
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
previousYear() {
|
|
943
|
-
this.currentYear.set(this.currentYear() - 1);
|
|
944
|
-
}
|
|
945
|
-
nextYear() {
|
|
946
|
-
this.currentYear.set(this.currentYear() + 1);
|
|
947
|
-
}
|
|
948
|
-
today() {
|
|
949
|
-
const today = new Date();
|
|
950
|
-
this.updateInternalState(today);
|
|
951
|
-
this.onChange(today.toISOString());
|
|
952
|
-
this.markAsTouched();
|
|
953
|
-
this.dateChange.emit(today);
|
|
881
|
+
this.dateSelected.emit({
|
|
882
|
+
filter: this.filterValue(),
|
|
883
|
+
value: newDate,
|
|
884
|
+
});
|
|
954
885
|
if (this.mode() === 'date') {
|
|
955
886
|
this.close();
|
|
956
887
|
}
|
|
957
888
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
this.
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
if (
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
this.markAsTouched();
|
|
973
|
-
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;
|
|
974
903
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
const selected = this.selectedDate();
|
|
980
|
-
if (!selected)
|
|
981
|
-
return false;
|
|
982
|
-
return (selected.getDate() === day &&
|
|
983
|
-
selected.getMonth() === this.currentMonth() &&
|
|
984
|
-
selected.getFullYear() === this.currentYear());
|
|
985
|
-
}
|
|
986
|
-
isToday(day) {
|
|
987
|
-
if (!day)
|
|
988
|
-
return false;
|
|
989
|
-
const today = new Date();
|
|
990
|
-
return (today.getDate() === day &&
|
|
991
|
-
today.getMonth() === this.currentMonth() &&
|
|
992
|
-
today.getFullYear() === this.currentYear());
|
|
993
|
-
}
|
|
994
|
-
isDayDisabled(day) {
|
|
995
|
-
if (!day)
|
|
996
|
-
return true;
|
|
997
|
-
const date = new Date(this.currentYear(), this.currentMonth(), day);
|
|
998
|
-
return this.isDateDisabled(date);
|
|
999
|
-
}
|
|
1000
|
-
isDateDisabled(date) {
|
|
1001
|
-
const minDate = this.minDate();
|
|
1002
|
-
const maxDate = this.maxDate();
|
|
1003
|
-
if (minDate && date < minDate)
|
|
1004
|
-
return true;
|
|
1005
|
-
if (maxDate && date > maxDate)
|
|
1006
|
-
return true;
|
|
1007
|
-
return false;
|
|
1008
|
-
}
|
|
1009
|
-
updateDateTime() {
|
|
1010
|
-
const selected = this.selectedDate();
|
|
1011
|
-
if (!selected)
|
|
1012
|
-
return;
|
|
1013
|
-
const newDate = new Date(selected);
|
|
1014
|
-
newDate.setHours(this.selectedHour());
|
|
1015
|
-
newDate.setMinutes(this.selectedMinute());
|
|
1016
|
-
this.updateInternalState(newDate);
|
|
1017
|
-
this.onChange(newDate.toISOString());
|
|
1018
|
-
this.markAsTouched();
|
|
1019
|
-
this.dateChange.emit(newDate);
|
|
1020
|
-
}
|
|
1021
|
-
// Manejo de input de texto (DD/MM/YYYY)
|
|
1022
|
-
onInputChange(event) {
|
|
904
|
+
return date.toLocaleDateString('es-ES', options);
|
|
905
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
906
|
+
// Input text handling
|
|
907
|
+
onInputChange(event, filterValue) {
|
|
1023
908
|
if (this.isDisabled())
|
|
1024
909
|
return;
|
|
1025
910
|
const input = event.target;
|
|
1026
911
|
let value = input.value;
|
|
1027
|
-
//
|
|
912
|
+
// Remove all non-numeric characters
|
|
1028
913
|
const numbersOnly = value.replace(/\D/g, '');
|
|
1029
|
-
//
|
|
914
|
+
// Limit to 8 digits (DD/MM/YYYY)
|
|
1030
915
|
const limitedNumbers = numbersOnly.slice(0, 8);
|
|
1031
|
-
//
|
|
916
|
+
// Format with slashes: DD/MM/YYYY
|
|
1032
917
|
let formatted = '';
|
|
1033
918
|
if (limitedNumbers.length > 0) {
|
|
1034
919
|
formatted = limitedNumbers.slice(0, 2);
|
|
@@ -1039,57 +924,100 @@ class DateTimePicker {
|
|
|
1039
924
|
formatted += '/' + limitedNumbers.slice(4, 8);
|
|
1040
925
|
}
|
|
1041
926
|
}
|
|
927
|
+
// Update the input value
|
|
1042
928
|
this.inputTextValue.set(formatted);
|
|
1043
929
|
input.value = formatted;
|
|
1044
930
|
this.markAsTouched();
|
|
1045
|
-
//
|
|
931
|
+
// Only parse when we have a complete date (DD/MM/YYYY = 10 characters)
|
|
1046
932
|
if (formatted.length === 10) {
|
|
1047
933
|
const parsedDate = this.parseDateInput(formatted);
|
|
1048
934
|
if (parsedDate) {
|
|
1049
935
|
if (this.isDateDisabled(parsedDate)) {
|
|
1050
|
-
//
|
|
936
|
+
// Invalid date (out of range), but keep the text
|
|
1051
937
|
return;
|
|
1052
938
|
}
|
|
1053
939
|
this.updateInternalState(parsedDate);
|
|
1054
940
|
this.onChange(parsedDate.toISOString());
|
|
1055
941
|
this.dateChange.emit(parsedDate);
|
|
942
|
+
this.dateSelected.emit({
|
|
943
|
+
filter: filterValue,
|
|
944
|
+
value: parsedDate,
|
|
945
|
+
});
|
|
1056
946
|
}
|
|
1057
947
|
}
|
|
1058
948
|
else if (formatted.trim() === '') {
|
|
1059
|
-
//
|
|
949
|
+
// Clear if input is empty
|
|
1060
950
|
this.resetInternalState();
|
|
1061
951
|
this.onChange(null);
|
|
1062
952
|
this.dateChange.emit(null);
|
|
1063
953
|
}
|
|
1064
954
|
}
|
|
1065
|
-
onInputFocus() {
|
|
955
|
+
onInputFocus(filterValue) {
|
|
1066
956
|
if (this.isDisabled())
|
|
1067
957
|
return;
|
|
958
|
+
this.activeFilterType.set(filterValue);
|
|
1068
959
|
this.open();
|
|
1069
960
|
}
|
|
1070
961
|
parseDateInput(input) {
|
|
1071
962
|
if (!input || input.trim() === '')
|
|
1072
963
|
return null;
|
|
964
|
+
// Only accept DD/MM/YYYY format
|
|
1073
965
|
const match = input.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
|
1074
966
|
if (match) {
|
|
1075
967
|
const day = parseInt(match[1], 10);
|
|
1076
968
|
const month = parseInt(match[2], 10) - 1;
|
|
1077
969
|
const year = parseInt(match[3], 10);
|
|
970
|
+
// Validate date
|
|
1078
971
|
if (day >= 1 && day <= 31 && month >= 0 && month <= 11 && year >= 1900 && year <= 2100) {
|
|
1079
972
|
const date = new Date(year, month, day);
|
|
973
|
+
// Check if date is valid (handles invalid dates like 31/02/2024)
|
|
1080
974
|
if (date.getDate() === day && date.getMonth() === month && date.getFullYear() === year) {
|
|
1081
975
|
return date;
|
|
1082
976
|
}
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
return null;
|
|
1086
|
-
}
|
|
1087
|
-
formatDateForInput(date) {
|
|
1088
|
-
const day = date.getDate().toString().padStart(2, '0');
|
|
1089
|
-
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
1090
|
-
const year = date.getFullYear();
|
|
1091
|
-
return `${day}/${month}/${year}`;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return null;
|
|
1092
980
|
}
|
|
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
|
|
1093
1021
|
updateInternalState(date) {
|
|
1094
1022
|
this.selectedDate.set(date);
|
|
1095
1023
|
this.currentMonth.set(date.getMonth());
|
|
@@ -1097,6 +1025,7 @@ class DateTimePicker {
|
|
|
1097
1025
|
this.selectedHour.set(date.getHours());
|
|
1098
1026
|
this.selectedMinute.set(date.getMinutes());
|
|
1099
1027
|
this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');
|
|
1028
|
+
// Update input text value to match the formatted date
|
|
1100
1029
|
const formatted = this.formatDateForInput(date);
|
|
1101
1030
|
this.inputTextValue.set(formatted);
|
|
1102
1031
|
}
|
|
@@ -1107,6 +1036,12 @@ class DateTimePicker {
|
|
|
1107
1036
|
this.selectedMinute.set(0);
|
|
1108
1037
|
this.selectedAmPm.set('AM');
|
|
1109
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
|
+
}
|
|
1110
1045
|
markAsTouched() {
|
|
1111
1046
|
if (!this.isTouched()) {
|
|
1112
1047
|
this.isTouched.set(true);
|
|
@@ -1114,9 +1049,8 @@ class DateTimePicker {
|
|
|
1114
1049
|
}
|
|
1115
1050
|
}
|
|
1116
1051
|
addDocumentListener() {
|
|
1117
|
-
if (this.documentClickListener)
|
|
1052
|
+
if (this.documentClickListener)
|
|
1118
1053
|
this.removeDocumentListener();
|
|
1119
|
-
}
|
|
1120
1054
|
this.ngZone.runOutsideAngular(() => {
|
|
1121
1055
|
this.documentClickListener = (event) => {
|
|
1122
1056
|
const target = event.target;
|
|
@@ -1129,9 +1063,7 @@ class DateTimePicker {
|
|
|
1129
1063
|
});
|
|
1130
1064
|
}
|
|
1131
1065
|
};
|
|
1132
|
-
setTimeout(() =>
|
|
1133
|
-
document.addEventListener('click', this.documentClickListener, true);
|
|
1134
|
-
}, 10);
|
|
1066
|
+
setTimeout(() => document.addEventListener('click', this.documentClickListener, true), 10);
|
|
1135
1067
|
});
|
|
1136
1068
|
}
|
|
1137
1069
|
removeDocumentListener() {
|
|
@@ -1140,52 +1072,137 @@ class DateTimePicker {
|
|
|
1140
1072
|
this.documentClickListener = undefined;
|
|
1141
1073
|
}
|
|
1142
1074
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
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
|
+
}
|
|
1153
1086
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
const date = new Date(isoString);
|
|
1161
|
-
if (!isNaN(date.getTime())) {
|
|
1162
|
-
this.writeValue(date);
|
|
1163
|
-
this.onChange(isoString);
|
|
1164
|
-
}
|
|
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);
|
|
1165
1093
|
}
|
|
1166
1094
|
else {
|
|
1167
|
-
this.
|
|
1095
|
+
this.currentMonth.set(currentMonth + 1);
|
|
1168
1096
|
}
|
|
1169
1097
|
}
|
|
1170
|
-
|
|
1171
|
-
|
|
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: [
|
|
1172
1189
|
{
|
|
1173
1190
|
provide: NG_VALUE_ACCESSOR,
|
|
1174
|
-
useExisting: forwardRef(() =>
|
|
1191
|
+
useExisting: forwardRef(() => DateTimeFilter),
|
|
1175
1192
|
multi: true,
|
|
1176
1193
|
},
|
|
1177
|
-
], ngImport: i0, template: "<div class=\"datetime-container\">\r\n <div\r\n class=\"datetime-header\"\r\n [class.active]=\"isOpen()\"\r\n [class.disabled]=\"isDisabled()\"\r\n (click)=\"toggle()\"\r\n (keydown)=\"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)=\"onInputFocus()\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"isDisabled()\"\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)=\"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{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: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 }] });
|
|
1178
1195
|
}
|
|
1179
|
-
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: [{
|
|
1180
1197
|
type: Component,
|
|
1181
|
-
args: [{ selector: 'lib-date-time-
|
|
1198
|
+
args: [{ selector: 'lib-date-time-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule], providers: [
|
|
1182
1199
|
{
|
|
1183
1200
|
provide: NG_VALUE_ACCESSOR,
|
|
1184
|
-
useExisting: forwardRef(() =>
|
|
1201
|
+
useExisting: forwardRef(() => DateTimeFilter),
|
|
1185
1202
|
multi: true,
|
|
1186
1203
|
},
|
|
1187
|
-
], template: "<div class=\"datetime-container\">\r\n <div\r\n class=\"datetime-header\"\r\n [class.active]=\"isOpen()\"\r\n [class.disabled]=\"isDisabled()\"\r\n (click)=\"toggle()\"\r\n (keydown)=\"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)=\"onInputFocus()\"\r\n (click)=\"$event.stopPropagation()\"\r\n [disabled]=\"isDisabled()\"\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)=\"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{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: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"] }]
|
|
1188
|
-
}], 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 }] }] } });
|
|
1189
1206
|
|
|
1190
1207
|
class InputNumberFilter {
|
|
1191
1208
|
// Inputs
|
|
@@ -1255,8 +1272,8 @@ class InputNumberFilter {
|
|
|
1255
1272
|
this.onTouched();
|
|
1256
1273
|
}
|
|
1257
1274
|
}
|
|
1258
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1259
|
-
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: [
|
|
1260
1277
|
{
|
|
1261
1278
|
provide: NG_VALUE_ACCESSOR,
|
|
1262
1279
|
useExisting: forwardRef(() => InputNumberFilter),
|
|
@@ -1264,7 +1281,7 @@ class InputNumberFilter {
|
|
|
1264
1281
|
},
|
|
1265
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 }] });
|
|
1266
1283
|
}
|
|
1267
|
-
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: [{
|
|
1268
1285
|
type: Component,
|
|
1269
1286
|
args: [{ selector: 'lib-input-number-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule], providers: [
|
|
1270
1287
|
{
|
|
@@ -1469,8 +1486,8 @@ class InputSelectFilter {
|
|
|
1469
1486
|
this.documentClickListener = undefined;
|
|
1470
1487
|
}
|
|
1471
1488
|
}
|
|
1472
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1473
|
-
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: [
|
|
1474
1491
|
{
|
|
1475
1492
|
provide: NG_VALUE_ACCESSOR,
|
|
1476
1493
|
useExisting: forwardRef(() => InputSelectFilter),
|
|
@@ -1478,7 +1495,7 @@ class InputSelectFilter {
|
|
|
1478
1495
|
},
|
|
1479
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 }] });
|
|
1480
1497
|
}
|
|
1481
|
-
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: [{
|
|
1482
1499
|
type: Component,
|
|
1483
1500
|
args: [{ selector: 'lib-input-select-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule], providers: [
|
|
1484
1501
|
{
|
|
@@ -1575,8 +1592,8 @@ class InputTextFilter {
|
|
|
1575
1592
|
this.onTouched();
|
|
1576
1593
|
}
|
|
1577
1594
|
}
|
|
1578
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1579
|
-
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: [
|
|
1580
1597
|
{
|
|
1581
1598
|
provide: NG_VALUE_ACCESSOR,
|
|
1582
1599
|
useExisting: forwardRef(() => InputTextFilter),
|
|
@@ -1584,7 +1601,7 @@ class InputTextFilter {
|
|
|
1584
1601
|
},
|
|
1585
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 }] });
|
|
1586
1603
|
}
|
|
1587
|
-
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: [{
|
|
1588
1605
|
type: Component,
|
|
1589
1606
|
args: [{ selector: 'lib-input-text-filter', standalone: true, imports: [CommonModule, ReactiveFormsModule, FormsModule], providers: [
|
|
1590
1607
|
{
|
|
@@ -1595,6 +1612,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
1595
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"] }]
|
|
1596
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"] }] } });
|
|
1597
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
|
+
|
|
1598
1648
|
class SelectCustomSearch {
|
|
1599
1649
|
elementRef;
|
|
1600
1650
|
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
@@ -1604,6 +1654,8 @@ class SelectCustomSearch {
|
|
|
1604
1654
|
searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
1605
1655
|
selectedValue = signal(null, ...(ngDevMode ? [{ debugName: "selectedValue" }] : []));
|
|
1606
1656
|
isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
1657
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
1658
|
+
isBlocked = computed(() => this.isDisabled() || this.readonly(), ...(ngDevMode ? [{ debugName: "isBlocked" }] : []));
|
|
1607
1659
|
selectedOption = computed(() => {
|
|
1608
1660
|
const value = this.selectedValue();
|
|
1609
1661
|
return this.options().find((option) => option.value === value) || null;
|
|
@@ -1634,7 +1686,7 @@ class SelectCustomSearch {
|
|
|
1634
1686
|
this.isDisabled.set(isDisabled);
|
|
1635
1687
|
}
|
|
1636
1688
|
toggle() {
|
|
1637
|
-
if (this.
|
|
1689
|
+
if (this.isBlocked())
|
|
1638
1690
|
return;
|
|
1639
1691
|
if (this.isOpen()) {
|
|
1640
1692
|
this.close();
|
|
@@ -1644,7 +1696,7 @@ class SelectCustomSearch {
|
|
|
1644
1696
|
}
|
|
1645
1697
|
}
|
|
1646
1698
|
open() {
|
|
1647
|
-
if (this.
|
|
1699
|
+
if (this.isBlocked())
|
|
1648
1700
|
return;
|
|
1649
1701
|
this.isOpen.set(true);
|
|
1650
1702
|
this.searchTerm.set('');
|
|
@@ -1659,7 +1711,7 @@ class SelectCustomSearch {
|
|
|
1659
1711
|
this.searchTerm.set('');
|
|
1660
1712
|
}
|
|
1661
1713
|
selectOption(option) {
|
|
1662
|
-
if (this.
|
|
1714
|
+
if (this.isBlocked())
|
|
1663
1715
|
return;
|
|
1664
1716
|
this.selectedValue.set(option.value);
|
|
1665
1717
|
this.onChange(option.value);
|
|
@@ -1668,13 +1720,13 @@ class SelectCustomSearch {
|
|
|
1668
1720
|
this.close();
|
|
1669
1721
|
}
|
|
1670
1722
|
onSearch(event) {
|
|
1671
|
-
if (this.
|
|
1723
|
+
if (this.isBlocked())
|
|
1672
1724
|
return;
|
|
1673
1725
|
const target = event.target;
|
|
1674
1726
|
this.searchTerm.set(target.value);
|
|
1675
1727
|
}
|
|
1676
1728
|
onKeyDown(event) {
|
|
1677
|
-
if (this.
|
|
1729
|
+
if (this.isBlocked())
|
|
1678
1730
|
return;
|
|
1679
1731
|
if (event.key === 'Escape') {
|
|
1680
1732
|
this.close();
|
|
@@ -1687,20 +1739,20 @@ class SelectCustomSearch {
|
|
|
1687
1739
|
}
|
|
1688
1740
|
}
|
|
1689
1741
|
onDocumentClick(event) {
|
|
1690
|
-
if (!this.
|
|
1742
|
+
if (!this.isBlocked() && !this.elementRef.nativeElement.contains(event.target)) {
|
|
1691
1743
|
this.close();
|
|
1692
1744
|
}
|
|
1693
1745
|
}
|
|
1694
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1695
|
-
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: [
|
|
1696
1748
|
{
|
|
1697
1749
|
provide: NG_VALUE_ACCESSOR,
|
|
1698
1750
|
useExisting: forwardRef(() => SelectCustomSearch),
|
|
1699
1751
|
multi: true,
|
|
1700
1752
|
},
|
|
1701
|
-
], ngImport: i0, template: "<div class=\"select-container\">\r\n <div
|
|
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"] });
|
|
1702
1754
|
}
|
|
1703
|
-
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: [{
|
|
1704
1756
|
type: Component,
|
|
1705
1757
|
args: [{ selector: 'lib-select-custom-search', imports: [], providers: [
|
|
1706
1758
|
{
|
|
@@ -1708,8 +1760,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
1708
1760
|
useExisting: forwardRef(() => SelectCustomSearch),
|
|
1709
1761
|
multi: true,
|
|
1710
1762
|
},
|
|
1711
|
-
], template: "<div class=\"select-container\">\r\n <div
|
|
1712
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], onDocumentClick: [{
|
|
1763
|
+
], 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"] }]
|
|
1764
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], onDocumentClick: [{
|
|
1713
1765
|
type: HostListener,
|
|
1714
1766
|
args: ['document:click', ['$event']]
|
|
1715
1767
|
}] } });
|
|
@@ -1820,12 +1872,12 @@ class DynamicFormFields {
|
|
|
1820
1872
|
}
|
|
1821
1873
|
onCancel() {
|
|
1822
1874
|
}
|
|
1823
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1824
|
-
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"] }] });
|
|
1825
1877
|
}
|
|
1826
|
-
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: [{
|
|
1827
1879
|
type: Component,
|
|
1828
|
-
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
|
|
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"] }]
|
|
1829
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 }] }] } });
|
|
1830
1882
|
|
|
1831
1883
|
class WizardForm {
|
|
@@ -1863,10 +1915,10 @@ class WizardForm {
|
|
|
1863
1915
|
const index = this.currentStep() - 1;
|
|
1864
1916
|
return this.steps()[index].component;
|
|
1865
1917
|
}, ...(ngDevMode ? [{ debugName: "currentGroupComponent" }] : []));
|
|
1866
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1867
|
-
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"] }] });
|
|
1868
1920
|
}
|
|
1869
|
-
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: [{
|
|
1870
1922
|
type: Component,
|
|
1871
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"] }]
|
|
1872
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"] }] } });
|
|
@@ -1903,12 +1955,12 @@ class ModalForm {
|
|
|
1903
1955
|
submitForm() {
|
|
1904
1956
|
this.onSubmit.emit(this.form()?.value);
|
|
1905
1957
|
}
|
|
1906
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1907
|
-
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"] }] });
|
|
1908
1960
|
}
|
|
1909
|
-
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: [{
|
|
1910
1962
|
type: Component,
|
|
1911
|
-
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"] }]
|
|
1912
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"] }] } });
|
|
1913
1965
|
|
|
1914
1966
|
class DialogAlertComponent {
|
|
@@ -1978,43 +2030,44 @@ class DialogAlertComponent {
|
|
|
1978
2030
|
}
|
|
1979
2031
|
}
|
|
1980
2032
|
onConfirm() {
|
|
1981
|
-
console.log('onConfirm called', this.isReasonNeeded, this.form.value);
|
|
1982
|
-
// Si se requiere razón, no permitir confirmar con campo vacío
|
|
1983
2033
|
if (this.isReasonNeeded && !this.form.get('reason')?.value?.trim().length) {
|
|
1984
2034
|
return;
|
|
1985
2035
|
}
|
|
1986
|
-
// Emitir la razón (vacía => undefined)
|
|
1987
2036
|
const reason = this.form.get('reason')?.value;
|
|
1988
|
-
this.
|
|
2037
|
+
const observations = this.form.get('observations')?.value;
|
|
2038
|
+
this.confirmReason.emit({
|
|
2039
|
+
reason: reason || undefined,
|
|
2040
|
+
observations: observations || undefined,
|
|
2041
|
+
});
|
|
1989
2042
|
this.close.emit(true);
|
|
1990
2043
|
}
|
|
1991
2044
|
onCancel() {
|
|
1992
2045
|
this.close.emit(false);
|
|
1993
2046
|
}
|
|
1994
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1995
|
-
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"] }] });
|
|
1996
2049
|
}
|
|
1997
|
-
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: [{
|
|
1998
2051
|
type: Component,
|
|
1999
|
-
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"] }]
|
|
2000
2053
|
}], propDecorators: { title: [{
|
|
2001
|
-
type: Input
|
|
2054
|
+
type: Input$1
|
|
2002
2055
|
}], message: [{
|
|
2003
|
-
type: Input
|
|
2056
|
+
type: Input$1
|
|
2004
2057
|
}], type: [{
|
|
2005
|
-
type: Input
|
|
2058
|
+
type: Input$1
|
|
2006
2059
|
}], action: [{
|
|
2007
|
-
type: Input
|
|
2060
|
+
type: Input$1
|
|
2008
2061
|
}], showReason: [{
|
|
2009
|
-
type: Input
|
|
2062
|
+
type: Input$1
|
|
2010
2063
|
}], confirm: [{
|
|
2011
|
-
type: Input
|
|
2064
|
+
type: Input$1
|
|
2012
2065
|
}], confirmLabel: [{
|
|
2013
|
-
type: Input
|
|
2066
|
+
type: Input$1
|
|
2014
2067
|
}], close: [{
|
|
2015
2068
|
type: Output
|
|
2016
2069
|
}], reasonOptions: [{
|
|
2017
|
-
type: Input
|
|
2070
|
+
type: Input$1
|
|
2018
2071
|
}], confirmReason: [{
|
|
2019
2072
|
type: Output
|
|
2020
2073
|
}] } });
|
|
@@ -2036,24 +2089,195 @@ class DialogConfirmation {
|
|
|
2036
2089
|
onCancel() {
|
|
2037
2090
|
this.close.emit(false);
|
|
2038
2091
|
}
|
|
2039
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2040
|
-
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 }] });
|
|
2041
2094
|
}
|
|
2042
|
-
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: [{
|
|
2043
2096
|
type: Component,
|
|
2044
|
-
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"] }]
|
|
2045
2098
|
}], propDecorators: { title: [{
|
|
2046
|
-
type: Input
|
|
2099
|
+
type: Input$1
|
|
2047
2100
|
}], confirm: [{
|
|
2048
|
-
type: Input
|
|
2101
|
+
type: Input$1
|
|
2049
2102
|
}], confirmLabel: [{
|
|
2050
|
-
type: Input
|
|
2103
|
+
type: Input$1
|
|
2051
2104
|
}], items: [{
|
|
2052
|
-
type: Input
|
|
2105
|
+
type: Input$1
|
|
2053
2106
|
}], close: [{
|
|
2054
2107
|
type: Output
|
|
2055
2108
|
}] } });
|
|
2056
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
|
+
|
|
2057
2281
|
// src/app/components/public-api.ts
|
|
2058
2282
|
// Exportar el componente
|
|
2059
2283
|
|
|
@@ -2061,5 +2285,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
2061
2285
|
* Generated bundle index. Do not edit.
|
|
2062
2286
|
*/
|
|
2063
2287
|
|
|
2064
|
-
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 };
|
|
2065
2289
|
//# sourceMappingURL=sapenlinea-components.mjs.map
|