sapenlinea-components 0.0.9 → 0.0.11
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 +527 -11
- package/fesm2022/sapenlinea-components.mjs.map +1 -1
- package/index.d.ts +111 -6
- package/package.json +1 -1
|
@@ -1,16 +1,439 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { input, output, signal, computed, forwardRef, Component, EventEmitter, Output, Input, HostListener } from '@angular/core';
|
|
3
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
4
|
import * as i1 from '@angular/common';
|
|
4
5
|
import { CommonModule } from '@angular/common';
|
|
5
6
|
|
|
6
|
-
class
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
class DateTimeFilter {
|
|
8
|
+
elementRef;
|
|
9
|
+
ngZone;
|
|
10
|
+
mode = input('date', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
11
|
+
placeholder = input('Seleccionar fecha', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
12
|
+
minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : []));
|
|
13
|
+
maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
14
|
+
filter = input.required(...(ngDevMode ? [{ debugName: "filter" }] : []));
|
|
15
|
+
dateSelected = output();
|
|
16
|
+
filters = [
|
|
17
|
+
{ label: 'Fecha inicio', value: 'inicio', type: 'date' },
|
|
18
|
+
{ label: 'Fecha fin', value: 'fin', type: 'date' },
|
|
19
|
+
{ label: 'Fecha Nacimiento', value: 'born', type: 'date' },
|
|
20
|
+
];
|
|
21
|
+
dateChange = output();
|
|
22
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
23
|
+
selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : []));
|
|
24
|
+
isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
25
|
+
isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
|
|
26
|
+
// Navegación del calendario
|
|
27
|
+
currentMonth = signal(new Date().getMonth(), ...(ngDevMode ? [{ debugName: "currentMonth" }] : []));
|
|
28
|
+
currentYear = signal(new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "currentYear" }] : []));
|
|
29
|
+
// Hora en formato 24h (para el backend)
|
|
30
|
+
selectedHour = signal(0, ...(ngDevMode ? [{ debugName: "selectedHour" }] : []));
|
|
31
|
+
selectedMinute = signal(0, ...(ngDevMode ? [{ debugName: "selectedMinute" }] : []));
|
|
32
|
+
// Estado AM/PM
|
|
33
|
+
selectedAmPm = signal('AM', ...(ngDevMode ? [{ debugName: "selectedAmPm" }] : []));
|
|
34
|
+
documentClickListener;
|
|
35
|
+
showFilters = false;
|
|
36
|
+
showDatePicker = false;
|
|
37
|
+
activeFilterType = null;
|
|
38
|
+
selectDate(date) {
|
|
39
|
+
this.dateSelected.emit({
|
|
40
|
+
filter: this.filter(),
|
|
41
|
+
value: date
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
getDatePickerMode(type) {
|
|
45
|
+
switch (type) {
|
|
46
|
+
case 'date':
|
|
47
|
+
return 'date';
|
|
48
|
+
case 'datetime':
|
|
49
|
+
return 'datetime';
|
|
50
|
+
default:
|
|
51
|
+
return 'date';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
displayValue = computed(() => {
|
|
55
|
+
const date = this.selectedDate();
|
|
56
|
+
if (!date)
|
|
57
|
+
return '';
|
|
58
|
+
const options = {
|
|
59
|
+
day: '2-digit',
|
|
60
|
+
month: '2-digit',
|
|
61
|
+
year: 'numeric',
|
|
62
|
+
};
|
|
63
|
+
if (this.mode() === 'datetime') {
|
|
64
|
+
options.hour = '2-digit';
|
|
65
|
+
options.minute = '2-digit';
|
|
66
|
+
options.hour12 = true; // Cambiado a formato 12 horas
|
|
67
|
+
}
|
|
68
|
+
return date.toLocaleDateString('es-ES', options);
|
|
69
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
70
|
+
monthName = computed(() => {
|
|
71
|
+
const months = [
|
|
72
|
+
'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
|
|
73
|
+
'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'
|
|
74
|
+
];
|
|
75
|
+
return months[this.currentMonth()];
|
|
76
|
+
}, ...(ngDevMode ? [{ debugName: "monthName" }] : []));
|
|
77
|
+
calendarDays = computed(() => {
|
|
78
|
+
const year = this.currentYear();
|
|
79
|
+
const month = this.currentMonth();
|
|
80
|
+
const firstDay = new Date(year, month, 1);
|
|
81
|
+
const lastDay = new Date(year, month + 1, 0);
|
|
82
|
+
const daysInMonth = lastDay.getDate();
|
|
83
|
+
const startingDayOfWeek = firstDay.getDay();
|
|
84
|
+
const days = [];
|
|
85
|
+
// Días vacíos al inicio
|
|
86
|
+
for (let i = 0; i < startingDayOfWeek; i++) {
|
|
87
|
+
days.push(null);
|
|
88
|
+
}
|
|
89
|
+
// Días del mes
|
|
90
|
+
for (let day = 1; day <= daysInMonth; day++) {
|
|
91
|
+
days.push(day);
|
|
92
|
+
}
|
|
93
|
+
return days;
|
|
94
|
+
}, ...(ngDevMode ? [{ debugName: "calendarDays" }] : []));
|
|
95
|
+
// Horas en formato 12h
|
|
96
|
+
hours12 = computed(() => {
|
|
97
|
+
return Array.from({ length: 12 }, (_, i) => {
|
|
98
|
+
const hour12 = i === 0 ? 12 : i;
|
|
99
|
+
return {
|
|
100
|
+
value: hour12,
|
|
101
|
+
display: hour12.toString().padStart(2, '0')
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
}, ...(ngDevMode ? [{ debugName: "hours12" }] : []));
|
|
105
|
+
// Hora seleccionada en formato 12h
|
|
106
|
+
selectedHour12 = computed(() => {
|
|
107
|
+
const hour24 = this.selectedHour();
|
|
108
|
+
if (hour24 === 0)
|
|
109
|
+
return 12;
|
|
110
|
+
if (hour24 > 12)
|
|
111
|
+
return hour24 - 12;
|
|
112
|
+
return hour24;
|
|
113
|
+
}, ...(ngDevMode ? [{ debugName: "selectedHour12" }] : []));
|
|
114
|
+
minutes = computed(() => Array.from({ length: 60 }, (_, i) => i), ...(ngDevMode ? [{ debugName: "minutes" }] : []));
|
|
115
|
+
onChange = () => { };
|
|
116
|
+
onTouched = () => { };
|
|
117
|
+
constructor(elementRef, ngZone) {
|
|
118
|
+
this.elementRef = elementRef;
|
|
119
|
+
this.ngZone = ngZone;
|
|
120
|
+
}
|
|
121
|
+
ngOnDestroy() {
|
|
122
|
+
this.removeDocumentListener();
|
|
123
|
+
}
|
|
124
|
+
writeValue(value) {
|
|
125
|
+
let date = null;
|
|
126
|
+
if (value instanceof Date) {
|
|
127
|
+
date = value;
|
|
128
|
+
}
|
|
129
|
+
else if (typeof value === 'string' && value) {
|
|
130
|
+
// Manejar tanto fechas ISO como otros formatos de string
|
|
131
|
+
const parsedDate = new Date(value);
|
|
132
|
+
if (!isNaN(parsedDate.getTime())) {
|
|
133
|
+
date = parsedDate;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (date) {
|
|
137
|
+
this.selectedDate.set(date);
|
|
138
|
+
this.currentMonth.set(date.getMonth());
|
|
139
|
+
this.currentYear.set(date.getFullYear());
|
|
140
|
+
this.selectedHour.set(date.getHours());
|
|
141
|
+
this.selectedMinute.set(date.getMinutes());
|
|
142
|
+
this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
this.selectedDate.set(null);
|
|
146
|
+
// Valores por defecto
|
|
147
|
+
this.selectedHour.set(0);
|
|
148
|
+
this.selectedMinute.set(0);
|
|
149
|
+
this.selectedAmPm.set('AM');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
registerOnChange(fn) {
|
|
153
|
+
this.onChange = fn;
|
|
154
|
+
}
|
|
155
|
+
registerOnTouched(fn) {
|
|
156
|
+
this.onTouched = fn;
|
|
157
|
+
}
|
|
158
|
+
setDisabledState(isDisabled) {
|
|
159
|
+
this.isDisabled.set(isDisabled);
|
|
160
|
+
}
|
|
161
|
+
toggle() {
|
|
162
|
+
if (this.isDisabled())
|
|
163
|
+
return;
|
|
164
|
+
this.markAsTouched();
|
|
165
|
+
if (this.isOpen()) {
|
|
166
|
+
this.close();
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
this.open();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
open() {
|
|
173
|
+
if (this.isDisabled())
|
|
174
|
+
return;
|
|
175
|
+
this.markAsTouched();
|
|
176
|
+
this.isOpen.set(true);
|
|
177
|
+
this.addDocumentListener();
|
|
178
|
+
// Si hay fecha seleccionada, navegar a ese mes/año
|
|
179
|
+
const selected = this.selectedDate();
|
|
180
|
+
if (selected) {
|
|
181
|
+
this.currentMonth.set(selected.getMonth());
|
|
182
|
+
this.currentYear.set(selected.getFullYear());
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
close() {
|
|
186
|
+
this.isOpen.set(false);
|
|
187
|
+
this.removeDocumentListener();
|
|
188
|
+
this.markAsTouched();
|
|
189
|
+
}
|
|
190
|
+
selectDay(day) {
|
|
191
|
+
if (!day || this.isDisabled())
|
|
192
|
+
return;
|
|
193
|
+
const newDate = new Date(this.currentYear(), this.currentMonth(), day, this.selectedHour(), this.selectedMinute());
|
|
194
|
+
if (this.isDateDisabled(newDate))
|
|
195
|
+
return;
|
|
196
|
+
this.selectedDate.set(newDate);
|
|
197
|
+
this.onChange(newDate.toISOString());
|
|
198
|
+
this.markAsTouched();
|
|
199
|
+
this.dateChange.emit(newDate);
|
|
200
|
+
// Notificar selección de fecha al padre
|
|
201
|
+
this.dateSelected.emit({
|
|
202
|
+
filter: this.filter(),
|
|
203
|
+
value: newDate,
|
|
204
|
+
});
|
|
205
|
+
// Solo cerrar automáticamente si es modo 'date'
|
|
206
|
+
if (this.mode() === 'date') {
|
|
207
|
+
this.close();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
setHour12(hour12) {
|
|
211
|
+
if (this.isDisabled())
|
|
212
|
+
return;
|
|
213
|
+
// Convertir de 12h a 24h
|
|
214
|
+
let hour24;
|
|
215
|
+
const amPm = this.selectedAmPm();
|
|
216
|
+
if (hour12 === 12) {
|
|
217
|
+
hour24 = amPm === 'AM' ? 0 : 12;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
hour24 = amPm === 'AM' ? hour12 : hour12 + 12;
|
|
221
|
+
}
|
|
222
|
+
this.selectedHour.set(hour24);
|
|
223
|
+
this.updateDateTime();
|
|
224
|
+
}
|
|
225
|
+
setMinute(minute) {
|
|
226
|
+
if (this.isDisabled())
|
|
227
|
+
return;
|
|
228
|
+
this.selectedMinute.set(minute);
|
|
229
|
+
this.updateDateTime();
|
|
230
|
+
}
|
|
231
|
+
setAmPm(amPm) {
|
|
232
|
+
if (this.isDisabled())
|
|
233
|
+
return;
|
|
234
|
+
const currentHour24 = this.selectedHour();
|
|
235
|
+
const currentHour12 = this.selectedHour12();
|
|
236
|
+
let newHour24;
|
|
237
|
+
if (amPm === 'AM') {
|
|
238
|
+
newHour24 = currentHour12 === 12 ? 0 : currentHour12;
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
newHour24 = currentHour12 === 12 ? 12 : currentHour12 + 12;
|
|
242
|
+
}
|
|
243
|
+
this.selectedAmPm.set(amPm);
|
|
244
|
+
this.selectedHour.set(newHour24);
|
|
245
|
+
this.updateDateTime();
|
|
246
|
+
}
|
|
247
|
+
previousMonth() {
|
|
248
|
+
const currentMonth = this.currentMonth();
|
|
249
|
+
const currentYear = this.currentYear();
|
|
250
|
+
if (currentMonth === 0) {
|
|
251
|
+
this.currentMonth.set(11);
|
|
252
|
+
this.currentYear.set(currentYear - 1);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.currentMonth.set(currentMonth - 1);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
nextMonth() {
|
|
259
|
+
const currentMonth = this.currentMonth();
|
|
260
|
+
const currentYear = this.currentYear();
|
|
261
|
+
if (currentMonth === 11) {
|
|
262
|
+
this.currentMonth.set(0);
|
|
263
|
+
this.currentYear.set(currentYear + 1);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
this.currentMonth.set(currentMonth + 1);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
previousYear() {
|
|
270
|
+
this.currentYear.set(this.currentYear() - 1);
|
|
271
|
+
}
|
|
272
|
+
nextYear() {
|
|
273
|
+
this.currentYear.set(this.currentYear() + 1);
|
|
274
|
+
}
|
|
275
|
+
today() {
|
|
276
|
+
const today = new Date();
|
|
277
|
+
this.currentMonth.set(today.getMonth());
|
|
278
|
+
this.currentYear.set(today.getFullYear());
|
|
279
|
+
this.selectedDate.set(today);
|
|
280
|
+
this.selectedHour.set(today.getHours());
|
|
281
|
+
this.selectedMinute.set(today.getMinutes());
|
|
282
|
+
this.selectedAmPm.set(today.getHours() >= 12 ? 'PM' : 'AM');
|
|
283
|
+
this.onChange(today.toISOString());
|
|
284
|
+
this.markAsTouched();
|
|
285
|
+
this.dateChange.emit(today);
|
|
286
|
+
// Notificar selección de fecha al padre
|
|
287
|
+
this.dateSelected.emit({
|
|
288
|
+
filter: this.filter(),
|
|
289
|
+
value: today,
|
|
290
|
+
});
|
|
291
|
+
if (this.mode() === 'date') {
|
|
292
|
+
this.close();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
clear() {
|
|
296
|
+
this.selectedDate.set(null);
|
|
297
|
+
this.onChange(null);
|
|
298
|
+
this.markAsTouched();
|
|
299
|
+
this.dateChange.emit(null);
|
|
300
|
+
this.close();
|
|
301
|
+
}
|
|
302
|
+
onKeyDown(event) {
|
|
303
|
+
if (this.isDisabled())
|
|
304
|
+
return;
|
|
305
|
+
if (event.key === 'Escape') {
|
|
306
|
+
this.close();
|
|
307
|
+
}
|
|
308
|
+
else if (event.key === 'Tab') {
|
|
309
|
+
this.markAsTouched();
|
|
310
|
+
this.close();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
isDaySelected(day) {
|
|
314
|
+
if (!day)
|
|
315
|
+
return false;
|
|
316
|
+
const selected = this.selectedDate();
|
|
317
|
+
if (!selected)
|
|
318
|
+
return false;
|
|
319
|
+
return (selected.getDate() === day &&
|
|
320
|
+
selected.getMonth() === this.currentMonth() &&
|
|
321
|
+
selected.getFullYear() === this.currentYear());
|
|
322
|
+
}
|
|
323
|
+
isToday(day) {
|
|
324
|
+
if (!day)
|
|
325
|
+
return false;
|
|
326
|
+
const today = new Date();
|
|
327
|
+
return (today.getDate() === day &&
|
|
328
|
+
today.getMonth() === this.currentMonth() &&
|
|
329
|
+
today.getFullYear() === this.currentYear());
|
|
330
|
+
}
|
|
331
|
+
isDayDisabled(day) {
|
|
332
|
+
if (!day)
|
|
333
|
+
return true;
|
|
334
|
+
const date = new Date(this.currentYear(), this.currentMonth(), day);
|
|
335
|
+
return this.isDateDisabled(date);
|
|
336
|
+
}
|
|
337
|
+
isDateDisabled(date) {
|
|
338
|
+
const minDate = this.minDate();
|
|
339
|
+
const maxDate = this.maxDate();
|
|
340
|
+
if (minDate && date < minDate)
|
|
341
|
+
return true;
|
|
342
|
+
if (maxDate && date > maxDate)
|
|
343
|
+
return true;
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
updateDateTime() {
|
|
347
|
+
const selected = this.selectedDate();
|
|
348
|
+
if (!selected)
|
|
349
|
+
return;
|
|
350
|
+
const newDate = new Date(selected);
|
|
351
|
+
newDate.setHours(this.selectedHour());
|
|
352
|
+
newDate.setMinutes(this.selectedMinute());
|
|
353
|
+
this.selectedDate.set(newDate);
|
|
354
|
+
this.onChange(newDate.toISOString());
|
|
355
|
+
this.markAsTouched();
|
|
356
|
+
this.dateChange.emit(newDate);
|
|
357
|
+
}
|
|
358
|
+
markAsTouched() {
|
|
359
|
+
if (!this.isTouched()) {
|
|
360
|
+
this.isTouched.set(true);
|
|
361
|
+
this.onTouched();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
addDocumentListener() {
|
|
365
|
+
if (this.documentClickListener) {
|
|
366
|
+
this.removeDocumentListener();
|
|
367
|
+
}
|
|
368
|
+
this.ngZone.runOutsideAngular(() => {
|
|
369
|
+
this.documentClickListener = (event) => {
|
|
370
|
+
const target = event.target;
|
|
371
|
+
if (!this.elementRef.nativeElement.contains(target)) {
|
|
372
|
+
this.ngZone.run(() => {
|
|
373
|
+
if (this.isOpen()) {
|
|
374
|
+
this.markAsTouched();
|
|
375
|
+
this.close();
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
setTimeout(() => {
|
|
381
|
+
document.addEventListener('click', this.documentClickListener, true);
|
|
382
|
+
}, 10);
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
removeDocumentListener() {
|
|
386
|
+
if (this.documentClickListener) {
|
|
387
|
+
document.removeEventListener('click', this.documentClickListener, true);
|
|
388
|
+
this.documentClickListener = undefined;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
markTouched() {
|
|
392
|
+
this.markAsTouched();
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Obtiene la fecha seleccionada en formato ISO string
|
|
396
|
+
* @returns string ISO o null si no hay fecha seleccionada
|
|
397
|
+
*/
|
|
398
|
+
getISOString() {
|
|
399
|
+
const date = this.selectedDate();
|
|
400
|
+
return date ? date.toISOString() : null;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Establece la fecha desde un string ISO
|
|
404
|
+
* @param isoString - Fecha en formato ISO
|
|
405
|
+
*/
|
|
406
|
+
setFromISOString(isoString) {
|
|
407
|
+
if (isoString) {
|
|
408
|
+
const date = new Date(isoString);
|
|
409
|
+
if (!isNaN(date.getTime())) {
|
|
410
|
+
this.writeValue(date);
|
|
411
|
+
this.onChange(isoString);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
this.clear();
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: DateTimeFilter, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
419
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: DateTimeFilter, isStandalone: true, selector: "app-date-time-filter", 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 }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dateSelected: "dateSelected", dateChange: "dateChange" }, providers: [
|
|
420
|
+
{
|
|
421
|
+
provide: NG_VALUE_ACCESSOR,
|
|
422
|
+
useExisting: forwardRef(() => DateTimeFilter),
|
|
423
|
+
multi: true,
|
|
424
|
+
},
|
|
425
|
+
], ngImport: i0, template: "<div class=\"datetime-container\">\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 -->\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 -->\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", styles: [".datetime-container{position:relative;width:100%}.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"] });
|
|
9
426
|
}
|
|
10
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type:
|
|
427
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: DateTimeFilter, decorators: [{
|
|
11
428
|
type: Component,
|
|
12
|
-
args: [{ selector: '
|
|
13
|
-
|
|
429
|
+
args: [{ selector: 'app-date-time-filter', standalone: true, imports: [], providers: [
|
|
430
|
+
{
|
|
431
|
+
provide: NG_VALUE_ACCESSOR,
|
|
432
|
+
useExisting: forwardRef(() => DateTimeFilter),
|
|
433
|
+
multi: true,
|
|
434
|
+
},
|
|
435
|
+
], template: "<div class=\"datetime-container\">\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 -->\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 -->\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", styles: [".datetime-container{position:relative;width:100%}.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"] }]
|
|
436
|
+
}], 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 }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: true }] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
|
|
14
437
|
|
|
15
438
|
class PaginationComponent {
|
|
16
439
|
page = 1;
|
|
@@ -75,8 +498,11 @@ class Table {
|
|
|
75
498
|
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
76
499
|
data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
77
500
|
actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
|
|
501
|
+
showActions = input(true, ...(ngDevMode ? [{ debugName: "showActions" }] : []));
|
|
78
502
|
openedMenu = signal(null, ...(ngDevMode ? [{ debugName: "openedMenu" }] : []));
|
|
79
503
|
selectedRow = signal(null, ...(ngDevMode ? [{ debugName: "selectedRow" }] : []));
|
|
504
|
+
sortColumn = signal(null, ...(ngDevMode ? [{ debugName: "sortColumn" }] : []));
|
|
505
|
+
sortDirection = signal('desc', ...(ngDevMode ? [{ debugName: "sortDirection" }] : []));
|
|
80
506
|
optionSelected = output();
|
|
81
507
|
toggleMenu(index) {
|
|
82
508
|
this.openedMenu.set(this.openedMenu() === index ? null : index);
|
|
@@ -100,13 +526,103 @@ class Table {
|
|
|
100
526
|
this.selectedRow.set(null);
|
|
101
527
|
}
|
|
102
528
|
}
|
|
529
|
+
getAlignment(col) {
|
|
530
|
+
if (col.align && col.align !== 'auto')
|
|
531
|
+
return col.align;
|
|
532
|
+
switch (col.type) {
|
|
533
|
+
case 'number':
|
|
534
|
+
case 'money':
|
|
535
|
+
case 'percentage':
|
|
536
|
+
return 'right';
|
|
537
|
+
case 'status':
|
|
538
|
+
return 'center';
|
|
539
|
+
default:
|
|
540
|
+
return 'left';
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
formatValue(col, value) {
|
|
544
|
+
if (value === null || value === undefined)
|
|
545
|
+
return '';
|
|
546
|
+
switch (col.type) {
|
|
547
|
+
case 'money':
|
|
548
|
+
return new Intl.NumberFormat('es-CO', {
|
|
549
|
+
style: 'currency',
|
|
550
|
+
currency: 'COP',
|
|
551
|
+
minimumFractionDigits: 0
|
|
552
|
+
}).format(value);
|
|
553
|
+
case 'number':
|
|
554
|
+
return new Intl.NumberFormat('es-CO').format(value);
|
|
555
|
+
case 'percentage':
|
|
556
|
+
return `${value}%`;
|
|
557
|
+
case 'date':
|
|
558
|
+
const d = new Date(value);
|
|
559
|
+
if (isNaN(d.getTime()))
|
|
560
|
+
return value;
|
|
561
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
562
|
+
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
563
|
+
const year = d.getFullYear();
|
|
564
|
+
return `${day}/${month}/${year}`;
|
|
565
|
+
default:
|
|
566
|
+
return String(value);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
getStatusStyle(value) {
|
|
570
|
+
const map = {
|
|
571
|
+
aprobado: { bg: '#E6F4EA', color: '#1E8E3E' }, // verde
|
|
572
|
+
pendiente: { bg: '#FFF4E5', color: '#E67E22' }, // naranja
|
|
573
|
+
rechazado: { bg: '#FCE8E6', color: '#D93025' }, // rojo
|
|
574
|
+
en_proceso: { bg: '#E8F0FE', color: '#1967D2' }, // azul
|
|
575
|
+
};
|
|
576
|
+
const key = value?.toString().toLowerCase()?.replace(/\s+/g, '_');
|
|
577
|
+
return map[key] || { bg: '#F4F4F4', color: '#5F6368' }; // default gris
|
|
578
|
+
}
|
|
579
|
+
sortData() {
|
|
580
|
+
const col = this.sortColumn();
|
|
581
|
+
if (!col)
|
|
582
|
+
return this.data();
|
|
583
|
+
const dir = this.sortDirection();
|
|
584
|
+
return [...this.data()].sort((a, b) => {
|
|
585
|
+
const x = a[col] ?? '';
|
|
586
|
+
const y = b[col] ?? '';
|
|
587
|
+
// Caso: fechas
|
|
588
|
+
if (this.isDate(x) && this.isDate(y)) {
|
|
589
|
+
return dir === 'asc'
|
|
590
|
+
? new Date(x).getTime() - new Date(y).getTime()
|
|
591
|
+
: new Date(y).getTime() - new Date(x).getTime();
|
|
592
|
+
}
|
|
593
|
+
// Caso: números
|
|
594
|
+
if (!isNaN(Number(x)) && !isNaN(Number(y))) {
|
|
595
|
+
return dir === 'asc' ? Number(x) - Number(y) : Number(y) - Number(x);
|
|
596
|
+
}
|
|
597
|
+
// Caso: strings
|
|
598
|
+
return dir === 'asc'
|
|
599
|
+
? x.toString().localeCompare(y.toString())
|
|
600
|
+
: y.toString().localeCompare(x.toString());
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
isDate(value) {
|
|
604
|
+
return (typeof value === 'string' &&
|
|
605
|
+
value.length > 5 &&
|
|
606
|
+
!isNaN(Date.parse(value)));
|
|
607
|
+
}
|
|
608
|
+
onSort(col) {
|
|
609
|
+
if (this.sortColumn() === col.key) {
|
|
610
|
+
// cambiar asc <-> desc
|
|
611
|
+
this.sortDirection.set(this.sortDirection() === 'asc' ? 'desc' : 'asc');
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
// nueva columna → empieza en desc (más reciente primero)
|
|
615
|
+
this.sortColumn.set(col.key);
|
|
616
|
+
this.sortDirection.set('desc');
|
|
617
|
+
}
|
|
618
|
+
}
|
|
103
619
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: Table, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
104
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", 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 } }, outputs: { optionSelected: "optionSelected" }, 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
|
|
620
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", 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 } }, outputs: { optionSelected: "optionSelected" }, 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 >\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\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 { {{ 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 actions(); 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}.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}.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-trash{width:24px;height:24px;background-color:currentColor;color:currentColor}.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-trash{-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>')}td.left{text-align:left}td.right{text-align:right}td.center{text-align:center}.status-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:8px;font-size:13px;font-weight:500}.status-dot{width:8px;height:8px;border-radius:50%;display:inline-block}.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"] });
|
|
105
621
|
}
|
|
106
622
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: Table, decorators: [{
|
|
107
623
|
type: Component,
|
|
108
|
-
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
|
|
109
|
-
}], 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 }] }], optionSelected: [{ type: i0.Output, args: ["optionSelected"] }], onClickOutside: [{
|
|
624
|
+
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 >\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\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 { {{ 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 actions(); 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}.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}.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-trash{width:24px;height:24px;background-color:currentColor;color:currentColor}.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-trash{-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>')}td.left{text-align:left}td.right{text-align:right}td.center{text-align:center}.status-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:8px;font-size:13px;font-weight:500}.status-dot{width:8px;height:8px;border-radius:50%;display:inline-block}.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"] }]
|
|
625
|
+
}], 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"] }], onClickOutside: [{
|
|
110
626
|
type: HostListener,
|
|
111
627
|
args: ['document:click', ['$event']]
|
|
112
628
|
}] } });
|
|
@@ -118,5 +634,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
|
|
|
118
634
|
* Generated bundle index. Do not edit.
|
|
119
635
|
*/
|
|
120
636
|
|
|
121
|
-
export {
|
|
637
|
+
export { DateTimeFilter, PaginationComponent, Table };
|
|
122
638
|
//# sourceMappingURL=sapenlinea-components.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sapenlinea-components.mjs","sources":["../../../projects/sapenlinea-components/src/lib/components/my-component/my-component.ts","../../../projects/sapenlinea-components/src/lib/components/my-component/my-component.html","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.ts","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.html","../../../projects/sapenlinea-components/src/lib/components/table/table.ts","../../../projects/sapenlinea-components/src/lib/components/table/table.html","../../../projects/sapenlinea-components/src/public-api.ts","../../../projects/sapenlinea-components/src/sapenlinea-components.ts"],"sourcesContent":["import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'lib-my-component',\r\n imports: [],\r\n templateUrl: './my-component.html',\r\n styleUrl: './my-component.css',\r\n})\r\nexport class MyComponent {\r\n\r\n}\r\n","<p>my-component works!</p>\r\n","import { Component, Input, Output, EventEmitter, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'app-pagination',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './pagination.html',\r\n styleUrls: ['./pagination.css']\r\n})\r\nexport class PaginationComponent {\r\n @Input() page = 1;\r\n @Input() pageSize = 10;\r\n @Input() totalItems = 0;\r\n\r\n @Input() showPageSizeSelector = false;\r\n @Input() pageSizeOptions: number[] = [5, 10, 20, 50];\r\n\r\n @Output() pageChange = new EventEmitter<number>();\r\n @Output() pageSizeChange = new EventEmitter<number>();\r\n\r\n pageSizeValue = signal(this.pageSize);\r\n isOpen = signal(false);\r\n isDisabled = signal(false);\r\n showPageSizeMenu = signal(false);\r\n\r\n totalPages = computed(() => {\r\n const size = this.pageSizeValue();\r\n const total = this.totalItems;\r\n return size > 0 ? Math.ceil(total / size) : 1;\r\n });\r\n\r\n pages = computed(() => {\r\n const tp = this.totalPages();\r\n return Array.from({ length: tp }, (_, i) => i + 1);\r\n });\r\n\r\n selectedPageSize = computed(() => this.pageSizeValue());\r\n\r\n goToPage(p: number) {\r\n if (p < 1 || p > this.totalPages()) return;\r\n this.pageChange.emit(p);\r\n }\r\n\r\n togglePageSizeMenu() {\r\n this.isOpen.update(v => !v);\r\n this.showPageSizeMenu.update(v => !v);\r\n }\r\n\r\n selectPageSize(size: number) {\r\n this.pageSizeValue.set(size);\r\n this.pageSizeChange.emit(size);\r\n this.showPageSizeMenu.set(false);\r\n this.isOpen.set(false);\r\n }\r\n}\r\n","<div class=\"pagination-container\">\r\n <div class=\"pagination\">\r\n <!-- Botón doble atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(1)\" [disabled]=\"page === 1\">\r\n ««\r\n </button>\r\n\r\n <!-- Botón atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page - 1)\" [disabled]=\"page === 1\">\r\n «\r\n </button>\r\n\r\n <!-- Números de página -->\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ón siguiente -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page + 1)\" [disabled]=\"page === totalPages()\">\r\n »\r\n </button>\r\n\r\n <!-- Botón doble adelante -->\r\n <button class=\"icon-button\" (click)=\"goToPage(totalPages())\" [disabled]=\"page === totalPages()\">\r\n »»\r\n </button>\r\n </div>\r\n\r\n <!-- Selector Items por página -->\r\n <div *ngIf=\"showPageSizeSelector\">\r\n <div class=\"pagination-v-4\">\r\n <div class=\"label-pagination\">Items por página</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ú 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","import { Component, HostListener, input, output, signal } from '@angular/core';\r\nimport { TableAction, TableColumn, TableRow } from '../../interfaces/table';\r\n\r\n@Component({\r\n selector: 'lib-table',\r\n imports: [],\r\n standalone: true,\r\n templateUrl: './table.html',\r\n styleUrl: './table.css',\r\n})\r\nexport class Table {\r\n columns = input<TableColumn[]>([]);\r\n data = input<TableRow[]>([]);\r\n actions = input<TableAction[]>([]);\r\n\r\n openedMenu = signal<number | null>(null);\r\n selectedRow = signal<TableRow | null>(null);\r\n \r\n optionSelected = output<{ action: string; row: TableRow }>();\r\n\r\n toggleMenu(index: number) {\r\n this.openedMenu.set(this.openedMenu() === index ? null : index);\r\n }\r\n\r\n onOptionClick(option: TableAction, row: TableRow) {\r\n this.optionSelected.emit({ action: option.label, row });\r\n this.openedMenu.set(null);\r\n }\r\n\r\n openModal(row: TableRow, event?: MouseEvent) {\r\n event?.stopPropagation();\r\n\r\n if (this.selectedRow()?.['id'] === row['id']) {\r\n this.selectedRow.set(null);\r\n } else {\r\n this.selectedRow.set(row);\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onClickOutside(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n if (!target.closest('.menu-acciones')) {\r\n this.selectedRow.set(null);\r\n }\r\n }\r\n}\r\n","<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>{{ col.label }}</th>\r\n }\r\n\r\n <!-- columna para acciones -->\r\n <th></th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of data(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td>{{ row[col.key] }}</td>\r\n }\r\n\r\n <!-- Celda de acciones -->\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 \r\n <div class=\"modal-content\">\r\n <ul>\r\n @for (option of actions(); 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 \r\n </div>\r\n }\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>","// src/app/components/public-api.ts\r\n\r\n// Exportar el componente\r\nexport * from './lib/components/my-component/my-component';\r\nexport * from './lib/components/pagination/pagination';\r\nexport * from './lib/components/table/table';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sapenlinea-components.mjs","sources":["../../../projects/sapenlinea-components/src/lib/components/date-time-filter/date-time-filter.ts","../../../projects/sapenlinea-components/src/lib/components/date-time-filter/date-time-filter.html","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.ts","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.html","../../../projects/sapenlinea-components/src/lib/components/table/table.ts","../../../projects/sapenlinea-components/src/lib/components/table/table.html","../../../projects/sapenlinea-components/src/public-api.ts","../../../projects/sapenlinea-components/src/sapenlinea-components.ts"],"sourcesContent":["import {\r\n Component,\r\n computed,\r\n ElementRef,\r\n input,\r\n output,\r\n signal,\r\n forwardRef,\r\n OnDestroy,\r\n NgZone,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';\r\n\r\nexport interface FilterOption {\r\n label: string;\r\n value: string;\r\n type: 'date';\r\n}\r\n\r\nexport interface DateFilterSelection {\r\n filter: string;\r\n value: Date;\r\n}\r\n\r\nexport type DateTimeMode = 'date' | 'datetime';\r\n\r\ninterface Hour12 {\r\n value: number;\r\n display: string;\r\n}\r\n\r\nexport type FilterType = DateTimeMode;\r\n\r\n@Component({\r\n selector: 'app-date-time-filter',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './date-time-filter.html',\r\n styleUrl: './date-time-filter.css',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => DateTimeFilter),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class DateTimeFilter implements ControlValueAccessor, OnDestroy {\r\n mode = input<DateTimeMode>('date');\r\n placeholder = input<string>('Seleccionar fecha');\r\n minDate = input<Date | null>(null);\r\n maxDate = input<Date | null>(null);\r\n filter = input.required<string>();\r\n dateSelected = output<DateFilterSelection>();\r\n\r\n filters: FilterOption[] = [\r\n { label: 'Fecha inicio', value: 'inicio', type: 'date' },\r\n { label: 'Fecha fin', value: 'fin', type: 'date' },\r\n { label: 'Fecha Nacimiento', value: 'born', type: 'date' },\r\n ];\r\n\r\n dateChange = output<Date | null>();\r\n\r\n isOpen = signal(false);\r\n selectedDate = signal<Date | null>(null);\r\n isDisabled = signal(false);\r\n isTouched = signal(false);\r\n\r\n // Navegación del calendario\r\n currentMonth = signal(new Date().getMonth());\r\n currentYear = signal(new Date().getFullYear());\r\n\r\n // Hora en formato 24h (para el backend)\r\n selectedHour = signal(0);\r\n selectedMinute = signal(0);\r\n\r\n // Estado AM/PM\r\n selectedAmPm = signal<'AM' | 'PM'>('AM');\r\n\r\n private documentClickListener?: (event: Event) => void;\r\n\r\n showFilters = false;\r\n showDatePicker = false;\r\n activeFilterType: string | null = null;\r\n\r\n selectDate(date: Date): void {\r\n this.dateSelected.emit({\r\n filter: this.filter(),\r\n value: date\r\n });\r\n }\r\n\r\n getDatePickerMode(type: FilterType): DateTimeMode {\r\n switch (type) {\r\n case 'date':\r\n return 'date';\r\n case 'datetime':\r\n return 'datetime';\r\n default:\r\n return 'date';\r\n }\r\n }\r\n\r\n displayValue = computed(() => {\r\n const date = this.selectedDate();\r\n if (!date) return '';\r\n\r\n const options: Intl.DateTimeFormatOptions = {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n };\r\n\r\n if (this.mode() === 'datetime') {\r\n options.hour = '2-digit';\r\n options.minute = '2-digit';\r\n options.hour12 = true; // Cambiado a formato 12 horas\r\n }\r\n\r\n return date.toLocaleDateString('es-ES', options);\r\n });\r\n\r\n monthName = computed(() => {\r\n const months = [\r\n 'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',\r\n 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'\r\n ];\r\n return months[this.currentMonth()];\r\n });\r\n\r\n calendarDays = computed(() => {\r\n const year = this.currentYear();\r\n const month = this.currentMonth();\r\n const firstDay = new Date(year, month, 1);\r\n const lastDay = new Date(year, month + 1, 0);\r\n const daysInMonth = lastDay.getDate();\r\n const startingDayOfWeek = firstDay.getDay();\r\n\r\n const days: (number | null)[] = [];\r\n\r\n // Días vacíos al inicio\r\n for (let i = 0; i < startingDayOfWeek; i++) {\r\n days.push(null);\r\n }\r\n\r\n // Días del mes\r\n for (let day = 1; day <= daysInMonth; day++) {\r\n days.push(day);\r\n }\r\n\r\n return days;\r\n });\r\n\r\n // Horas en formato 12h\r\n hours12 = computed((): Hour12[] => {\r\n return Array.from({ length: 12 }, (_, i) => {\r\n const hour12 = i === 0 ? 12 : i;\r\n return {\r\n value: hour12,\r\n display: hour12.toString().padStart(2, '0')\r\n };\r\n });\r\n });\r\n\r\n // Hora seleccionada en formato 12h\r\n selectedHour12 = computed(() => {\r\n const hour24 = this.selectedHour();\r\n if (hour24 === 0) return 12;\r\n if (hour24 > 12) return hour24 - 12;\r\n return hour24;\r\n });\r\n\r\n minutes = computed(() => Array.from({ length: 60 }, (_, i) => i));\r\n\r\n private onChange: (value: string | null) => void = () => { };\r\n private onTouched: () => void = () => { };\r\n\r\n constructor(private elementRef: ElementRef, private ngZone: NgZone) { }\r\n\r\n ngOnDestroy() {\r\n this.removeDocumentListener();\r\n }\r\n\r\n writeValue(value: string | Date | null): void {\r\n let date: Date | null = null;\r\n\r\n if (value instanceof Date) {\r\n date = value;\r\n } else if (typeof value === 'string' && value) {\r\n // Manejar tanto fechas ISO como otros formatos de string\r\n const parsedDate = new Date(value);\r\n if (!isNaN(parsedDate.getTime())) {\r\n date = parsedDate;\r\n }\r\n }\r\n\r\n if (date) {\r\n this.selectedDate.set(date);\r\n this.currentMonth.set(date.getMonth());\r\n this.currentYear.set(date.getFullYear());\r\n this.selectedHour.set(date.getHours());\r\n this.selectedMinute.set(date.getMinutes());\r\n this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');\r\n } else {\r\n this.selectedDate.set(null);\r\n // Valores por defecto\r\n this.selectedHour.set(0);\r\n this.selectedMinute.set(0);\r\n this.selectedAmPm.set('AM');\r\n }\r\n }\r\n\r\n registerOnChange(fn: (value: string | null) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this.isDisabled.set(isDisabled);\r\n }\r\n\r\n toggle() {\r\n if (this.isDisabled()) return;\r\n\r\n this.markAsTouched();\r\n\r\n if (this.isOpen()) {\r\n this.close();\r\n } else {\r\n this.open();\r\n }\r\n }\r\n\r\n open() {\r\n if (this.isDisabled()) return;\r\n\r\n this.markAsTouched();\r\n this.isOpen.set(true);\r\n this.addDocumentListener();\r\n\r\n // Si hay fecha seleccionada, navegar a ese mes/año\r\n const selected = this.selectedDate();\r\n if (selected) {\r\n this.currentMonth.set(selected.getMonth());\r\n this.currentYear.set(selected.getFullYear());\r\n }\r\n }\r\n\r\n close() {\r\n this.isOpen.set(false);\r\n this.removeDocumentListener();\r\n this.markAsTouched();\r\n }\r\n\r\n selectDay(day: number | null) {\r\n if (!day || this.isDisabled()) return;\r\n\r\n const newDate = new Date(\r\n this.currentYear(),\r\n this.currentMonth(),\r\n day,\r\n this.selectedHour(),\r\n this.selectedMinute()\r\n );\r\n\r\n if (this.isDateDisabled(newDate)) return;\r\n\r\n this.selectedDate.set(newDate);\r\n this.onChange(newDate.toISOString());\r\n this.markAsTouched();\r\n this.dateChange.emit(newDate);\r\n\r\n // Notificar selección de fecha al padre\r\n this.dateSelected.emit({\r\n filter: this.filter(),\r\n value: newDate,\r\n });\r\n\r\n // Solo cerrar automáticamente si es modo 'date'\r\n if (this.mode() === 'date') {\r\n this.close();\r\n }\r\n }\r\n\r\n setHour12(hour12: number) {\r\n if (this.isDisabled()) return;\r\n\r\n // Convertir de 12h a 24h\r\n let hour24: number;\r\n const amPm = this.selectedAmPm();\r\n\r\n if (hour12 === 12) {\r\n hour24 = amPm === 'AM' ? 0 : 12;\r\n } else {\r\n hour24 = amPm === 'AM' ? hour12 : hour12 + 12;\r\n }\r\n\r\n this.selectedHour.set(hour24);\r\n this.updateDateTime();\r\n }\r\n\r\n setMinute(minute: number) {\r\n if (this.isDisabled()) return;\r\n\r\n this.selectedMinute.set(minute);\r\n this.updateDateTime();\r\n }\r\n\r\n setAmPm(amPm: 'AM' | 'PM') {\r\n if (this.isDisabled()) return;\r\n\r\n const currentHour24 = this.selectedHour();\r\n const currentHour12 = this.selectedHour12();\r\n let newHour24: number;\r\n\r\n if (amPm === 'AM') {\r\n newHour24 = currentHour12 === 12 ? 0 : currentHour12;\r\n } else {\r\n newHour24 = currentHour12 === 12 ? 12 : currentHour12 + 12;\r\n }\r\n\r\n this.selectedAmPm.set(amPm);\r\n this.selectedHour.set(newHour24);\r\n this.updateDateTime();\r\n }\r\n\r\n previousMonth() {\r\n const currentMonth = this.currentMonth();\r\n const currentYear = this.currentYear();\r\n\r\n if (currentMonth === 0) {\r\n this.currentMonth.set(11);\r\n this.currentYear.set(currentYear - 1);\r\n } else {\r\n this.currentMonth.set(currentMonth - 1);\r\n }\r\n }\r\n\r\n nextMonth() {\r\n const currentMonth = this.currentMonth();\r\n const currentYear = this.currentYear();\r\n\r\n if (currentMonth === 11) {\r\n this.currentMonth.set(0);\r\n this.currentYear.set(currentYear + 1);\r\n } else {\r\n this.currentMonth.set(currentMonth + 1);\r\n }\r\n }\r\n\r\n previousYear() {\r\n this.currentYear.set(this.currentYear() - 1);\r\n }\r\n\r\n nextYear() {\r\n this.currentYear.set(this.currentYear() + 1);\r\n }\r\n\r\n today() {\r\n const today = new Date();\r\n this.currentMonth.set(today.getMonth());\r\n this.currentYear.set(today.getFullYear());\r\n this.selectedDate.set(today);\r\n this.selectedHour.set(today.getHours());\r\n this.selectedMinute.set(today.getMinutes());\r\n this.selectedAmPm.set(today.getHours() >= 12 ? 'PM' : 'AM');\r\n this.onChange(today.toISOString());\r\n this.markAsTouched();\r\n this.dateChange.emit(today);\r\n\r\n // Notificar selección de fecha al padre\r\n this.dateSelected.emit({\r\n filter: this.filter(),\r\n value: today,\r\n });\r\n\r\n if (this.mode() === 'date') {\r\n this.close();\r\n }\r\n }\r\n\r\n clear() {\r\n this.selectedDate.set(null);\r\n this.onChange(null);\r\n this.markAsTouched();\r\n this.dateChange.emit(null);\r\n this.close();\r\n }\r\n\r\n onKeyDown(event: KeyboardEvent) {\r\n if (this.isDisabled()) return;\r\n\r\n if (event.key === 'Escape') {\r\n this.close();\r\n } else if (event.key === 'Tab') {\r\n this.markAsTouched();\r\n this.close();\r\n }\r\n }\r\n\r\n isDaySelected(day: number | null): boolean {\r\n if (!day) return false;\r\n const selected = this.selectedDate();\r\n if (!selected) return false;\r\n\r\n return (\r\n selected.getDate() === day &&\r\n selected.getMonth() === this.currentMonth() &&\r\n selected.getFullYear() === this.currentYear()\r\n );\r\n }\r\n\r\n isToday(day: number | null): boolean {\r\n if (!day) return false;\r\n const today = new Date();\r\n return (\r\n today.getDate() === day &&\r\n today.getMonth() === this.currentMonth() &&\r\n today.getFullYear() === this.currentYear()\r\n );\r\n }\r\n\r\n isDayDisabled(day: number | null): boolean {\r\n if (!day) return true;\r\n\r\n const date = new Date(this.currentYear(), this.currentMonth(), day);\r\n return this.isDateDisabled(date);\r\n }\r\n\r\n isDateDisabled(date: Date): boolean {\r\n const minDate = this.minDate();\r\n const maxDate = this.maxDate();\r\n\r\n if (minDate && date < minDate) return true;\r\n if (maxDate && date > maxDate) return true;\r\n\r\n return false;\r\n }\r\n\r\n private updateDateTime() {\r\n const selected = this.selectedDate();\r\n if (!selected) return;\r\n\r\n const newDate = new Date(selected);\r\n newDate.setHours(this.selectedHour());\r\n newDate.setMinutes(this.selectedMinute());\r\n\r\n this.selectedDate.set(newDate);\r\n this.onChange(newDate.toISOString());\r\n this.markAsTouched();\r\n this.dateChange.emit(newDate);\r\n }\r\n\r\n private markAsTouched() {\r\n if (!this.isTouched()) {\r\n this.isTouched.set(true);\r\n this.onTouched();\r\n }\r\n }\r\n\r\n private addDocumentListener() {\r\n if (this.documentClickListener) {\r\n this.removeDocumentListener();\r\n }\r\n\r\n this.ngZone.runOutsideAngular(() => {\r\n this.documentClickListener = (event: Event) => {\r\n const target = event.target as Node;\r\n if (!this.elementRef.nativeElement.contains(target)) {\r\n this.ngZone.run(() => {\r\n if (this.isOpen()) {\r\n this.markAsTouched();\r\n this.close();\r\n }\r\n });\r\n }\r\n };\r\n\r\n setTimeout(() => {\r\n document.addEventListener('click', this.documentClickListener!, true);\r\n }, 10);\r\n });\r\n }\r\n\r\n private removeDocumentListener() {\r\n if (this.documentClickListener) {\r\n document.removeEventListener('click', this.documentClickListener, true);\r\n this.documentClickListener = undefined;\r\n }\r\n }\r\n\r\n public markTouched() {\r\n this.markAsTouched();\r\n }\r\n\r\n /**\r\n * Obtiene la fecha seleccionada en formato ISO string\r\n * @returns string ISO o null si no hay fecha seleccionada\r\n */\r\n public getISOString(): string | null {\r\n const date = this.selectedDate();\r\n return date ? date.toISOString() : null;\r\n }\r\n\r\n /**\r\n * Establece la fecha desde un string ISO\r\n * @param isoString - Fecha en formato ISO\r\n */\r\n public setFromISOString(isoString: string | null): void {\r\n if (isoString) {\r\n const date = new Date(isoString);\r\n if (!isNaN(date.getTime())) {\r\n this.writeValue(date);\r\n this.onChange(isoString);\r\n }\r\n } else {\r\n this.clear();\r\n }\r\n }\r\n}","<div class=\"datetime-container\">\r\n \r\n @if (isOpen()) {\r\n <div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Sección del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegación -->\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ño anterior\"\r\n >\r\n ‹‹\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 ‹\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 ›\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente año\"\r\n >\r\n ››\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Días 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é</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">Sáb</div>\r\n </div>\r\n\r\n <!-- Días -->\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","import { Component, Input, Output, EventEmitter, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'app-pagination',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './pagination.html',\r\n styleUrls: ['./pagination.css']\r\n})\r\nexport class PaginationComponent {\r\n @Input() page = 1;\r\n @Input() pageSize = 10;\r\n @Input() totalItems = 0;\r\n\r\n @Input() showPageSizeSelector = false;\r\n @Input() pageSizeOptions: number[] = [5, 10, 20, 50];\r\n\r\n @Output() pageChange = new EventEmitter<number>();\r\n @Output() pageSizeChange = new EventEmitter<number>();\r\n\r\n pageSizeValue = signal(this.pageSize);\r\n isOpen = signal(false);\r\n isDisabled = signal(false);\r\n showPageSizeMenu = signal(false);\r\n\r\n totalPages = computed(() => {\r\n const size = this.pageSizeValue();\r\n const total = this.totalItems;\r\n return size > 0 ? Math.ceil(total / size) : 1;\r\n });\r\n\r\n pages = computed(() => {\r\n const tp = this.totalPages();\r\n return Array.from({ length: tp }, (_, i) => i + 1);\r\n });\r\n\r\n selectedPageSize = computed(() => this.pageSizeValue());\r\n\r\n goToPage(p: number) {\r\n if (p < 1 || p > this.totalPages()) return;\r\n this.pageChange.emit(p);\r\n }\r\n\r\n togglePageSizeMenu() {\r\n this.isOpen.update(v => !v);\r\n this.showPageSizeMenu.update(v => !v);\r\n }\r\n\r\n selectPageSize(size: number) {\r\n this.pageSizeValue.set(size);\r\n this.pageSizeChange.emit(size);\r\n this.showPageSizeMenu.set(false);\r\n this.isOpen.set(false);\r\n }\r\n}\r\n","<div class=\"pagination-container\">\r\n <div class=\"pagination\">\r\n <!-- Botón doble atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(1)\" [disabled]=\"page === 1\">\r\n ««\r\n </button>\r\n\r\n <!-- Botón atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page - 1)\" [disabled]=\"page === 1\">\r\n «\r\n </button>\r\n\r\n <!-- Números de página -->\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ón siguiente -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page + 1)\" [disabled]=\"page === totalPages()\">\r\n »\r\n </button>\r\n\r\n <!-- Botón doble adelante -->\r\n <button class=\"icon-button\" (click)=\"goToPage(totalPages())\" [disabled]=\"page === totalPages()\">\r\n »»\r\n </button>\r\n </div>\r\n\r\n <!-- Selector Items por página -->\r\n <div *ngIf=\"showPageSizeSelector\">\r\n <div class=\"pagination-v-4\">\r\n <div class=\"label-pagination\">Items por página</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ú 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","import { Component, HostListener, input, output, signal } from '@angular/core';\r\nimport { TableAction, TableColumn, TableRow } from '../../interfaces/table';\r\n\r\n@Component({\r\n selector: 'lib-table',\r\n imports: [],\r\n standalone: true,\r\n templateUrl: './table.html',\r\n styleUrl: './table.css',\r\n})\r\nexport class Table {\r\n columns = input<TableColumn[]>([]);\r\n data = input<TableRow[]>([]);\r\n actions = input<TableAction[]>([]);\r\n showActions = input<Boolean>(true);\r\n\r\n openedMenu = signal<number | null>(null);\r\n selectedRow = signal<TableRow | null>(null);\r\n sortColumn = signal<string | null>(null);\r\n sortDirection = signal<'asc' | 'desc'>('desc');\r\n\r\n optionSelected = output<{ action: string; row: TableRow }>();\r\n\r\n toggleMenu(index: number) {\r\n this.openedMenu.set(this.openedMenu() === index ? null : index);\r\n }\r\n\r\n onOptionClick(option: TableAction, row: TableRow) {\r\n this.optionSelected.emit({ action: option.label, row });\r\n this.openedMenu.set(null);\r\n }\r\n\r\n openModal(row: TableRow, event?: MouseEvent) {\r\n event?.stopPropagation();\r\n\r\n if (this.selectedRow()?.['id'] === row['id']) {\r\n this.selectedRow.set(null);\r\n } else {\r\n this.selectedRow.set(row);\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onClickOutside(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n if (!target.closest('.menu-acciones')) {\r\n this.selectedRow.set(null);\r\n }\r\n }\r\n\r\n getAlignment(col: TableColumn): string {\r\n if (col.align && col.align !== 'auto') return col.align;\r\n\r\n switch (col.type) {\r\n case 'number':\r\n case 'money':\r\n case 'percentage':\r\n return 'right';\r\n case 'status':\r\n return 'center';\r\n default:\r\n return 'left';\r\n }\r\n }\r\n\r\n formatValue(col: TableColumn, value: any): string {\r\n if (value === null || value === undefined) return '';\r\n\r\n switch (col.type) {\r\n case 'money':\r\n return new Intl.NumberFormat('es-CO', {\r\n style: 'currency',\r\n currency: 'COP',\r\n minimumFractionDigits: 0\r\n }).format(value);\r\n\r\n case 'number':\r\n return new Intl.NumberFormat('es-CO').format(value);\r\n\r\n case 'percentage':\r\n return `${value}%`;\r\n\r\n case 'date':\r\n const d = new Date(value);\r\n if (isNaN(d.getTime())) return value;\r\n\r\n const day = String(d.getDate()).padStart(2, '0');\r\n const month = String(d.getMonth() + 1).padStart(2, '0');\r\n const year = d.getFullYear();\r\n\r\n return `${day}/${month}/${year}`;\r\n\r\n\r\n default:\r\n return String(value);\r\n }\r\n }\r\n\r\n getStatusStyle(value: string) {\r\n const map: Record<string, { bg: string; color: string }> = {\r\n aprobado: { bg: '#E6F4EA', color: '#1E8E3E' }, // verde\r\n pendiente: { bg: '#FFF4E5', color: '#E67E22' }, // naranja\r\n rechazado: { bg: '#FCE8E6', color: '#D93025' }, // rojo\r\n en_proceso: { bg: '#E8F0FE', color: '#1967D2' }, // azul\r\n };\r\n\r\n const key = value?.toString().toLowerCase()?.replace(/\\s+/g, '_');\r\n\r\n return map[key] || { bg: '#F4F4F4', color: '#5F6368' }; // default gris\r\n }\r\n\r\n sortData() {\r\n const col = this.sortColumn();\r\n if (!col) return this.data();\r\n\r\n const dir = this.sortDirection();\r\n\r\n return [...this.data()].sort((a, b) => {\r\n const x = a[col] ?? '';\r\n const y = b[col] ?? '';\r\n\r\n // Caso: fechas\r\n if (this.isDate(x) && this.isDate(y)) {\r\n return dir === 'asc'\r\n ? new Date(x).getTime() - new Date(y).getTime()\r\n : new Date(y).getTime() - new Date(x).getTime();\r\n }\r\n\r\n // Caso: números\r\n if (!isNaN(Number(x)) && !isNaN(Number(y))) {\r\n return dir === 'asc' ? Number(x) - Number(y) : Number(y) - Number(x);\r\n }\r\n\r\n // Caso: strings\r\n return dir === 'asc'\r\n ? x.toString().localeCompare(y.toString())\r\n : y.toString().localeCompare(x.toString());\r\n });\r\n }\r\n\r\n isDate(value: any): boolean {\r\n return (\r\n typeof value === 'string' &&\r\n value.length > 5 &&\r\n !isNaN(Date.parse(value))\r\n );\r\n }\r\n\r\n onSort(col: TableColumn) {\r\n if (this.sortColumn() === col.key) {\r\n // cambiar asc <-> desc\r\n this.sortDirection.set(\r\n this.sortDirection() === 'asc' ? 'desc' : 'asc'\r\n );\r\n } else {\r\n // nueva columna → empieza en desc (más reciente primero)\r\n this.sortColumn.set(col.key);\r\n this.sortDirection.set('desc');\r\n }\r\n }\r\n}\r\n","<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 >\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' ? '▲' : '▼' }}\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\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 { {{ 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 actions(); 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","// src/app/components/public-api.ts\r\n\r\n// Exportar el componente\r\nexport * from './lib/components/date-time-filter/date-time-filter';\r\nexport * from './lib/components/pagination/pagination';\r\nexport * from './lib/components/table/table';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -1,9 +1,97 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import { OnDestroy, ElementRef, NgZone, EventEmitter } from '@angular/core';
|
|
3
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
interface FilterOption {
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
type: 'date';
|
|
9
|
+
}
|
|
10
|
+
interface DateFilterSelection {
|
|
11
|
+
filter: string;
|
|
12
|
+
value: Date;
|
|
13
|
+
}
|
|
14
|
+
type DateTimeMode = 'date' | 'datetime';
|
|
15
|
+
interface Hour12 {
|
|
16
|
+
value: number;
|
|
17
|
+
display: string;
|
|
18
|
+
}
|
|
19
|
+
type FilterType = DateTimeMode;
|
|
20
|
+
declare class DateTimeFilter implements ControlValueAccessor, OnDestroy {
|
|
21
|
+
private elementRef;
|
|
22
|
+
private ngZone;
|
|
23
|
+
mode: _angular_core.InputSignal<DateTimeMode>;
|
|
24
|
+
placeholder: _angular_core.InputSignal<string>;
|
|
25
|
+
minDate: _angular_core.InputSignal<Date | null>;
|
|
26
|
+
maxDate: _angular_core.InputSignal<Date | null>;
|
|
27
|
+
filter: _angular_core.InputSignal<string>;
|
|
28
|
+
dateSelected: _angular_core.OutputEmitterRef<DateFilterSelection>;
|
|
29
|
+
filters: FilterOption[];
|
|
30
|
+
dateChange: _angular_core.OutputEmitterRef<Date | null>;
|
|
31
|
+
isOpen: _angular_core.WritableSignal<boolean>;
|
|
32
|
+
selectedDate: _angular_core.WritableSignal<Date | null>;
|
|
33
|
+
isDisabled: _angular_core.WritableSignal<boolean>;
|
|
34
|
+
isTouched: _angular_core.WritableSignal<boolean>;
|
|
35
|
+
currentMonth: _angular_core.WritableSignal<number>;
|
|
36
|
+
currentYear: _angular_core.WritableSignal<number>;
|
|
37
|
+
selectedHour: _angular_core.WritableSignal<number>;
|
|
38
|
+
selectedMinute: _angular_core.WritableSignal<number>;
|
|
39
|
+
selectedAmPm: _angular_core.WritableSignal<"AM" | "PM">;
|
|
40
|
+
private documentClickListener?;
|
|
41
|
+
showFilters: boolean;
|
|
42
|
+
showDatePicker: boolean;
|
|
43
|
+
activeFilterType: string | null;
|
|
44
|
+
selectDate(date: Date): void;
|
|
45
|
+
getDatePickerMode(type: FilterType): DateTimeMode;
|
|
46
|
+
displayValue: _angular_core.Signal<string>;
|
|
47
|
+
monthName: _angular_core.Signal<string>;
|
|
48
|
+
calendarDays: _angular_core.Signal<(number | null)[]>;
|
|
49
|
+
hours12: _angular_core.Signal<Hour12[]>;
|
|
50
|
+
selectedHour12: _angular_core.Signal<number>;
|
|
51
|
+
minutes: _angular_core.Signal<number[]>;
|
|
52
|
+
private onChange;
|
|
53
|
+
private onTouched;
|
|
54
|
+
constructor(elementRef: ElementRef, ngZone: NgZone);
|
|
55
|
+
ngOnDestroy(): void;
|
|
56
|
+
writeValue(value: string | Date | null): void;
|
|
57
|
+
registerOnChange(fn: (value: string | null) => void): void;
|
|
58
|
+
registerOnTouched(fn: () => void): void;
|
|
59
|
+
setDisabledState(isDisabled: boolean): void;
|
|
60
|
+
toggle(): void;
|
|
61
|
+
open(): void;
|
|
62
|
+
close(): void;
|
|
63
|
+
selectDay(day: number | null): void;
|
|
64
|
+
setHour12(hour12: number): void;
|
|
65
|
+
setMinute(minute: number): void;
|
|
66
|
+
setAmPm(amPm: 'AM' | 'PM'): void;
|
|
67
|
+
previousMonth(): void;
|
|
68
|
+
nextMonth(): void;
|
|
69
|
+
previousYear(): void;
|
|
70
|
+
nextYear(): void;
|
|
71
|
+
today(): void;
|
|
72
|
+
clear(): void;
|
|
73
|
+
onKeyDown(event: KeyboardEvent): void;
|
|
74
|
+
isDaySelected(day: number | null): boolean;
|
|
75
|
+
isToday(day: number | null): boolean;
|
|
76
|
+
isDayDisabled(day: number | null): boolean;
|
|
77
|
+
isDateDisabled(date: Date): boolean;
|
|
78
|
+
private updateDateTime;
|
|
79
|
+
private markAsTouched;
|
|
80
|
+
private addDocumentListener;
|
|
81
|
+
private removeDocumentListener;
|
|
82
|
+
markTouched(): void;
|
|
83
|
+
/**
|
|
84
|
+
* Obtiene la fecha seleccionada en formato ISO string
|
|
85
|
+
* @returns string ISO o null si no hay fecha seleccionada
|
|
86
|
+
*/
|
|
87
|
+
getISOString(): string | null;
|
|
88
|
+
/**
|
|
89
|
+
* Establece la fecha desde un string ISO
|
|
90
|
+
* @param isoString - Fecha en formato ISO
|
|
91
|
+
*/
|
|
92
|
+
setFromISOString(isoString: string | null): void;
|
|
93
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DateTimeFilter, never>;
|
|
94
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DateTimeFilter, "app-date-time-filter", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": true; "isSignal": true; }; }, { "dateSelected": "dateSelected"; "dateChange": "dateChange"; }, never, never, true, never>;
|
|
7
95
|
}
|
|
8
96
|
|
|
9
97
|
declare class PaginationComponent {
|
|
@@ -31,6 +119,10 @@ declare class PaginationComponent {
|
|
|
31
119
|
interface TableColumn {
|
|
32
120
|
key: string;
|
|
33
121
|
label: string;
|
|
122
|
+
type?: 'text' | 'number' | 'money' | 'date' | 'percentage' | 'status';
|
|
123
|
+
align?: 'left' | 'right' | 'center' | 'auto';
|
|
124
|
+
sortable?: boolean;
|
|
125
|
+
showActions?: boolean;
|
|
34
126
|
}
|
|
35
127
|
interface TableRow {
|
|
36
128
|
[key: string]: any;
|
|
@@ -45,8 +137,11 @@ declare class Table {
|
|
|
45
137
|
columns: _angular_core.InputSignal<TableColumn[]>;
|
|
46
138
|
data: _angular_core.InputSignal<TableRow[]>;
|
|
47
139
|
actions: _angular_core.InputSignal<TableAction[]>;
|
|
140
|
+
showActions: _angular_core.InputSignal<Boolean>;
|
|
48
141
|
openedMenu: _angular_core.WritableSignal<number | null>;
|
|
49
142
|
selectedRow: _angular_core.WritableSignal<TableRow | null>;
|
|
143
|
+
sortColumn: _angular_core.WritableSignal<string | null>;
|
|
144
|
+
sortDirection: _angular_core.WritableSignal<"asc" | "desc">;
|
|
50
145
|
optionSelected: _angular_core.OutputEmitterRef<{
|
|
51
146
|
action: string;
|
|
52
147
|
row: TableRow;
|
|
@@ -55,8 +150,18 @@ declare class Table {
|
|
|
55
150
|
onOptionClick(option: TableAction, row: TableRow): void;
|
|
56
151
|
openModal(row: TableRow, event?: MouseEvent): void;
|
|
57
152
|
onClickOutside(event: MouseEvent): void;
|
|
153
|
+
getAlignment(col: TableColumn): string;
|
|
154
|
+
formatValue(col: TableColumn, value: any): string;
|
|
155
|
+
getStatusStyle(value: string): {
|
|
156
|
+
bg: string;
|
|
157
|
+
color: string;
|
|
158
|
+
};
|
|
159
|
+
sortData(): TableRow[];
|
|
160
|
+
isDate(value: any): boolean;
|
|
161
|
+
onSort(col: TableColumn): void;
|
|
58
162
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<Table, never>;
|
|
59
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Table, "lib-table", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; }, { "optionSelected": "optionSelected"; }, never, never, true, never>;
|
|
163
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<Table, "lib-table", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; "showActions": { "alias": "showActions"; "required": false; "isSignal": true; }; }, { "optionSelected": "optionSelected"; }, never, never, true, never>;
|
|
60
164
|
}
|
|
61
165
|
|
|
62
|
-
export {
|
|
166
|
+
export { DateTimeFilter, PaginationComponent, Table };
|
|
167
|
+
export type { DateFilterSelection, DateTimeMode, FilterOption, FilterType };
|