@ddiazr/generic-table-drag-and-drop 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,172 @@
1
+ # Generic Table Drag and Drop
2
+
3
+ Tabla Dinamica con Drag and Drop Angular 21+
4
+
5
+ ## Instalación
6
+
7
+ ```bash
8
+ npm install @ddiazr/generic-table-drag-and-drop
9
+ ```
10
+
11
+ ## Peer Dependencies
12
+
13
+ ```bash
14
+ ng add @angular/cdk
15
+ npm i bootstrap @fortawesome/fontawesome-free
16
+ ```
17
+
18
+ ## ColumnConfig && TableAction
19
+
20
+ ```bash
21
+ interface TableAction<T> {
22
+ label: string;
23
+ icon: string;
24
+ class: string;
25
+ callback: (row: T) => void;
26
+ showIf?: (row: T) => boolean; // Tu validación dinámica
27
+ }
28
+
29
+ interface ColumnConfig {
30
+ key: string;
31
+ label: string;
32
+ type?: 'text' | 'number' | 'currency' | 'date';
33
+ bold?: boolean;
34
+ }
35
+ ```
36
+
37
+ ## Campos
38
+
39
+ | Propiedad | Tipo | Obligatorio | Descripción |
40
+ | --------------- | ---------------- | ----------- | ----------------------------------------------------- |
41
+ | `data` | `any[]` | ✅ Sí | Datos de entrada segun el jsonen la tabla |
42
+ | `columnsConfig` | `ColumnConfig[]` | ✅ Sí | Datos de las columnas que quieras que tenga la tabla |
43
+ | `pageSize` | `number` | ❌ No | Valor por defecto tiene 25 para la paginación |
44
+ | `exportExcel` | `boolean` | ❌ No | Valor por defecto false, exportacion a excel |
45
+ | `exportPdf` | `boolean` | ❌ No | Valor por defecto false, exportacion a pdf |
46
+ | `nameExport` | `string` | ❌ No | Nombre que se le dara a las exportaciones |
47
+ | `actions` | `TableAction<T>[]` | ❌ No | Funcion que devuelve la accion segun el columnsConfig |
48
+
49
+ ## Uso básico
50
+
51
+ ```typescript
52
+ import { GenericTableDragAndDrop } from '@ddiazr/generic-table-drag-and-drop';
53
+
54
+ interface ColumnConfig {
55
+ key: string;
56
+ label: string;
57
+ type?: 'text' | 'number' | 'currency' | 'date';
58
+ bold?: boolean;
59
+ }
60
+ interface TableAction<T> {
61
+ label: string;
62
+ icon: string;
63
+ class: string;
64
+ callback: (row: T) => void;
65
+ showIf?: (row: T) => boolean; // Tu validación dinámica
66
+ }
67
+ @Component({
68
+ imports: [GenericTableDragAndDrop],
69
+ template: `
70
+ <tbl-generic-drag-and-drop
71
+ [data]="data()"
72
+ [columnsConfig]="columns()"
73
+ [pageSize]="pageSize()"
74
+ [exportExcel]="exportExcel"
75
+ [exportPdf]="exportPdf"
76
+ nameExport="Reporte pruebas"
77
+ [actions]="actions()"
78
+ />
79
+ `,
80
+ })
81
+ export class AppComponent {
82
+ // SI NO QUEREMOS EL DEFECTO SE LO PODEMOS MANDAR INDICANDO EL VALOR
83
+ pageSize = signal<number>(10);
84
+ // SI NECESITAMOS EXPORTAR LO QUE LA TABLA PRESENTA EN EXCEL
85
+ exportExcel = signal<boolean>(true);
86
+ // SI NECESITAMOS EXPORTAR LO QUE LA TABLA PRESENTA EN PDF
87
+ exportPdf = signal<boolean>(true);
88
+ // AQUI SE LE ASIGNA LOS VALORES QUE SE MOSTRARAN EN LA TABLA
89
+ data = signal<any[]>([
90
+ {
91
+ id: 1,
92
+ nombre: 'Juan Perez',
93
+ edad: 36,
94
+ salario: 1000,
95
+ fechanac: '21/07/1700',
96
+ },
97
+ {
98
+ id: 2,
99
+ nombre: 'Juana Perez',
100
+ edad: 14,
101
+ salario: 2000,
102
+ fechanac: '21/07/1700',
103
+ },
104
+ ]);
105
+ //DECALRAMOS LAS COLUMNAS QUE VA A CONTENER LA TABLA
106
+ columns = signal<ColumnConfig[]>([
107
+ {
108
+ key: 'id',
109
+ label: 'ID',
110
+ },
111
+ {
112
+ key: 'nombre',
113
+ label: 'NOMBRE',
114
+ },
115
+ {
116
+ key: 'edad',
117
+ label: 'EDAD',
118
+ },
119
+ {
120
+ key: 'salario',
121
+ label: 'SALARIO',
122
+ type: 'currency',
123
+ },
124
+ {
125
+ key: 'fechanac',
126
+ label: 'FECHA NACIMIENTO',
127
+ type: 'date',
128
+ },
129
+ ]);
130
+
131
+ // SI SE NECESITA QUE LA TABLA TENGA BOTONES PARA N ACCIONES
132
+ // SE MUESTRA ESTE EJEMPLO QUE TIENE DOS ACCIONES
133
+ // 1. MUESTRA EL BOTON EDIT SI LA EDAD ES > 18
134
+ // 2. MUESTRA EL BOTON SIN RESTRICCION
135
+ actions = signal<TableAction<any>[]>([
136
+ {
137
+ label: 'Edit',
138
+ icon: 'fa fa-edit',
139
+ class: 'btn btn-warning',
140
+ showIf: (row) => row.edad > 18,
141
+ callback: (row) => this.edit(row),
142
+ },
143
+ {
144
+ label: 'VER',
145
+ icon: 'fa fa-edit',
146
+ class: 'btn btn-warning',
147
+ callback: (row) => this.ver(row.id),
148
+ },
149
+ ]);
150
+ }
151
+ ```
152
+
153
+ ## Configuración de estilos
154
+
155
+ En tu `angular.json`:
156
+
157
+ ```json
158
+ "styles": [
159
+ "node_modules/bootstrap/dist/css/bootstrap.min.css",
160
+ "node_modules/@fortawesome/fontawesome-free/css/all.min.css"
161
+ ]
162
+ ```
163
+
164
+ ## Licencia
165
+
166
+ MIT
167
+
168
+ # Source files
169
+
170
+ src/
171
+ _.ts
172
+ !_.d.ts
@@ -0,0 +1,354 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import * as i1 from '@angular/cdk/drag-drop';
3
+ import { moveItemInArray, transferArrayItem, DragDropModule, CdkDropList, CdkDrag } from '@angular/cdk/drag-drop';
4
+ import * as i0 from '@angular/core';
5
+ import { Pipe, input, signal, effect, computed, Component } from '@angular/core';
6
+ import * as XLSX from 'xlsx';
7
+ import jsPDF from 'jspdf';
8
+ import autoTable from 'jspdf-autotable';
9
+ import { ModalGeneric } from 'modal-generic';
10
+
11
+ class SafeDatePipe {
12
+ transform(value) {
13
+ if (!value)
14
+ return "";
15
+ const date = new Date(value);
16
+ if (isNaN(date.getTime()))
17
+ return value;
18
+ const day = String(date.getDate()).padStart(2, "0");
19
+ const month = String(date.getMonth() + 1).padStart(2, "0");
20
+ const year = date.getFullYear();
21
+ return `${day}/${month}/${year}`;
22
+ }
23
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SafeDatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
24
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.2", ngImport: i0, type: SafeDatePipe, isStandalone: true, name: "safeDate" });
25
+ }
26
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SafeDatePipe, decorators: [{
27
+ type: Pipe,
28
+ args: [{
29
+ name: "safeDate",
30
+ standalone: true,
31
+ pure: true, // ✅ Muy importante para performance
32
+ }]
33
+ }] });
34
+
35
+ class SafeCurrencyPipe {
36
+ transform(value) {
37
+ if (value == null || value === '')
38
+ return '';
39
+ const num = Number(value);
40
+ if (isNaN(num))
41
+ return value;
42
+ return 'Q' + num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
43
+ }
44
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SafeCurrencyPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
45
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.2", ngImport: i0, type: SafeCurrencyPipe, isStandalone: true, name: "safeCurrency" });
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SafeCurrencyPipe, decorators: [{
48
+ type: Pipe,
49
+ args: [{
50
+ name: 'safeCurrency',
51
+ standalone: true,
52
+ pure: true
53
+ }]
54
+ }] });
55
+
56
+ class SafeNumberPipe {
57
+ transform(value) {
58
+ if (value == null || value === "")
59
+ return "";
60
+ const num = Number(value);
61
+ if (isNaN(num))
62
+ return value;
63
+ return num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
64
+ }
65
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SafeNumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
66
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.2", ngImport: i0, type: SafeNumberPipe, isStandalone: true, name: "safeNumber" });
67
+ }
68
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SafeNumberPipe, decorators: [{
69
+ type: Pipe,
70
+ args: [{
71
+ name: "safeNumber",
72
+ standalone: true,
73
+ pure: true,
74
+ }]
75
+ }] });
76
+
77
+ class GenericTableDragAndDrop {
78
+ // Inputs
79
+ data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
80
+ columnsConfig = input([], ...(ngDevMode ? [{ debugName: "columnsConfig" }] : []));
81
+ footData = input({}, ...(ngDevMode ? [{ debugName: "footData" }] : []));
82
+ actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
83
+ exportExcel = input(false, ...(ngDevMode ? [{ debugName: "exportExcel" }] : []));
84
+ exportPdf = input(false, ...(ngDevMode ? [{ debugName: "exportPdf" }] : []));
85
+ nameExport = input('reporte', ...(ngDevMode ? [{ debugName: "nameExport" }] : []));
86
+ pageSize = input(25, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
87
+ // Estado
88
+ displayedColumns = signal([], ...(ngDevMode ? [{ debugName: "displayedColumns" }] : []));
89
+ availableColumns = signal([], ...(ngDevMode ? [{ debugName: "availableColumns" }] : []));
90
+ globalFilter = signal('', ...(ngDevMode ? [{ debugName: "globalFilter" }] : []));
91
+ filters = signal({}, ...(ngDevMode ? [{ debugName: "filters" }] : []));
92
+ sortConfig = signal({
93
+ column: '',
94
+ direction: null,
95
+ }, ...(ngDevMode ? [{ debugName: "sortConfig" }] : []));
96
+ activeFilterColumn = signal('', ...(ngDevMode ? [{ debugName: "activeFilterColumn" }] : []));
97
+ showModal = signal(false, ...(ngDevMode ? [{ debugName: "showModal" }] : []));
98
+ currentPage = signal(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
99
+ constructor() {
100
+ effect(() => {
101
+ const d = this.data();
102
+ if (d?.length) {
103
+ this.currentPage.set(1);
104
+ }
105
+ }, { allowSignalWrites: true });
106
+ // Inicialización de columnas
107
+ effect(() => {
108
+ const config = this.columnsConfig();
109
+ if (config.length > 0 && this.displayedColumns().length === 0) {
110
+ this.displayedColumns.set(config.map((c) => c.key));
111
+ }
112
+ }, { allowSignalWrites: true });
113
+ // RESET de página al filtrar: Muy importante
114
+ effect(() => {
115
+ this.globalFilter();
116
+ this.filters();
117
+ this.currentPage.set(1);
118
+ }, { allowSignalWrites: true });
119
+ }
120
+ // Lógica de filtrado
121
+ filteredData = computed(() => {
122
+ let result = [...this.data()];
123
+ const search = this.globalFilter().toLowerCase();
124
+ const activeFilters = this.filters();
125
+ const sort = this.sortConfig();
126
+ if (search) {
127
+ result = result.filter((row) => Object.values(row).some((val) => String(val).toLowerCase().includes(search)));
128
+ }
129
+ Object.keys(activeFilters).forEach((col) => {
130
+ const values = activeFilters[col];
131
+ if (values?.length > 0) {
132
+ result = result.filter((row) => values.includes(String(row[col])));
133
+ }
134
+ });
135
+ if (sort.column && sort.direction) {
136
+ result.sort((a, b) => {
137
+ const valA = String(a[sort.column]).toLowerCase();
138
+ const valB = String(b[sort.column]).toLowerCase();
139
+ const res = valA.localeCompare(valB, undefined, { numeric: true });
140
+ return sort.direction === 'asc' ? res : -res;
141
+ });
142
+ }
143
+ return result;
144
+ }, ...(ngDevMode ? [{ debugName: "filteredData" }] : []));
145
+ uniqueValuesMap = computed(() => {
146
+ const baseData = this.data();
147
+ const activeFilters = this.filters();
148
+ const allCols = [...this.availableColumns(), ...this.displayedColumns()];
149
+ const map = {};
150
+ allCols.forEach((col) => {
151
+ // FILTRADO DINÁMICO:
152
+ // Para la lista de la columna "X", filtramos la data base
153
+ // usando los criterios de TODAS las columnas MENOS la columna "X".
154
+ const dataFilteredByOthers = baseData.filter((row) => {
155
+ return Object.keys(activeFilters).every((filterCol) => {
156
+ // Si es la misma columna que estamos calculando, ignoramos su filtro
157
+ if (filterCol === col)
158
+ return true;
159
+ const values = activeFilters[filterCol];
160
+ if (!values || values.length === 0)
161
+ return true;
162
+ return values.includes(String(row[filterCol]));
163
+ });
164
+ });
165
+ // Extraemos los valores únicos de esa data filtrada por los demás
166
+ map[col] = [
167
+ ...new Set(dataFilteredByOthers.map((item) => String(item[col]))),
168
+ ].sort();
169
+ });
170
+ return map;
171
+ }, ...(ngDevMode ? [{ debugName: "uniqueValuesMap" }] : []));
172
+ // Data que realmente se renderiza (muy ligera)
173
+ pagedData = computed(() => {
174
+ const start = (this.currentPage() - 1) * this.pageSize();
175
+ return this.filteredData().slice(start, start + this.pageSize());
176
+ }, ...(ngDevMode ? [{ debugName: "pagedData" }] : []));
177
+ totalPages = computed(() => Math.ceil(this.filteredData().length / this.pageSize()) || 1, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
178
+ // Genera el array de números para los botones (ej: [1, 2, 3...])
179
+ pagesArray = computed(() => {
180
+ const current = this.currentPage();
181
+ const total = this.totalPages();
182
+ const pages = []; // Especificamos el tipo aquí
183
+ for (let i = 1; i <= total; i++) {
184
+ // Lógica para mostrar: primera, última, y 2 alrededor de la actual
185
+ if (i === 1 || i === total || (i >= current - 2 && i <= current + 2)) {
186
+ pages.push(i);
187
+ }
188
+ else if (pages[pages.length - 1] !== '...') {
189
+ pages.push('...');
190
+ }
191
+ }
192
+ return pages;
193
+ }, ...(ngDevMode ? [{ debugName: "pagesArray" }] : []));
194
+ //SI TRAE FOOT
195
+ hasFootData = computed(() => Object.keys(this.footData()).length > 0, ...(ngDevMode ? [{ debugName: "hasFootData" }] : []));
196
+ getConfig(key) {
197
+ return this.columnsConfig().find((c) => c.key === key);
198
+ }
199
+ // Métodos de UI (Drop, Sort, Filter) simplificados
200
+ drop(event) {
201
+ console.log('Envent:::', event);
202
+ const prev = event.previousContainer.data;
203
+ const curr = event.container.data;
204
+ if (event.previousContainer === event.container) {
205
+ moveItemInArray(curr, event.previousIndex, event.currentIndex);
206
+ }
207
+ else {
208
+ transferArrayItem(prev, curr, event.previousIndex, event.currentIndex);
209
+ }
210
+ // Sincronizar con los modelos
211
+ if (event.container.id === 'active-list')
212
+ this.displayedColumns.set([...curr]);
213
+ else
214
+ this.availableColumns.set([...curr]);
215
+ }
216
+ toggleSort(col) {
217
+ const cur = this.sortConfig();
218
+ const dir = cur.column === col
219
+ ? cur.direction === 'asc'
220
+ ? 'desc'
221
+ : cur.direction === 'desc'
222
+ ? null
223
+ : 'asc'
224
+ : 'asc';
225
+ this.sortConfig.set({ column: dir ? col : '', direction: dir });
226
+ }
227
+ toggleFilter(column, value) {
228
+ this.filters.update((prev) => {
229
+ const currentList = prev[column] || [];
230
+ const newList = currentList.includes(value)
231
+ ? currentList.filter((v) => v !== value) // Quitar si ya está
232
+ : [...currentList, value]; // Agregar si no está
233
+ return { ...prev, [column]: newList };
234
+ });
235
+ }
236
+ isAllSelected(column) {
237
+ if (!column)
238
+ return false;
239
+ const uniqueValues = this.uniqueValuesMap()[column] || [];
240
+ const currentFilters = this.filters()[column] || [];
241
+ // Si no hay filtros, por defecto todo está "seleccionado" visualmente
242
+ if (currentFilters.length === 0)
243
+ return true;
244
+ return uniqueValues.length === currentFilters.length;
245
+ }
246
+ toggleAll(column) {
247
+ const uniqueValues = this.uniqueValuesMap()[column] || [];
248
+ const currentFilters = this.filters()[column] || [];
249
+ this.filters.update((prev) => {
250
+ // Si ya están todos, limpiamos para mostrar todo de nuevo
251
+ if (currentFilters.length === 0 || currentFilters.length === uniqueValues.length) {
252
+ return { ...prev, [column]: [] };
253
+ }
254
+ else {
255
+ // Si no, seleccionamos todos los valores únicos
256
+ return { ...prev, [column]: [...uniqueValues] };
257
+ }
258
+ });
259
+ }
260
+ exportToExcel() {
261
+ const data = this.filteredData();
262
+ const columns = this.displayedColumns();
263
+ const foot = this.footData(); // El input que viene del padre
264
+ // 1. Mapear los datos del cuerpo
265
+ const dataToExport = data.map((row) => {
266
+ const filteredRow = {};
267
+ columns.forEach((col) => {
268
+ const headerName = this.getConfig(col)?.label || col;
269
+ filteredRow[headerName] = row[col];
270
+ });
271
+ return filteredRow;
272
+ });
273
+ // 2. Crear la fila del pie de página
274
+ const footerRow = {};
275
+ columns.forEach((col) => {
276
+ const headerName = this.getConfig(col)?.label || col;
277
+ // Buscamos si existe un valor en footData para esta key
278
+ footerRow[headerName] = foot[col] ?? '';
279
+ });
280
+ // 3. Insertar al final
281
+ dataToExport.push(footerRow);
282
+ const worksheet = XLSX.utils.json_to_sheet(dataToExport);
283
+ const workbook = XLSX.utils.book_new();
284
+ XLSX.utils.book_append_sheet(workbook, worksheet, 'Reporte');
285
+ XLSX.writeFile(workbook, `${this.nameExport()}_${new Date().getTime()}.xlsx`);
286
+ }
287
+ exportToPDF() {
288
+ const doc = new jsPDF('l', 'mm', 'a4');
289
+ const data = this.filteredData();
290
+ const columns = this.displayedColumns();
291
+ const foot = this.footData();
292
+ const headers = columns.map((col) => this.getConfig(col)?.label || col);
293
+ // Datos del cuerpo
294
+ const rows = data.map((row) => columns.map((col) => row[col]));
295
+ // Fila del pie de página mapeada según el orden de las columnas visibles
296
+ const footerRow = columns.map((col) => foot[col] ?? '');
297
+ autoTable(doc, {
298
+ head: [headers],
299
+ body: rows,
300
+ foot: [footerRow], // Pasamos el pie aquí
301
+ theme: 'grid',
302
+ headStyles: { fillColor: [13, 110, 253] }, // Azul
303
+ footStyles: {
304
+ fillColor: [240, 240, 240], // Gris claro para resaltar
305
+ textColor: [0, 0, 0],
306
+ fontStyle: 'bold',
307
+ },
308
+ styles: { fontSize: 8, cellPadding: 2 },
309
+ });
310
+ doc.save(`${this.nameExport()}_${new Date().getTime()}.pdf`);
311
+ }
312
+ resetAllFilters() {
313
+ // 1. Limpiamos el objeto de filtros de columnas (vuelve a {})
314
+ this.filters.set({});
315
+ // 2. Limpiamos el buscador global
316
+ this.globalFilter.set('');
317
+ // 3. (Opcional) Si quieres que las columnas vuelvan a su orden original:
318
+ const config = this.columnsConfig();
319
+ this.displayedColumns.set(config.map((c) => c.key));
320
+ // Available inicia vacío por defecto como pediste
321
+ this.availableColumns.set([]);
322
+ }
323
+ goToPage(page) {
324
+ if (typeof page === 'number' && page > 0 && page <= this.totalPages()) {
325
+ this.currentPage.set(page);
326
+ }
327
+ }
328
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: GenericTableDragAndDrop, deps: [], target: i0.ɵɵFactoryTarget.Component });
329
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: GenericTableDragAndDrop, isStandalone: true, selector: "tbl-generic-drag-and-drop", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columnsConfig: { classPropertyName: "columnsConfig", publicName: "columnsConfig", isSignal: true, isRequired: false, transformFunction: null }, footData: { classPropertyName: "footData", publicName: "footData", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, exportExcel: { classPropertyName: "exportExcel", publicName: "exportExcel", isSignal: true, isRequired: false, transformFunction: null }, exportPdf: { classPropertyName: "exportPdf", publicName: "exportPdf", isSignal: true, isRequired: false, transformFunction: null }, nameExport: { classPropertyName: "nameExport", publicName: "nameExport", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"row g-3 mb-1 align-items-end\">\r\n <div class=\"col-12\">\r\n <div class=\"table-toolbar-container\">\r\n <div class=\"btn-group shadow-sm h-100\">\r\n <button\r\n class=\"btn btn-outline-warning btn-sm d-flex align-items-center\"\r\n (click)=\"resetAllFilters()\"\r\n title=\"Limpiar todos los filtros\"\r\n >\r\n <i class=\"fa fa-sync-alt me-1\"></i> Restablecer\r\n </button>\r\n @if (exportExcel()) {\r\n <button class=\"btn btn-outline-success border-end-0\" (click)=\"exportToExcel()\">\r\n <i class=\"fa fa-file-excel me-1\"></i>\r\n </button>\r\n }\r\n @if (exportPdf()) {\r\n <button class=\"btn btn-outline-danger border-end-0\" (click)=\"exportToPDF()\">\r\n <i class=\"fa fa-file-pdf me-1\"></i>\r\n </button>\r\n }\r\n <ng-content select=\"[buttonsexport]\"></ng-content>\r\n </div>\r\n\r\n <div class=\"input-group custom-search-input shadow-sm flex-grow-1 h-100\">\r\n <span class=\"input-group-text\"><i class=\"fa fa-search\"></i></span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"Buscar en el reporte actual...\"\r\n [value]=\"globalFilter()\"\r\n (input)=\"globalFilter.set($any($event.target).value)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 mb-3\">\r\n <div\r\n cdkDropList\r\n #availableList=\"cdkDropList\"\r\n id=\"available-list\"\r\n [cdkDropListData]=\"availableColumns()\"\r\n [cdkDropListConnectedTo]=\"[activeList]\"\r\n orientation=\"horizontal\"\r\n class=\"available-cols-box d-flex gap-2 flex-wrap justify-content-center align-items-center p-2 border rounded bg-light\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n >\r\n @for (col of availableColumns(); track col) {\r\n <div class=\"column-tag shadow-sm badge rounded-pill bg-danger p-2\" cdkDrag>\r\n <i class=\"fa fa-eye-slash me-1\"></i> {{ col }}\r\n </div>\r\n } @empty {\r\n <small class=\"text-muted opacity-50\">Arrastre aqu\u00ED las columnas que desea ocultar</small>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"table-responsive shadow-sm border rounded mb-2\" (scroll)=\"(0)\">\r\n <!-- <div class=\"table-container-scroll shadow-sm\"> -->\r\n <table class=\"table table-hover mb-0 table-sm\">\r\n <thead class=\"bg-dark text-white\">\r\n <tr\r\n cdkDropList\r\n #activeList=\"cdkDropList\"\r\n id=\"active-list\"\r\n [cdkDropListData]=\"displayedColumns()\"\r\n [cdkDropListConnectedTo]=\"[availableList]\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n cdkDropListOrientation=\"horizontal\"\r\n orientation=\"horizontal\"\r\n >\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col);\r\n <th cdkDrag class=\"bg-primary text-white border-end nowrap\">\r\n <div class=\"d-flex align-items-center justify-content-between h-100\">\r\n <span (click)=\"toggleSort(col)\" style=\"cursor: pointer\">\r\n <i class=\"fa fa-grip-vertical me-2 opacity-50\"></i>{{ config?.label || col }}\r\n @if (sortConfig().column === col) {\r\n <i\r\n class=\"fa ms-1\"\r\n [class.fa-sort-up]=\"sortConfig().direction === 'asc'\"\r\n [class.fa-sort-down]=\"sortConfig().direction === 'desc'\"\r\n ></i>\r\n }\r\n </span>\r\n <button\r\n class=\"btn btn-sm text-white p-0\"\r\n (click)=\"activeFilterColumn.set(col); showModal.set(true)\"\r\n >\r\n <i\r\n class=\"fa fa-filter\"\r\n [class.text-warning]=\"(filters()[col]?.length ?? 0) > 0\"\r\n ></i>\r\n </button>\r\n </div>\r\n </th>\r\n }\r\n @if (actions().length > 0) {\r\n <th class=\"bg-dark text-center\">Acciones</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of pagedData(); track row.id) {\r\n <tr>\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col);\r\n <!-- <td>{{ $any(row)[col] }}</td> -->\r\n\r\n <td class=\"py-2 px-3 border-end\">\r\n <div [class.fw-bold]=\"config?.bold\" class=\"text-dark\">\r\n @switch (config?.type) {\r\n @case ('date') {\r\n {{ $any(row)[col] | safeDate }}\r\n }\r\n @case ('currency') {\r\n {{ $any(row)[col] | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ $any(row)[col] | safeNumber }}\r\n }\r\n @default {\r\n {{ $any(row)[col] }}\r\n }\r\n }\r\n </div>\r\n <!-- {{ $any(row)[col] }} -->\r\n </td>\r\n }\r\n @if (actions().length > 0) {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track action.label) {\r\n @if (!action.showIf || action.showIf(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.class\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i>\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n @if (hasFootData()) {\r\n <tfoot class=\"bg-light fw-bold border-top\">\r\n <tr>\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col); @let footValue = footData()[col];\r\n\r\n <td class=\"py-2 px-3 border-end text-dark\">\r\n @if (footValue !== undefined && footValue !== null) {\r\n @switch (config?.type) {\r\n @case ('currency') {\r\n {{ footValue | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ footValue | safeNumber }}\r\n }\r\n @default {\r\n {{ footValue }}\r\n }\r\n }\r\n }\r\n </td>\r\n }\r\n @if (actions().length > 0) {\r\n <td class=\"bg-light\"></td>\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n </table>\r\n <!-- </div> -->\r\n</div>\r\n<nav>\r\n <ul class=\"pagination pagination-sm mb-0\">\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === 1\">\r\n <button class=\"page-link\" (click)=\"goToPage(currentPage() - 1)\">Anterior</button>\r\n </li>\r\n\r\n @for (p of pagesArray(); track $index) {\r\n @if (p === '...') {\r\n <li class=\"page-item disabled\"><span class=\"page-link\">...</span></li>\r\n } @else {\r\n <li class=\"page-item\" [class.active]=\"currentPage() === p\">\r\n <button class=\"page-link\" (click)=\"goToPage(p)\">{{ p }}</button>\r\n </li>\r\n }\r\n }\r\n\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === totalPages()\">\r\n <button class=\"page-link\" (click)=\"goToPage(currentPage() + 1)\">Siguiente</button>\r\n </li>\r\n </ul>\r\n</nav>\r\n@if (showModal()) {\r\n <mdl-modal-generic\r\n [textTitle]=\"'Filtrar: ' + activeFilterColumn()\"\r\n [showFooter]=\"false\"\r\n modalSize=\"md\"\r\n >\r\n <ng-container buttonclose>\r\n <button type=\"button\" class=\"btn-close py-0\" (click)=\"showModal.set(false)\"></button>\r\n </ng-container>\r\n\r\n <ng-container body>\r\n <div class=\"px-2\">\r\n <div class=\"form-check mb-3\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"all-modal\"\r\n [checked]=\"isAllSelected(activeFilterColumn())\"\r\n (change)=\"toggleAll(activeFilterColumn())\"\r\n />\r\n <label class=\"form-check-label fw-bold\" for=\"all-modal\">(Seleccionar todo)</label>\r\n </div>\r\n <hr />\r\n <div style=\"max-height: 300px; overflow-y: auto\" class=\"custom-scroll\">\r\n @for (val of uniqueValuesMap()[activeFilterColumn()]; track val) {\r\n <div class=\"form-check py-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"'check-' + val\"\r\n [checked]=\"filters()[activeFilterColumn()]?.includes(val)\"\r\n (change)=\"toggleFilter(activeFilterColumn(), val)\"\r\n />\r\n <label class=\"form-check-label\" [for]=\"'check-' + val\">{{ val }}</label>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-container>\r\n </mdl-modal-generic>\r\n}\r\n", styles: ["@charset \"UTF-8\";tfoot{position:sticky;bottom:0;z-index:10;background-color:#f8f9fa;box-shadow:0 -2px 5px #0000001a}.table-toolbar-container{display:flex;align-items:center;gap:10px;height:40px}.custom-search-input{border-radius:6px!important;border:1px solid #ced4da;height:100%}.custom-search-input .input-group-text{background-color:#fff;border-right:none;color:#adb5bd;padding-left:12px;padding-right:8px}.custom-search-input .form-control{border-left:none;font-size:.9rem;box-shadow:none!important}.custom-search-input:focus-within{border-color:#0d6efd;box-shadow:0 0 0 .25rem #0d6efd1a}.available-cols-box{background-color:#d3d3d4;border-radius:8px;padding:8px 12px;min-height:50px}.column-tag{background-color:#ff6b52!important;color:#fff;padding:6px 14px;font-size:.85rem;font-weight:600;border-radius:20px;cursor:grab;transition:all .2s}.column-tag:hover{transform:translateY(-2px);filter:brightness(1.1)}th,td{overflow:hidden;white-space:nowrap}tfoot{position:sticky;bottom:0;z-index:5;background-color:#f8f9fa}tfoot td{border-top:2px solid #dee2e6!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: ModalGeneric, selector: "mdl-modal-generic", inputs: ["textTitle", "modalSize", "showFooter", "FullScreen"] }, { kind: "pipe", type: SafeDatePipe, name: "safeDate" }, { kind: "pipe", type: SafeCurrencyPipe, name: "safeCurrency" }, { kind: "pipe", type: SafeNumberPipe, name: "safeNumber" }] });
330
+ }
331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: GenericTableDragAndDrop, decorators: [{
332
+ type: Component,
333
+ args: [{ selector: 'tbl-generic-drag-and-drop', imports: [
334
+ CommonModule,
335
+ DragDropModule,
336
+ ModalGeneric,
337
+ CdkDropList,
338
+ CdkDrag,
339
+ SafeDatePipe,
340
+ SafeCurrencyPipe,
341
+ SafeNumberPipe,
342
+ ], template: "<div class=\"row g-3 mb-1 align-items-end\">\r\n <div class=\"col-12\">\r\n <div class=\"table-toolbar-container\">\r\n <div class=\"btn-group shadow-sm h-100\">\r\n <button\r\n class=\"btn btn-outline-warning btn-sm d-flex align-items-center\"\r\n (click)=\"resetAllFilters()\"\r\n title=\"Limpiar todos los filtros\"\r\n >\r\n <i class=\"fa fa-sync-alt me-1\"></i> Restablecer\r\n </button>\r\n @if (exportExcel()) {\r\n <button class=\"btn btn-outline-success border-end-0\" (click)=\"exportToExcel()\">\r\n <i class=\"fa fa-file-excel me-1\"></i>\r\n </button>\r\n }\r\n @if (exportPdf()) {\r\n <button class=\"btn btn-outline-danger border-end-0\" (click)=\"exportToPDF()\">\r\n <i class=\"fa fa-file-pdf me-1\"></i>\r\n </button>\r\n }\r\n <ng-content select=\"[buttonsexport]\"></ng-content>\r\n </div>\r\n\r\n <div class=\"input-group custom-search-input shadow-sm flex-grow-1 h-100\">\r\n <span class=\"input-group-text\"><i class=\"fa fa-search\"></i></span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"Buscar en el reporte actual...\"\r\n [value]=\"globalFilter()\"\r\n (input)=\"globalFilter.set($any($event.target).value)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 mb-3\">\r\n <div\r\n cdkDropList\r\n #availableList=\"cdkDropList\"\r\n id=\"available-list\"\r\n [cdkDropListData]=\"availableColumns()\"\r\n [cdkDropListConnectedTo]=\"[activeList]\"\r\n orientation=\"horizontal\"\r\n class=\"available-cols-box d-flex gap-2 flex-wrap justify-content-center align-items-center p-2 border rounded bg-light\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n >\r\n @for (col of availableColumns(); track col) {\r\n <div class=\"column-tag shadow-sm badge rounded-pill bg-danger p-2\" cdkDrag>\r\n <i class=\"fa fa-eye-slash me-1\"></i> {{ col }}\r\n </div>\r\n } @empty {\r\n <small class=\"text-muted opacity-50\">Arrastre aqu\u00ED las columnas que desea ocultar</small>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"table-responsive shadow-sm border rounded mb-2\" (scroll)=\"(0)\">\r\n <!-- <div class=\"table-container-scroll shadow-sm\"> -->\r\n <table class=\"table table-hover mb-0 table-sm\">\r\n <thead class=\"bg-dark text-white\">\r\n <tr\r\n cdkDropList\r\n #activeList=\"cdkDropList\"\r\n id=\"active-list\"\r\n [cdkDropListData]=\"displayedColumns()\"\r\n [cdkDropListConnectedTo]=\"[availableList]\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n cdkDropListOrientation=\"horizontal\"\r\n orientation=\"horizontal\"\r\n >\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col);\r\n <th cdkDrag class=\"bg-primary text-white border-end nowrap\">\r\n <div class=\"d-flex align-items-center justify-content-between h-100\">\r\n <span (click)=\"toggleSort(col)\" style=\"cursor: pointer\">\r\n <i class=\"fa fa-grip-vertical me-2 opacity-50\"></i>{{ config?.label || col }}\r\n @if (sortConfig().column === col) {\r\n <i\r\n class=\"fa ms-1\"\r\n [class.fa-sort-up]=\"sortConfig().direction === 'asc'\"\r\n [class.fa-sort-down]=\"sortConfig().direction === 'desc'\"\r\n ></i>\r\n }\r\n </span>\r\n <button\r\n class=\"btn btn-sm text-white p-0\"\r\n (click)=\"activeFilterColumn.set(col); showModal.set(true)\"\r\n >\r\n <i\r\n class=\"fa fa-filter\"\r\n [class.text-warning]=\"(filters()[col]?.length ?? 0) > 0\"\r\n ></i>\r\n </button>\r\n </div>\r\n </th>\r\n }\r\n @if (actions().length > 0) {\r\n <th class=\"bg-dark text-center\">Acciones</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of pagedData(); track row.id) {\r\n <tr>\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col);\r\n <!-- <td>{{ $any(row)[col] }}</td> -->\r\n\r\n <td class=\"py-2 px-3 border-end\">\r\n <div [class.fw-bold]=\"config?.bold\" class=\"text-dark\">\r\n @switch (config?.type) {\r\n @case ('date') {\r\n {{ $any(row)[col] | safeDate }}\r\n }\r\n @case ('currency') {\r\n {{ $any(row)[col] | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ $any(row)[col] | safeNumber }}\r\n }\r\n @default {\r\n {{ $any(row)[col] }}\r\n }\r\n }\r\n </div>\r\n <!-- {{ $any(row)[col] }} -->\r\n </td>\r\n }\r\n @if (actions().length > 0) {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track action.label) {\r\n @if (!action.showIf || action.showIf(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.class\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i>\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n @if (hasFootData()) {\r\n <tfoot class=\"bg-light fw-bold border-top\">\r\n <tr>\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col); @let footValue = footData()[col];\r\n\r\n <td class=\"py-2 px-3 border-end text-dark\">\r\n @if (footValue !== undefined && footValue !== null) {\r\n @switch (config?.type) {\r\n @case ('currency') {\r\n {{ footValue | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ footValue | safeNumber }}\r\n }\r\n @default {\r\n {{ footValue }}\r\n }\r\n }\r\n }\r\n </td>\r\n }\r\n @if (actions().length > 0) {\r\n <td class=\"bg-light\"></td>\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n </table>\r\n <!-- </div> -->\r\n</div>\r\n<nav>\r\n <ul class=\"pagination pagination-sm mb-0\">\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === 1\">\r\n <button class=\"page-link\" (click)=\"goToPage(currentPage() - 1)\">Anterior</button>\r\n </li>\r\n\r\n @for (p of pagesArray(); track $index) {\r\n @if (p === '...') {\r\n <li class=\"page-item disabled\"><span class=\"page-link\">...</span></li>\r\n } @else {\r\n <li class=\"page-item\" [class.active]=\"currentPage() === p\">\r\n <button class=\"page-link\" (click)=\"goToPage(p)\">{{ p }}</button>\r\n </li>\r\n }\r\n }\r\n\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === totalPages()\">\r\n <button class=\"page-link\" (click)=\"goToPage(currentPage() + 1)\">Siguiente</button>\r\n </li>\r\n </ul>\r\n</nav>\r\n@if (showModal()) {\r\n <mdl-modal-generic\r\n [textTitle]=\"'Filtrar: ' + activeFilterColumn()\"\r\n [showFooter]=\"false\"\r\n modalSize=\"md\"\r\n >\r\n <ng-container buttonclose>\r\n <button type=\"button\" class=\"btn-close py-0\" (click)=\"showModal.set(false)\"></button>\r\n </ng-container>\r\n\r\n <ng-container body>\r\n <div class=\"px-2\">\r\n <div class=\"form-check mb-3\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"all-modal\"\r\n [checked]=\"isAllSelected(activeFilterColumn())\"\r\n (change)=\"toggleAll(activeFilterColumn())\"\r\n />\r\n <label class=\"form-check-label fw-bold\" for=\"all-modal\">(Seleccionar todo)</label>\r\n </div>\r\n <hr />\r\n <div style=\"max-height: 300px; overflow-y: auto\" class=\"custom-scroll\">\r\n @for (val of uniqueValuesMap()[activeFilterColumn()]; track val) {\r\n <div class=\"form-check py-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"'check-' + val\"\r\n [checked]=\"filters()[activeFilterColumn()]?.includes(val)\"\r\n (change)=\"toggleFilter(activeFilterColumn(), val)\"\r\n />\r\n <label class=\"form-check-label\" [for]=\"'check-' + val\">{{ val }}</label>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-container>\r\n </mdl-modal-generic>\r\n}\r\n", styles: ["@charset \"UTF-8\";tfoot{position:sticky;bottom:0;z-index:10;background-color:#f8f9fa;box-shadow:0 -2px 5px #0000001a}.table-toolbar-container{display:flex;align-items:center;gap:10px;height:40px}.custom-search-input{border-radius:6px!important;border:1px solid #ced4da;height:100%}.custom-search-input .input-group-text{background-color:#fff;border-right:none;color:#adb5bd;padding-left:12px;padding-right:8px}.custom-search-input .form-control{border-left:none;font-size:.9rem;box-shadow:none!important}.custom-search-input:focus-within{border-color:#0d6efd;box-shadow:0 0 0 .25rem #0d6efd1a}.available-cols-box{background-color:#d3d3d4;border-radius:8px;padding:8px 12px;min-height:50px}.column-tag{background-color:#ff6b52!important;color:#fff;padding:6px 14px;font-size:.85rem;font-weight:600;border-radius:20px;cursor:grab;transition:all .2s}.column-tag:hover{transform:translateY(-2px);filter:brightness(1.1)}th,td{overflow:hidden;white-space:nowrap}tfoot{position:sticky;bottom:0;z-index:5;background-color:#f8f9fa}tfoot td{border-top:2px solid #dee2e6!important}\n"] }]
343
+ }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], columnsConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnsConfig", required: false }] }], footData: [{ type: i0.Input, args: [{ isSignal: true, alias: "footData", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], exportExcel: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportExcel", required: false }] }], exportPdf: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportPdf", required: false }] }], nameExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "nameExport", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }] } });
344
+
345
+ /*
346
+ * Public API Surface of generic-table-drag-and-drop
347
+ */
348
+
349
+ /**
350
+ * Generated bundle index. Do not edit.
351
+ */
352
+
353
+ export { GenericTableDragAndDrop };
354
+ //# sourceMappingURL=ddiazr-generic-table-drag-and-drop.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ddiazr-generic-table-drag-and-drop.mjs","sources":["../../../projects/generic-table-drag-and-drop/src/lib/pipes/safe-date.pipe.ts","../../../projects/generic-table-drag-and-drop/src/lib/pipes/safe-currency.pipe.ts","../../../projects/generic-table-drag-and-drop/src/lib/pipes/safe-number.pipe.ts","../../../projects/generic-table-drag-and-drop/src/lib/generic-table-drag-and-drop.ts","../../../projects/generic-table-drag-and-drop/src/lib/generic-table-drag-and-drop.html","../../../projects/generic-table-drag-and-drop/src/public-api.ts","../../../projects/generic-table-drag-and-drop/src/ddiazr-generic-table-drag-and-drop.ts"],"sourcesContent":["import { Pipe, PipeTransform } from \"@angular/core\";\r\n\r\n@Pipe({\r\n name: \"safeDate\",\r\n standalone: true,\r\n pure: true, // ✅ Muy importante para performance\r\n})\r\nexport class SafeDatePipe implements PipeTransform {\r\n transform(value: any): string {\r\n if (!value) return \"\";\r\n const date = new Date(value);\r\n if (isNaN(date.getTime())) return value;\r\n\r\n const day = String(date.getDate()).padStart(2, \"0\");\r\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\r\n const year = date.getFullYear();\r\n\r\n return `${day}/${month}/${year}`;\r\n }\r\n}\r\n","import { Pipe, PipeTransform } from \"@angular/core\";\r\n\r\n@Pipe({\r\n name: 'safeCurrency',\r\n standalone: true,\r\n pure: true\r\n})\r\nexport class SafeCurrencyPipe implements PipeTransform {\r\n transform(value: any): string {\r\n if (value == null || value === '') return '';\r\n const num = Number(value);\r\n if (isNaN(num)) return value;\r\n \r\n return 'Q' + num.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\r\n }\r\n}","import { Pipe, PipeTransform } from \"@angular/core\";\r\n\r\n@Pipe({\r\n name: \"safeNumber\",\r\n standalone: true,\r\n pure: true,\r\n})\r\nexport class SafeNumberPipe implements PipeTransform {\r\n transform(value: any): string {\r\n if (value == null || value === \"\") return \"\";\r\n const num = Number(value);\r\n if (isNaN(num)) return value;\r\n\r\n return num.toFixed(2).replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport {\r\n CdkDrag,\r\n CdkDragDrop,\r\n CdkDropList,\r\n DragDropModule,\r\n moveItemInArray,\r\n transferArrayItem,\r\n} from '@angular/cdk/drag-drop';\r\nimport { Component, computed, effect, input, signal } from '@angular/core';\r\nimport * as XLSX from 'xlsx';\r\nimport jsPDF from 'jspdf';\r\nimport autoTable from 'jspdf-autotable';\r\nimport { ColumnConfig, TableAction } from './models/table.interfaces';\r\nimport { SafeDatePipe } from './pipes/safe-date.pipe';\r\nimport { SafeCurrencyPipe } from './pipes/safe-currency.pipe';\r\nimport { SafeNumberPipe } from './pipes/safe-number.pipe';\r\nimport { ModalGeneric } from 'modal-generic'\r\n\r\n@Component({\r\n selector: 'tbl-generic-drag-and-drop',\r\n imports: [\r\n CommonModule,\r\n DragDropModule,\r\n ModalGeneric,\r\n CdkDropList,\r\n CdkDrag,\r\n SafeDatePipe,\r\n SafeCurrencyPipe,\r\n SafeNumberPipe,\r\n ],\r\n templateUrl: './generic-table-drag-and-drop.html',\r\n styleUrl: './generic-table-drag-and-drop.scss',\r\n})\r\nexport class GenericTableDragAndDrop<T extends { id: any }> {\r\n // Inputs\r\n data = input.required<T[]>();\r\n columnsConfig = input<ColumnConfig[]>([]);\r\n footData = input<Record<string, any>>({});\r\n actions = input<TableAction<T>[]>([]);\r\n exportExcel = input<boolean>(false);\r\n exportPdf = input<boolean>(false);\r\n nameExport = input<string>('reporte');\r\n pageSize = input<number>(25);\r\n\r\n // Estado\r\n displayedColumns = signal<string[]>([]);\r\n availableColumns = signal<string[]>([]);\r\n globalFilter = signal<string>('');\r\n filters = signal<Record<string, string[]>>({});\r\n sortConfig = signal<{ column: string; direction: 'asc' | 'desc' | null }>({\r\n column: '',\r\n direction: null,\r\n });\r\n activeFilterColumn = signal<string>('');\r\n showModal = signal<boolean>(false);\r\n currentPage = signal(1);\r\n\r\n constructor() {\r\n effect(\r\n () => {\r\n const d = this.data();\r\n if (d?.length) {\r\n this.currentPage.set(1);\r\n }\r\n },\r\n { allowSignalWrites: true },\r\n );\r\n\r\n // Inicialización de columnas\r\n effect(\r\n () => {\r\n const config = this.columnsConfig();\r\n if (config.length > 0 && this.displayedColumns().length === 0) {\r\n this.displayedColumns.set(config.map((c) => c.key));\r\n }\r\n },\r\n { allowSignalWrites: true },\r\n );\r\n\r\n // RESET de página al filtrar: Muy importante\r\n effect(\r\n () => {\r\n this.globalFilter();\r\n this.filters();\r\n this.currentPage.set(1);\r\n },\r\n { allowSignalWrites: true },\r\n );\r\n }\r\n\r\n // Lógica de filtrado\r\n filteredData = computed(() => {\r\n let result = [...this.data()];\r\n const search = this.globalFilter().toLowerCase();\r\n const activeFilters = this.filters();\r\n const sort = this.sortConfig();\r\n\r\n if (search) {\r\n result = result.filter((row) =>\r\n Object.values(row).some((val) => String(val).toLowerCase().includes(search)),\r\n );\r\n }\r\n\r\n Object.keys(activeFilters).forEach((col) => {\r\n const values = activeFilters[col];\r\n if (values?.length > 0) {\r\n result = result.filter((row) => values.includes(String((row as any)[col])));\r\n }\r\n });\r\n\r\n if (sort.column && sort.direction) {\r\n result.sort((a, b) => {\r\n const valA = String((a as any)[sort.column]).toLowerCase();\r\n const valB = String((b as any)[sort.column]).toLowerCase();\r\n const res = valA.localeCompare(valB, undefined, { numeric: true });\r\n return sort.direction === 'asc' ? res : -res;\r\n });\r\n }\r\n return result;\r\n });\r\n\r\n uniqueValuesMap = computed(() => {\r\n const baseData = this.data();\r\n const activeFilters = this.filters();\r\n const allCols = [...this.availableColumns(), ...this.displayedColumns()];\r\n const map: Record<string, string[]> = {};\r\n\r\n allCols.forEach((col) => {\r\n // FILTRADO DINÁMICO:\r\n // Para la lista de la columna \"X\", filtramos la data base\r\n // usando los criterios de TODAS las columnas MENOS la columna \"X\".\r\n const dataFilteredByOthers = baseData.filter((row) => {\r\n return Object.keys(activeFilters).every((filterCol) => {\r\n // Si es la misma columna que estamos calculando, ignoramos su filtro\r\n if (filterCol === col) return true;\r\n\r\n const values = activeFilters[filterCol];\r\n if (!values || values.length === 0) return true;\r\n\r\n return values.includes(String((row as any)[filterCol]));\r\n });\r\n });\r\n\r\n // Extraemos los valores únicos de esa data filtrada por los demás\r\n map[col] = [\r\n ...new Set(dataFilteredByOthers.map((item) => String((item as any)[col]))),\r\n ].sort();\r\n });\r\n\r\n return map;\r\n });\r\n\r\n // Data que realmente se renderiza (muy ligera)\r\n pagedData = computed(() => {\r\n const start = (this.currentPage() - 1) * this.pageSize();\r\n return this.filteredData().slice(start, start + this.pageSize());\r\n });\r\n\r\n totalPages = computed(() => Math.ceil(this.filteredData().length / this.pageSize()) || 1);\r\n\r\n // Genera el array de números para los botones (ej: [1, 2, 3...])\r\n pagesArray = computed<(number | string)[]>(() => {\r\n const current = this.currentPage();\r\n const total = this.totalPages();\r\n const pages: (number | string)[] = []; // Especificamos el tipo aquí\r\n\r\n for (let i = 1; i <= total; i++) {\r\n // Lógica para mostrar: primera, última, y 2 alrededor de la actual\r\n if (i === 1 || i === total || (i >= current - 2 && i <= current + 2)) {\r\n pages.push(i);\r\n } else if (pages[pages.length - 1] !== '...') {\r\n pages.push('...');\r\n }\r\n }\r\n return pages;\r\n });\r\n\r\n //SI TRAE FOOT\r\n hasFootData = computed(() => Object.keys(this.footData()).length > 0);\r\n\r\n getConfig(key: string): ColumnConfig | undefined {\r\n return this.columnsConfig().find((c) => c.key === key);\r\n }\r\n // Métodos de UI (Drop, Sort, Filter) simplificados\r\n drop(event: CdkDragDrop<string[]>) {\r\n console.log('Envent:::', event);\r\n const prev = event.previousContainer.data;\r\n const curr = event.container.data;\r\n if (event.previousContainer === event.container) {\r\n moveItemInArray(curr, event.previousIndex, event.currentIndex);\r\n } else {\r\n transferArrayItem(prev, curr, event.previousIndex, event.currentIndex);\r\n }\r\n // Sincronizar con los modelos\r\n if (event.container.id === 'active-list') this.displayedColumns.set([...curr]);\r\n else this.availableColumns.set([...curr]);\r\n }\r\n\r\n toggleSort(col: string) {\r\n const cur = this.sortConfig();\r\n const dir =\r\n cur.column === col\r\n ? cur.direction === 'asc'\r\n ? 'desc'\r\n : cur.direction === 'desc'\r\n ? null\r\n : 'asc'\r\n : 'asc';\r\n this.sortConfig.set({ column: dir ? col : '', direction: dir });\r\n }\r\n\r\n toggleFilter(column: string, value: string) {\r\n this.filters.update((prev) => {\r\n const currentList = prev[column] || [];\r\n const newList = currentList.includes(value)\r\n ? currentList.filter((v) => v !== value) // Quitar si ya está\r\n : [...currentList, value]; // Agregar si no está\r\n\r\n return { ...prev, [column]: newList };\r\n });\r\n }\r\n\r\n isAllSelected(column: string): boolean {\r\n if (!column) return false;\r\n const uniqueValues = this.uniqueValuesMap()[column] || [];\r\n const currentFilters = this.filters()[column] || [];\r\n\r\n // Si no hay filtros, por defecto todo está \"seleccionado\" visualmente\r\n if (currentFilters.length === 0) return true;\r\n return uniqueValues.length === currentFilters.length;\r\n }\r\n\r\n toggleAll(column: string) {\r\n const uniqueValues = this.uniqueValuesMap()[column] || [];\r\n const currentFilters = this.filters()[column] || [];\r\n\r\n this.filters.update((prev) => {\r\n // Si ya están todos, limpiamos para mostrar todo de nuevo\r\n if (currentFilters.length === 0 || currentFilters.length === uniqueValues.length) {\r\n return { ...prev, [column]: [] };\r\n } else {\r\n // Si no, seleccionamos todos los valores únicos\r\n return { ...prev, [column]: [...uniqueValues] };\r\n }\r\n });\r\n }\r\n\r\n exportToExcel() {\r\n const data = this.filteredData();\r\n const columns = this.displayedColumns();\r\n const foot = this.footData(); // El input que viene del padre\r\n\r\n // 1. Mapear los datos del cuerpo\r\n const dataToExport = data.map((row) => {\r\n const filteredRow: any = {};\r\n columns.forEach((col) => {\r\n const headerName = this.getConfig(col)?.label || col;\r\n filteredRow[headerName] = (row as any)[col];\r\n });\r\n return filteredRow;\r\n });\r\n\r\n // 2. Crear la fila del pie de página\r\n const footerRow: any = {};\r\n columns.forEach((col) => {\r\n const headerName = this.getConfig(col)?.label || col;\r\n // Buscamos si existe un valor en footData para esta key\r\n footerRow[headerName] = foot[col] ?? '';\r\n });\r\n\r\n // 3. Insertar al final\r\n dataToExport.push(footerRow);\r\n\r\n const worksheet = XLSX.utils.json_to_sheet(dataToExport);\r\n const workbook = XLSX.utils.book_new();\r\n XLSX.utils.book_append_sheet(workbook, worksheet, 'Reporte');\r\n\r\n XLSX.writeFile(workbook, `${this.nameExport()}_${new Date().getTime()}.xlsx`);\r\n }\r\n\r\n exportToPDF() {\r\n const doc = new jsPDF('l', 'mm', 'a4');\r\n const data = this.filteredData();\r\n const columns = this.displayedColumns();\r\n const foot = this.footData();\r\n\r\n const headers = columns.map((col) => this.getConfig(col)?.label || col);\r\n\r\n // Datos del cuerpo\r\n const rows = data.map((row) => columns.map((col) => (row as any)[col]));\r\n\r\n // Fila del pie de página mapeada según el orden de las columnas visibles\r\n const footerRow = columns.map((col) => foot[col] ?? '');\r\n\r\n autoTable(doc, {\r\n head: [headers],\r\n body: rows,\r\n foot: [footerRow], // Pasamos el pie aquí\r\n theme: 'grid',\r\n headStyles: { fillColor: [13, 110, 253] }, // Azul\r\n footStyles: {\r\n fillColor: [240, 240, 240], // Gris claro para resaltar\r\n textColor: [0, 0, 0],\r\n fontStyle: 'bold',\r\n },\r\n styles: { fontSize: 8, cellPadding: 2 },\r\n });\r\n\r\n doc.save(`${this.nameExport()}_${new Date().getTime()}.pdf`);\r\n }\r\n\r\n resetAllFilters() {\r\n // 1. Limpiamos el objeto de filtros de columnas (vuelve a {})\r\n this.filters.set({});\r\n\r\n // 2. Limpiamos el buscador global\r\n this.globalFilter.set('');\r\n\r\n // 3. (Opcional) Si quieres que las columnas vuelvan a su orden original:\r\n const config = this.columnsConfig();\r\n this.displayedColumns.set(config.map((c) => c.key));\r\n // Available inicia vacío por defecto como pediste\r\n this.availableColumns.set([]);\r\n }\r\n\r\n goToPage(page: number | string) {\r\n if (typeof page === 'number' && page > 0 && page <= this.totalPages()) {\r\n this.currentPage.set(page);\r\n }\r\n }\r\n}\r\n","<div class=\"row g-3 mb-1 align-items-end\">\r\n <div class=\"col-12\">\r\n <div class=\"table-toolbar-container\">\r\n <div class=\"btn-group shadow-sm h-100\">\r\n <button\r\n class=\"btn btn-outline-warning btn-sm d-flex align-items-center\"\r\n (click)=\"resetAllFilters()\"\r\n title=\"Limpiar todos los filtros\"\r\n >\r\n <i class=\"fa fa-sync-alt me-1\"></i> Restablecer\r\n </button>\r\n @if (exportExcel()) {\r\n <button class=\"btn btn-outline-success border-end-0\" (click)=\"exportToExcel()\">\r\n <i class=\"fa fa-file-excel me-1\"></i>\r\n </button>\r\n }\r\n @if (exportPdf()) {\r\n <button class=\"btn btn-outline-danger border-end-0\" (click)=\"exportToPDF()\">\r\n <i class=\"fa fa-file-pdf me-1\"></i>\r\n </button>\r\n }\r\n <ng-content select=\"[buttonsexport]\"></ng-content>\r\n </div>\r\n\r\n <div class=\"input-group custom-search-input shadow-sm flex-grow-1 h-100\">\r\n <span class=\"input-group-text\"><i class=\"fa fa-search\"></i></span>\r\n <input\r\n type=\"text\"\r\n class=\"form-control\"\r\n placeholder=\"Buscar en el reporte actual...\"\r\n [value]=\"globalFilter()\"\r\n (input)=\"globalFilter.set($any($event.target).value)\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 mb-3\">\r\n <div\r\n cdkDropList\r\n #availableList=\"cdkDropList\"\r\n id=\"available-list\"\r\n [cdkDropListData]=\"availableColumns()\"\r\n [cdkDropListConnectedTo]=\"[activeList]\"\r\n orientation=\"horizontal\"\r\n class=\"available-cols-box d-flex gap-2 flex-wrap justify-content-center align-items-center p-2 border rounded bg-light\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n >\r\n @for (col of availableColumns(); track col) {\r\n <div class=\"column-tag shadow-sm badge rounded-pill bg-danger p-2\" cdkDrag>\r\n <i class=\"fa fa-eye-slash me-1\"></i> {{ col }}\r\n </div>\r\n } @empty {\r\n <small class=\"text-muted opacity-50\">Arrastre aquí las columnas que desea ocultar</small>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"table-responsive shadow-sm border rounded mb-2\" (scroll)=\"(0)\">\r\n <!-- <div class=\"table-container-scroll shadow-sm\"> -->\r\n <table class=\"table table-hover mb-0 table-sm\">\r\n <thead class=\"bg-dark text-white\">\r\n <tr\r\n cdkDropList\r\n #activeList=\"cdkDropList\"\r\n id=\"active-list\"\r\n [cdkDropListData]=\"displayedColumns()\"\r\n [cdkDropListConnectedTo]=\"[availableList]\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n cdkDropListOrientation=\"horizontal\"\r\n orientation=\"horizontal\"\r\n >\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col);\r\n <th cdkDrag class=\"bg-primary text-white border-end nowrap\">\r\n <div class=\"d-flex align-items-center justify-content-between h-100\">\r\n <span (click)=\"toggleSort(col)\" style=\"cursor: pointer\">\r\n <i class=\"fa fa-grip-vertical me-2 opacity-50\"></i>{{ config?.label || col }}\r\n @if (sortConfig().column === col) {\r\n <i\r\n class=\"fa ms-1\"\r\n [class.fa-sort-up]=\"sortConfig().direction === 'asc'\"\r\n [class.fa-sort-down]=\"sortConfig().direction === 'desc'\"\r\n ></i>\r\n }\r\n </span>\r\n <button\r\n class=\"btn btn-sm text-white p-0\"\r\n (click)=\"activeFilterColumn.set(col); showModal.set(true)\"\r\n >\r\n <i\r\n class=\"fa fa-filter\"\r\n [class.text-warning]=\"(filters()[col]?.length ?? 0) > 0\"\r\n ></i>\r\n </button>\r\n </div>\r\n </th>\r\n }\r\n @if (actions().length > 0) {\r\n <th class=\"bg-dark text-center\">Acciones</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of pagedData(); track row.id) {\r\n <tr>\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col);\r\n <!-- <td>{{ $any(row)[col] }}</td> -->\r\n\r\n <td class=\"py-2 px-3 border-end\">\r\n <div [class.fw-bold]=\"config?.bold\" class=\"text-dark\">\r\n @switch (config?.type) {\r\n @case ('date') {\r\n {{ $any(row)[col] | safeDate }}\r\n }\r\n @case ('currency') {\r\n {{ $any(row)[col] | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ $any(row)[col] | safeNumber }}\r\n }\r\n @default {\r\n {{ $any(row)[col] }}\r\n }\r\n }\r\n </div>\r\n <!-- {{ $any(row)[col] }} -->\r\n </td>\r\n }\r\n @if (actions().length > 0) {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track action.label) {\r\n @if (!action.showIf || action.showIf(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.class\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i>\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n @if (hasFootData()) {\r\n <tfoot class=\"bg-light fw-bold border-top\">\r\n <tr>\r\n @for (col of displayedColumns(); track col) {\r\n @let config = getConfig(col); @let footValue = footData()[col];\r\n\r\n <td class=\"py-2 px-3 border-end text-dark\">\r\n @if (footValue !== undefined && footValue !== null) {\r\n @switch (config?.type) {\r\n @case ('currency') {\r\n {{ footValue | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ footValue | safeNumber }}\r\n }\r\n @default {\r\n {{ footValue }}\r\n }\r\n }\r\n }\r\n </td>\r\n }\r\n @if (actions().length > 0) {\r\n <td class=\"bg-light\"></td>\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n </table>\r\n <!-- </div> -->\r\n</div>\r\n<nav>\r\n <ul class=\"pagination pagination-sm mb-0\">\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === 1\">\r\n <button class=\"page-link\" (click)=\"goToPage(currentPage() - 1)\">Anterior</button>\r\n </li>\r\n\r\n @for (p of pagesArray(); track $index) {\r\n @if (p === '...') {\r\n <li class=\"page-item disabled\"><span class=\"page-link\">...</span></li>\r\n } @else {\r\n <li class=\"page-item\" [class.active]=\"currentPage() === p\">\r\n <button class=\"page-link\" (click)=\"goToPage(p)\">{{ p }}</button>\r\n </li>\r\n }\r\n }\r\n\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === totalPages()\">\r\n <button class=\"page-link\" (click)=\"goToPage(currentPage() + 1)\">Siguiente</button>\r\n </li>\r\n </ul>\r\n</nav>\r\n@if (showModal()) {\r\n <mdl-modal-generic\r\n [textTitle]=\"'Filtrar: ' + activeFilterColumn()\"\r\n [showFooter]=\"false\"\r\n modalSize=\"md\"\r\n >\r\n <ng-container buttonclose>\r\n <button type=\"button\" class=\"btn-close py-0\" (click)=\"showModal.set(false)\"></button>\r\n </ng-container>\r\n\r\n <ng-container body>\r\n <div class=\"px-2\">\r\n <div class=\"form-check mb-3\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n id=\"all-modal\"\r\n [checked]=\"isAllSelected(activeFilterColumn())\"\r\n (change)=\"toggleAll(activeFilterColumn())\"\r\n />\r\n <label class=\"form-check-label fw-bold\" for=\"all-modal\">(Seleccionar todo)</label>\r\n </div>\r\n <hr />\r\n <div style=\"max-height: 300px; overflow-y: auto\" class=\"custom-scroll\">\r\n @for (val of uniqueValuesMap()[activeFilterColumn()]; track val) {\r\n <div class=\"form-check py-1\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"'check-' + val\"\r\n [checked]=\"filters()[activeFilterColumn()]?.includes(val)\"\r\n (change)=\"toggleFilter(activeFilterColumn(), val)\"\r\n />\r\n <label class=\"form-check-label\" [for]=\"'check-' + val\">{{ val }}</label>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ng-container>\r\n </mdl-modal-generic>\r\n}\r\n","/*\r\n * Public API Surface of generic-table-drag-and-drop\r\n */\r\n\r\nexport * from './lib/generic-table-drag-and-drop';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@ddiazr/generic-table-drag-and-drop",
3
+ "version": "0.0.1",
4
+ "description": "Tabla generica que puede hacer drag and drop, acciones, export PDF,EXCEl",
5
+ "author": {
6
+ "name": "Dany Díaz",
7
+ "email": "danylen1@hotmail.com"
8
+ },
9
+ "license": "MIT",
10
+ "peerDependencies": {
11
+ "@angular/common": "^21.1.0",
12
+ "@angular/core": "^21.1.0",
13
+ "@angular/cdk": "^21.1.2",
14
+ "bootstrap": "^5.3.8",
15
+ "@fortawesome/fontawesome-free": "^7.1.0",
16
+ "jspdf": "^4.0.0",
17
+ "jspdf-autotable": "^5.0.7",
18
+ "xlsx": "^0.18.5"
19
+ },
20
+ "dependencies": {
21
+ "tslib": "^2.3.0"
22
+ },
23
+ "sideEffects": false,
24
+ "module": "fesm2022/ddiazr-generic-table-drag-and-drop.mjs",
25
+ "typings": "types/ddiazr-generic-table-drag-and-drop.d.ts",
26
+ "exports": {
27
+ "./package.json": {
28
+ "default": "./package.json"
29
+ },
30
+ ".": {
31
+ "types": "./types/ddiazr-generic-table-drag-and-drop.d.ts",
32
+ "default": "./fesm2022/ddiazr-generic-table-drag-and-drop.mjs"
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,61 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { CdkDragDrop } from '@angular/cdk/drag-drop';
3
+
4
+ interface TableAction<T> {
5
+ label: string;
6
+ icon: string;
7
+ class: string;
8
+ callback: (row: T) => void;
9
+ showIf?: (row: T) => boolean;
10
+ }
11
+ interface ColumnConfig {
12
+ key: string;
13
+ label: string;
14
+ type?: 'text' | 'number' | 'currency' | 'date';
15
+ bold?: boolean;
16
+ }
17
+
18
+ declare class GenericTableDragAndDrop<T extends {
19
+ id: any;
20
+ }> {
21
+ data: _angular_core.InputSignal<T[]>;
22
+ columnsConfig: _angular_core.InputSignal<ColumnConfig[]>;
23
+ footData: _angular_core.InputSignal<Record<string, any>>;
24
+ actions: _angular_core.InputSignal<TableAction<T>[]>;
25
+ exportExcel: _angular_core.InputSignal<boolean>;
26
+ exportPdf: _angular_core.InputSignal<boolean>;
27
+ nameExport: _angular_core.InputSignal<string>;
28
+ pageSize: _angular_core.InputSignal<number>;
29
+ displayedColumns: _angular_core.WritableSignal<string[]>;
30
+ availableColumns: _angular_core.WritableSignal<string[]>;
31
+ globalFilter: _angular_core.WritableSignal<string>;
32
+ filters: _angular_core.WritableSignal<Record<string, string[]>>;
33
+ sortConfig: _angular_core.WritableSignal<{
34
+ column: string;
35
+ direction: "asc" | "desc" | null;
36
+ }>;
37
+ activeFilterColumn: _angular_core.WritableSignal<string>;
38
+ showModal: _angular_core.WritableSignal<boolean>;
39
+ currentPage: _angular_core.WritableSignal<number>;
40
+ constructor();
41
+ filteredData: _angular_core.Signal<T[]>;
42
+ uniqueValuesMap: _angular_core.Signal<Record<string, string[]>>;
43
+ pagedData: _angular_core.Signal<T[]>;
44
+ totalPages: _angular_core.Signal<number>;
45
+ pagesArray: _angular_core.Signal<(string | number)[]>;
46
+ hasFootData: _angular_core.Signal<boolean>;
47
+ getConfig(key: string): ColumnConfig | undefined;
48
+ drop(event: CdkDragDrop<string[]>): void;
49
+ toggleSort(col: string): void;
50
+ toggleFilter(column: string, value: string): void;
51
+ isAllSelected(column: string): boolean;
52
+ toggleAll(column: string): void;
53
+ exportToExcel(): void;
54
+ exportToPDF(): void;
55
+ resetAllFilters(): void;
56
+ goToPage(page: number | string): void;
57
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<GenericTableDragAndDrop<any>, never>;
58
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<GenericTableDragAndDrop<any>, "tbl-generic-drag-and-drop", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; "columnsConfig": { "alias": "columnsConfig"; "required": false; "isSignal": true; }; "footData": { "alias": "footData"; "required": false; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; "exportExcel": { "alias": "exportExcel"; "required": false; "isSignal": true; }; "exportPdf": { "alias": "exportPdf"; "required": false; "isSignal": true; }; "nameExport": { "alias": "nameExport"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; }, {}, never, ["[buttonsexport]"], true, never>;
59
+ }
60
+
61
+ export { GenericTableDragAndDrop };