@ddiazr/data-table 0.0.4 → 0.0.6
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
CHANGED
|
@@ -39,14 +39,17 @@ interface TableColumn<T> {
|
|
|
39
39
|
|
|
40
40
|
## Campos
|
|
41
41
|
|
|
42
|
-
| Propiedad
|
|
43
|
-
|
|
|
44
|
-
| `data`
|
|
45
|
-
| `columns`
|
|
46
|
-
| `filterPlaceholder`
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
|
|
42
|
+
| Propiedad | Tipo | Obligatorio | Descripción |
|
|
43
|
+
| ------------------------ | ---------------- | ----------- | ------------------------------------------------------ |
|
|
44
|
+
| `data` | `any[]` | ✅ Sí | Json que contendra la tabla |
|
|
45
|
+
| `columns` | `ColumnConfig[]` | ✅ Sí | Columnas que seran parametrizadas a mostrar al usuario |
|
|
46
|
+
| `filterPlaceholder` | `string` | ❌ No | Si necesita cambiar al buscador el placeholder |
|
|
47
|
+
| `showExportButtonsExcel` | `boolean` | ❌ No | Boton para exportar a excel |
|
|
48
|
+
| `showExportButtonsPdf` | `boolean` | ❌ No | Boton para exportar a pdf |
|
|
49
|
+
|
|
50
|
+
| `nameExportFile` | `string` | ❌ No | Nombre del archivo a descargar |
|
|
51
|
+
| `actions` | `TableAction<T>[]` | ❌ No | Funcion que devuelve la accion segun el columnsConfig |
|
|
52
|
+
| `positionActions` | `Position` | ❌ No | La posicion de los botones action. start(primera columna), end (ultima columna) |
|
|
50
53
|
|
|
51
54
|
## Uso básico
|
|
52
55
|
|
|
@@ -61,7 +64,8 @@ import { DataTable, TableColumn, TableAction, DataType, Position } from '@ddiazr
|
|
|
61
64
|
[columns]="columns()"
|
|
62
65
|
[actions]="actions()"
|
|
63
66
|
filterPlaceholder="BUSCAR POR"
|
|
64
|
-
[
|
|
67
|
+
[showExportButtonsExcel]="true"
|
|
68
|
+
nameExportFile="prueba"
|
|
65
69
|
/>
|
|
66
70
|
`,
|
|
67
71
|
})
|
|
@@ -4,6 +4,9 @@ import * as i0 from '@angular/core';
|
|
|
4
4
|
import { Pipe, input, output, signal, computed, Component } from '@angular/core';
|
|
5
5
|
import * as i2 from '@angular/forms';
|
|
6
6
|
import { FormsModule } from '@angular/forms';
|
|
7
|
+
import * as XLSX from 'xlsx';
|
|
8
|
+
import jsPDF from 'jspdf';
|
|
9
|
+
import autoTable from 'jspdf-autotable';
|
|
7
10
|
|
|
8
11
|
class SafeDatePipe {
|
|
9
12
|
transform(value) {
|
|
@@ -79,13 +82,14 @@ class DataTable {
|
|
|
79
82
|
columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
80
83
|
actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
|
|
81
84
|
filterPlaceholder = input('Buscar...', ...(ngDevMode ? [{ debugName: "filterPlaceholder" }] : []));
|
|
82
|
-
|
|
85
|
+
showExportButtonsExcel = input(false, ...(ngDevMode ? [{ debugName: "showExportButtonsExcel" }] : []));
|
|
86
|
+
showExportButtonsPdf = input(false, ...(ngDevMode ? [{ debugName: "showExportButtonsPdf" }] : []));
|
|
87
|
+
nameExportFile = input("", ...(ngDevMode ? [{ debugName: "nameExportFile" }] : []));
|
|
83
88
|
positionActions = input('end', ...(ngDevMode ? [{ debugName: "positionActions" }] : []));
|
|
84
89
|
// ------------------------------------
|
|
85
90
|
// II. OUTPUTS (Usando la función output())
|
|
86
91
|
// ------------------------------------
|
|
87
92
|
actionClicked = output();
|
|
88
|
-
exportRequested = output();
|
|
89
93
|
// ------------------------------------
|
|
90
94
|
// III. ESTADO INTERNO (Signals para Filtrado)
|
|
91
95
|
// ------------------------------------
|
|
@@ -196,8 +200,45 @@ class DataTable {
|
|
|
196
200
|
* FUNCIÓN DE EXPORTACIÓN
|
|
197
201
|
* Emite el evento de salida, delegando la lógica al padre.
|
|
198
202
|
*/
|
|
199
|
-
|
|
200
|
-
this.
|
|
203
|
+
exportToExcel() {
|
|
204
|
+
const data = this.filteredData();
|
|
205
|
+
const columns = this.columns();
|
|
206
|
+
// 1. Mapear los datos del cuerpo
|
|
207
|
+
const dataToExport = data.map((row) => {
|
|
208
|
+
const filteredRow = {};
|
|
209
|
+
columns.forEach((col) => {
|
|
210
|
+
const headerName = this.getConfig(col.key.toString())?.label || col;
|
|
211
|
+
filteredRow[headerName.toString()] = row[col.key];
|
|
212
|
+
});
|
|
213
|
+
return filteredRow;
|
|
214
|
+
});
|
|
215
|
+
const worksheet = XLSX.utils.json_to_sheet(dataToExport);
|
|
216
|
+
const workbook = XLSX.utils.book_new();
|
|
217
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, 'Reporte');
|
|
218
|
+
XLSX.writeFile(workbook, `${this.nameExportFile()}_${new Date().getTime()}.xlsx`);
|
|
219
|
+
}
|
|
220
|
+
exportToPDF() {
|
|
221
|
+
const doc = new jsPDF('l', 'mm', 'a4');
|
|
222
|
+
const data = this.filteredData();
|
|
223
|
+
const columns = this.columns();
|
|
224
|
+
const headers = columns.map((col) => this.getConfig(col.key.toString())?.label || col.label);
|
|
225
|
+
// Datos del cuerpo
|
|
226
|
+
const rows = data.map((row) => columns.map((col) => row[col.key]));
|
|
227
|
+
// Fila del pie de página mapeada según el orden de las columnas visibles
|
|
228
|
+
autoTable(doc, {
|
|
229
|
+
head: [headers],
|
|
230
|
+
body: rows,
|
|
231
|
+
foot: [], // Pasamos el pie aquí
|
|
232
|
+
theme: 'grid',
|
|
233
|
+
headStyles: { fillColor: [13, 110, 253] }, // Azul
|
|
234
|
+
footStyles: {
|
|
235
|
+
fillColor: [240, 240, 240], // Gris claro para resaltar
|
|
236
|
+
textColor: [0, 0, 0],
|
|
237
|
+
fontStyle: 'bold',
|
|
238
|
+
},
|
|
239
|
+
styles: { fontSize: 8, cellPadding: 2 },
|
|
240
|
+
});
|
|
241
|
+
doc.save(`${this.nameExportFile()}_${new Date().getTime()}.pdf`);
|
|
201
242
|
}
|
|
202
243
|
getConfig(key) {
|
|
203
244
|
return this.columns().find((c) => c.key === key);
|
|
@@ -216,12 +257,12 @@ class DataTable {
|
|
|
216
257
|
this.currentPage.set(1);
|
|
217
258
|
}
|
|
218
259
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DataTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
219
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: DataTable, isStandalone: true, selector: "dtbl-data-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null },
|
|
260
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: DataTable, isStandalone: true, selector: "dtbl-data-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, showExportButtonsExcel: { classPropertyName: "showExportButtonsExcel", publicName: "showExportButtonsExcel", isSignal: true, isRequired: false, transformFunction: null }, showExportButtonsPdf: { classPropertyName: "showExportButtonsPdf", publicName: "showExportButtonsPdf", isSignal: true, isRequired: false, transformFunction: null }, nameExportFile: { classPropertyName: "nameExportFile", publicName: "nameExportFile", isSignal: true, isRequired: false, transformFunction: null }, positionActions: { classPropertyName: "positionActions", publicName: "positionActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClicked: "actionClicked" }, ngImport: i0, template: "<div class=\"container-fluid pt-3\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control w-25\"\r\n [placeholder]=\"filterPlaceholder()\"\r\n [ngModel]=\"filterTerm()\"\r\n (ngModelChange)=\"onSearchChange($event)\"\r\n />\r\n\r\n <div class=\"export-buttons btn-group\" role=\"group\">\r\n @if (showExportButtonsExcel()) {\r\n <button class=\"btn btn-outline-success\" (click)=\"exportToExcel()\">\r\n <i class=\"fa fa-file-excel\"></i> Exportar a Excel\r\n </button>\r\n }\r\n @if (showExportButtonsPdf()) {\r\n <button class=\"btn btn-outline-danger\" (click)=\"exportToPDF()\">\r\n <i class=\"fa fa-file-pdf\"></i> Exportar a PDF\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-hover table-bordered caption-top\">\r\n <caption>\r\n Mostrando\r\n {{\r\n paginatedData().length\r\n }}\r\n de\r\n {{\r\n sortedAndFilteredData().length\r\n }}\r\n resultados (Total:\r\n {{\r\n data().length\r\n }}).\r\n </caption>\r\n\r\n <thead>\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <th\r\n [class.sortable]=\"col.isSortable\"\r\n (click)=\"col.isSortable && onSort(col.key)\"\r\n scope=\"col\"\r\n class=\"text-nowrap\"\r\n >\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span class=\"fw-bold\">{{ col.label }}</span>\r\n\r\n @if (col.isSortable) {\r\n @if (col.key === sortState().column) {\r\n <i\r\n class=\"fa fa-solid ms-1\"\r\n [class.fa-sort-up]=\"sortState().direction === 'asc'\"\r\n [class.fa-sort-down]=\"sortState().direction === 'desc'\"\r\n >\r\n </i>\r\n } @else {\r\n <i class=\"fa fa-solid fa-sort text-muted ms-1\" style=\"opacity: 0.5\"></i>\r\n }\r\n }\r\n </div>\r\n </th>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of paginatedData(); track row.id || $index) {\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action.label }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <td class=\"text-nowrap\">\r\n @if (col.templateRef) {\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n col.templateRef;\r\n context: { $implicit: row, column: col.key }\r\n \"\r\n ></ng-container>\r\n } @else {\r\n <!-- {{ formatCellValue(row, col) }} -->\r\n @let config = getConfig(col.key.toString());\r\n @switch (config?.dataType) {\r\n @case ('date') {\r\n {{ $any(row)[col.key] | safeDate }}\r\n }\r\n @case ('currency') {\r\n {{ $any(row)[col.key] | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ $any(row)[col.key] | safeNumber }}\r\n }\r\n @default {\r\n {{ $any(row)[col.key] }}\r\n }\r\n }\r\n }\r\n </td>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action.label }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n </tr>\r\n } @empty {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\" class=\"text-center\">\r\n No hay datos disponibles para mostrar.\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <label for=\"pageSizeSelect\" class=\"me-2 text-nowrap\">Art\u00EDculos por p\u00E1gina: </label>\r\n <select\r\n id=\"pageSizeSelect\"\r\n class=\"form-select form-select-sm w-auto\"\r\n (change)=\"onPageSizeChange($event)\"\r\n >\r\n <option value=\"10\" [selected]=\"pageSize() === 10\">10</option>\r\n <option value=\"25\" [selected]=\"pageSize() === 25\">25</option>\r\n <option value=\"50\" [selected]=\"pageSize() === 50\">50</option>\r\n <option value=\"100\" [selected]=\"pageSize() === 100\">100</option>\r\n </select>\r\n </div>\r\n\r\n <nav aria-label=\"Paginaci\u00F3n de tabla\">\r\n <ul class=\"pagination pagination-md mb-0\">\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === 1\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() - 1)\"><<</button>\r\n </li>\r\n\r\n @for (pageNumber of pagesToShow(); track pageNumber) {\r\n <li class=\"page-item\" [class.active]=\"currentPage() === pageNumber\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(pageNumber)\">\r\n {{ pageNumber }}\r\n </button>\r\n </li>\r\n }\r\n\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === totalPages()\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() + 1)\">>></button>\r\n </li>\r\n </ul>\r\n </nav>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: SafeDatePipe, name: "safeDate" }, { kind: "pipe", type: SafeCurrencyPipe, name: "safeCurrency" }, { kind: "pipe", type: SafeNumberPipe, name: "safeNumber" }] });
|
|
220
261
|
}
|
|
221
262
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DataTable, decorators: [{
|
|
222
263
|
type: Component,
|
|
223
|
-
args: [{ selector: 'dtbl-data-table', imports: [CommonModule, FormsModule, SafeDatePipe, SafeCurrencyPipe, SafeNumberPipe], template: "<div class=\"container-fluid pt-3\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control w-25\"\r\n [placeholder]=\"filterPlaceholder()\"\r\n [ngModel]=\"filterTerm()\"\r\n (ngModelChange)=\"onSearchChange($event)\"\r\n />\r\n\r\n
|
|
224
|
-
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }],
|
|
264
|
+
args: [{ selector: 'dtbl-data-table', imports: [CommonModule, FormsModule, SafeDatePipe, SafeCurrencyPipe, SafeNumberPipe], template: "<div class=\"container-fluid pt-3\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control w-25\"\r\n [placeholder]=\"filterPlaceholder()\"\r\n [ngModel]=\"filterTerm()\"\r\n (ngModelChange)=\"onSearchChange($event)\"\r\n />\r\n\r\n <div class=\"export-buttons btn-group\" role=\"group\">\r\n @if (showExportButtonsExcel()) {\r\n <button class=\"btn btn-outline-success\" (click)=\"exportToExcel()\">\r\n <i class=\"fa fa-file-excel\"></i> Exportar a Excel\r\n </button>\r\n }\r\n @if (showExportButtonsPdf()) {\r\n <button class=\"btn btn-outline-danger\" (click)=\"exportToPDF()\">\r\n <i class=\"fa fa-file-pdf\"></i> Exportar a PDF\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-hover table-bordered caption-top\">\r\n <caption>\r\n Mostrando\r\n {{\r\n paginatedData().length\r\n }}\r\n de\r\n {{\r\n sortedAndFilteredData().length\r\n }}\r\n resultados (Total:\r\n {{\r\n data().length\r\n }}).\r\n </caption>\r\n\r\n <thead>\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <th\r\n [class.sortable]=\"col.isSortable\"\r\n (click)=\"col.isSortable && onSort(col.key)\"\r\n scope=\"col\"\r\n class=\"text-nowrap\"\r\n >\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span class=\"fw-bold\">{{ col.label }}</span>\r\n\r\n @if (col.isSortable) {\r\n @if (col.key === sortState().column) {\r\n <i\r\n class=\"fa fa-solid ms-1\"\r\n [class.fa-sort-up]=\"sortState().direction === 'asc'\"\r\n [class.fa-sort-down]=\"sortState().direction === 'desc'\"\r\n >\r\n </i>\r\n } @else {\r\n <i class=\"fa fa-solid fa-sort text-muted ms-1\" style=\"opacity: 0.5\"></i>\r\n }\r\n }\r\n </div>\r\n </th>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of paginatedData(); track row.id || $index) {\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action.label }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <td class=\"text-nowrap\">\r\n @if (col.templateRef) {\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n col.templateRef;\r\n context: { $implicit: row, column: col.key }\r\n \"\r\n ></ng-container>\r\n } @else {\r\n <!-- {{ formatCellValue(row, col) }} -->\r\n @let config = getConfig(col.key.toString());\r\n @switch (config?.dataType) {\r\n @case ('date') {\r\n {{ $any(row)[col.key] | safeDate }}\r\n }\r\n @case ('currency') {\r\n {{ $any(row)[col.key] | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ $any(row)[col.key] | safeNumber }}\r\n }\r\n @default {\r\n {{ $any(row)[col.key] }}\r\n }\r\n }\r\n }\r\n </td>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action.label }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n </tr>\r\n } @empty {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\" class=\"text-center\">\r\n No hay datos disponibles para mostrar.\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <label for=\"pageSizeSelect\" class=\"me-2 text-nowrap\">Art\u00EDculos por p\u00E1gina: </label>\r\n <select\r\n id=\"pageSizeSelect\"\r\n class=\"form-select form-select-sm w-auto\"\r\n (change)=\"onPageSizeChange($event)\"\r\n >\r\n <option value=\"10\" [selected]=\"pageSize() === 10\">10</option>\r\n <option value=\"25\" [selected]=\"pageSize() === 25\">25</option>\r\n <option value=\"50\" [selected]=\"pageSize() === 50\">50</option>\r\n <option value=\"100\" [selected]=\"pageSize() === 100\">100</option>\r\n </select>\r\n </div>\r\n\r\n <nav aria-label=\"Paginaci\u00F3n de tabla\">\r\n <ul class=\"pagination pagination-md mb-0\">\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === 1\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() - 1)\"><<</button>\r\n </li>\r\n\r\n @for (pageNumber of pagesToShow(); track pageNumber) {\r\n <li class=\"page-item\" [class.active]=\"currentPage() === pageNumber\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(pageNumber)\">\r\n {{ pageNumber }}\r\n </button>\r\n </li>\r\n }\r\n\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === totalPages()\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() + 1)\">>></button>\r\n </li>\r\n </ul>\r\n </nav>\r\n </div>\r\n</div>\r\n" }]
|
|
265
|
+
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], showExportButtonsExcel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExportButtonsExcel", required: false }] }], showExportButtonsPdf: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExportButtonsPdf", required: false }] }], nameExportFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "nameExportFile", required: false }] }], positionActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "positionActions", required: false }] }], actionClicked: [{ type: i0.Output, args: ["actionClicked"] }] } });
|
|
225
266
|
|
|
226
267
|
/**
|
|
227
268
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ddiazr-data-table.mjs","sources":["../../../projects/data-table/src/lib/pipes/safe-date.pipe.ts","../../../projects/data-table/src/lib/pipes/safe-currency.pipe.ts","../../../projects/data-table/src/lib/pipes/safe-number.pipe.ts","../../../projects/data-table/src/lib/data-table.ts","../../../projects/data-table/src/lib/data-table.html","../../../projects/data-table/src/ddiazr-data-table.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 { Component, computed, input, output, signal, WritableSignal } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { SortDirection, TableColumn, SortState, TableAction, Position } from './interfaces/table.interface';\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\n@Component({\r\n selector: 'dtbl-data-table',\r\n imports: [CommonModule, FormsModule, SafeDatePipe, SafeCurrencyPipe, SafeNumberPipe],\r\n templateUrl: './data-table.html',\r\n styles: ``,\r\n})\r\nexport class DataTable<T extends { id?: any }> {\r\n // ------------------------------------\r\n // I. INPUT SIGNALS\r\n // ------------------------------------\r\n public data = input.required<T[]>();\r\n public columns = input.required<TableColumn<T>[]>();\r\n public actions = input<TableAction<T>[]>([]);\r\n public filterPlaceholder = input<string>('Buscar...');\r\n public showExportButtons = input<boolean>(false);\r\n public positionActions = input<Position>('end');\r\n\r\n // ------------------------------------\r\n // II. OUTPUTS (Usando la función output())\r\n // ------------------------------------\r\n public actionClicked = output<{ action: string; rowData: T }>();\r\n public exportRequested = output<'pdf' | 'excel' | 'print'>();\r\n\r\n // ------------------------------------\r\n // III. ESTADO INTERNO (Signals para Filtrado)\r\n // ------------------------------------\r\n\r\n public filterTerm: WritableSignal<string> = signal('');\r\n public sortState: WritableSignal<SortState<T>> = signal({\r\n column: null,\r\n direction: null,\r\n });\r\n\r\n public currentPage: WritableSignal<number> = signal(1); // Página actual, inicia en 1\r\n public pageSize: WritableSignal<number> = signal(10); // Elementos por página\r\n\r\n // 4. Datos filtrados (Computed Signal - LÓGICA DE BÚSQUEDA)\r\n public filteredData = computed(() => {\r\n const term = this.filterTerm().toLowerCase();\r\n const currentData = this.data();\r\n\r\n if (!term) return currentData;\r\n\r\n return currentData.filter((item) =>\r\n Object.values(item as object).some((value) => String(value).toLowerCase().includes(term)),\r\n );\r\n });\r\n\r\n public sortedAndFilteredData = computed(() => {\r\n const data = [...this.filteredData()]; // Copia para ordenar\r\n const state = this.sortState();\r\n\r\n if (!state.column || !state.direction) {\r\n return data; // Sin ordenamiento\r\n }\r\n\r\n const directionMultiplier = state.direction === 'asc' ? 1 : -1;\r\n const columnKey = state.column as keyof T;\r\n\r\n return data.sort((a, b) => {\r\n // Usamos localeCompare para ordenar strings correctamente, si no, comparación simple\r\n const aValue = a[columnKey];\r\n const bValue = b[columnKey];\r\n\r\n if (typeof aValue === 'string' && typeof bValue === 'string') {\r\n return aValue.localeCompare(bValue) * directionMultiplier;\r\n }\r\n\r\n if (aValue < bValue) {\r\n return -1 * directionMultiplier;\r\n }\r\n if (aValue > bValue) {\r\n return 1 * directionMultiplier;\r\n }\r\n return 0;\r\n });\r\n });\r\n\r\n public paginatedData = computed(() => {\r\n const data = this.sortedAndFilteredData();\r\n const size = this.pageSize();\r\n const page = this.currentPage();\r\n\r\n const start = (page - 1) * size;\r\n const end = start + size;\r\n\r\n // Retorna solo el slice (rebanada) de datos de la página actual\r\n return data.slice(start, end);\r\n });\r\n\r\n public totalPages = computed(() => {\r\n const totalItems = this.sortedAndFilteredData().length;\r\n const size = this.pageSize();\r\n return Math.ceil(totalItems / size);\r\n });\r\n\r\n public pagesToShow = computed<number[]>(() => {\r\n const total = this.totalPages();\r\n const current = this.currentPage();\r\n const maxPagesToShow = 5; // Máximo de botones numéricos a mostrar\r\n const pages: number[] = [];\r\n\r\n // Lógica simple para centrar los botones en la página actual\r\n let start = Math.max(1, current - Math.floor(maxPagesToShow / 2));\r\n let end = Math.min(total, start + maxPagesToShow - 1);\r\n\r\n // Ajuste si la tabla es pequeña\r\n if (end - start + 1 < maxPagesToShow) {\r\n start = Math.max(1, end - maxPagesToShow + 1);\r\n }\r\n\r\n for (let i = start; i <= end; i++) {\r\n pages.push(i);\r\n }\r\n return pages;\r\n });\r\n\r\n // ------------------------------------\r\n // IV. FUNCIONES\r\n // ------------------------------------\r\n onSort(columnKey: keyof T | 'actions' | 'select'): void {\r\n // Solo permitir ordenar si no es una columna de acción/selección\r\n if (columnKey === 'actions' || columnKey === 'select') return;\r\n\r\n this.sortState.update((current) => {\r\n let newDirection: SortDirection = 'asc';\r\n\r\n if (current.column === columnKey) {\r\n // Mismo column, se alterna la dirección\r\n newDirection = current.direction === 'asc' ? 'desc' : 'asc';\r\n }\r\n\r\n return {\r\n column: columnKey as keyof T,\r\n direction: newDirection,\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * FUNCIÓN DE BÚSQUEDA\r\n * Actualiza el WritableSignal interno.\r\n */\r\n onSearchChange(term: string): void {\r\n this.filterTerm.set(term);\r\n }\r\n\r\n /**\r\n * FUNCIÓN DE ACCIONES\r\n * Emite el evento usando .emit() del Output Signal.\r\n */\r\n onActionClick(action: string, rowData: T): void {\r\n this.actionClicked.emit({ action, rowData });\r\n }\r\n\r\n /**\r\n * FUNCIÓN DE EXPORTACIÓN\r\n * Emite el evento de salida, delegando la lógica al padre.\r\n */\r\n exportData(format: 'pdf' | 'excel' | 'print'): void {\r\n this.exportRequested.emit(format);\r\n }\r\n\r\n getConfig(key: string): TableColumn<T> | undefined {\r\n return this.columns().find((c) => c.key === key);\r\n }\r\n\r\n goToPage(page: number): void {\r\n const total = this.totalPages();\r\n if (page >= 1 && page <= total) {\r\n this.currentPage.set(page);\r\n }\r\n }\r\n\r\n onPageSizeChange(event: Event): void {\r\n const target = event.target as HTMLSelectElement;\r\n const newSize = Number(target.value);\r\n\r\n this.pageSize.set(newSize);\r\n // Reiniciar a la página 1 después de cambiar el tamaño para evitar errores de índice\r\n this.currentPage.set(1);\r\n }\r\n}\r\n","<div class=\"container-fluid pt-3\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control w-25\"\r\n [placeholder]=\"filterPlaceholder()\"\r\n [ngModel]=\"filterTerm()\"\r\n (ngModelChange)=\"onSearchChange($event)\"\r\n />\r\n\r\n @if (showExportButtons()) {\r\n <div class=\"export-buttons btn-group\" role=\"group\">\r\n <button class=\"btn btn-outline-success\" (click)=\"exportData('excel')\">\r\n <i class=\"fa fa-file-excel\"></i> Exportar a Excel\r\n </button>\r\n <button class=\"btn btn-outline-danger\" (click)=\"exportData('pdf')\">\r\n <i class=\"fa fa-file-pdf\"></i> Exportar a PDF\r\n </button>\r\n <button class=\"btn btn-outline-secondary\" (click)=\"exportData('print')\">\r\n <i class=\"fa fa-print\"></i> Imprimir\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-hover table-bordered caption-top\">\r\n <caption>\r\n Mostrando\r\n {{\r\n paginatedData().length\r\n }}\r\n de\r\n {{\r\n sortedAndFilteredData().length\r\n }}\r\n resultados (Total:\r\n {{\r\n data().length\r\n }}).\r\n </caption>\r\n\r\n <thead>\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <th\r\n [class.sortable]=\"col.isSortable\"\r\n (click)=\"col.isSortable && onSort(col.key)\"\r\n scope=\"col\"\r\n class=\"text-nowrap\"\r\n >\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span class=\"fw-bold\">{{ col.label }}</span>\r\n\r\n @if (col.isSortable) {\r\n @if (col.key === sortState().column) {\r\n <i\r\n class=\"fa fa-solid ms-1\"\r\n [class.fa-sort-up]=\"sortState().direction === 'asc'\"\r\n [class.fa-sort-down]=\"sortState().direction === 'desc'\"\r\n >\r\n </i>\r\n } @else {\r\n <i class=\"fa fa-solid fa-sort text-muted ms-1\" style=\"opacity: 0.5\"></i>\r\n }\r\n }\r\n </div>\r\n </th>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of paginatedData(); track row.id || $index) {\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action?.label ?? '' }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <td class=\"text-nowrap\">\r\n @if (col.templateRef) {\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n col.templateRef;\r\n context: { $implicit: row, column: col.key }\r\n \"\r\n ></ng-container>\r\n } @else {\r\n <!-- {{ formatCellValue(row, col) }} -->\r\n @let config = getConfig(col.key.toString());\r\n @switch (config?.dataType) {\r\n @case ('date') {\r\n {{ $any(row)[col.key] | safeDate }}\r\n }\r\n @case ('currency') {\r\n {{ $any(row)[col.key] | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ $any(row)[col.key] | safeNumber }}\r\n }\r\n @default {\r\n {{ $any(row)[col.key] }}\r\n }\r\n }\r\n }\r\n </td>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action?.label ?? '' }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n </tr>\r\n } @empty {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\" class=\"text-center\">\r\n No hay datos disponibles para mostrar.\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <label for=\"pageSizeSelect\" class=\"me-2 text-nowrap\">Artículos por página: </label>\r\n <select\r\n id=\"pageSizeSelect\"\r\n class=\"form-select form-select-sm w-auto\"\r\n (change)=\"onPageSizeChange($event)\"\r\n >\r\n <option value=\"10\" [selected]=\"pageSize() === 10\">10</option>\r\n <option value=\"25\" [selected]=\"pageSize() === 25\">25</option>\r\n <option value=\"50\" [selected]=\"pageSize() === 50\">50</option>\r\n <option value=\"100\" [selected]=\"pageSize() === 100\">100</option>\r\n </select>\r\n </div>\r\n\r\n <nav aria-label=\"Paginación de tabla\">\r\n <ul class=\"pagination pagination-md mb-0\">\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === 1\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() - 1)\"><<</button>\r\n </li>\r\n\r\n @for (pageNumber of pagesToShow(); track pageNumber) {\r\n <li class=\"page-item\" [class.active]=\"currentPage() === pageNumber\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(pageNumber)\">\r\n {{ pageNumber }}\r\n </button>\r\n </li>\r\n }\r\n\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === totalPages()\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() + 1)\">>></button>\r\n </li>\r\n </ul>\r\n </nav>\r\n </div>\r\n</div>\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":"ddiazr-data-table.mjs","sources":["../../../projects/data-table/src/lib/pipes/safe-date.pipe.ts","../../../projects/data-table/src/lib/pipes/safe-currency.pipe.ts","../../../projects/data-table/src/lib/pipes/safe-number.pipe.ts","../../../projects/data-table/src/lib/data-table.ts","../../../projects/data-table/src/lib/data-table.html","../../../projects/data-table/src/ddiazr-data-table.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 { Component, computed, input, output, signal, WritableSignal } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { SortDirection, TableColumn, SortState, TableAction, Position } from './interfaces/table.interface';\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 * as XLSX from 'xlsx';\r\nimport jsPDF from 'jspdf';\r\nimport autoTable from 'jspdf-autotable';\r\n@Component({\r\n selector: 'dtbl-data-table',\r\n imports: [CommonModule, FormsModule, SafeDatePipe, SafeCurrencyPipe, SafeNumberPipe],\r\n templateUrl: './data-table.html',\r\n styles: ``,\r\n})\r\nexport class DataTable<T extends { id?: any }> {\r\n // ------------------------------------\r\n // I. INPUT SIGNALS\r\n // ------------------------------------\r\n public data = input.required<T[]>();\r\n public columns = input.required<TableColumn<T>[]>();\r\n public actions = input<TableAction<T>[]>([]);\r\n public filterPlaceholder = input<string>('Buscar...');\r\n public showExportButtonsExcel = input<boolean>(false);\r\n public showExportButtonsPdf = input<boolean>(false);\r\n public nameExportFile = input<string>(\"\");\r\n public positionActions = input<Position>('end');\r\n\r\n // ------------------------------------\r\n // II. OUTPUTS (Usando la función output())\r\n // ------------------------------------\r\n public actionClicked = output<{ action: string; rowData: T }>();\r\n\r\n // ------------------------------------\r\n // III. ESTADO INTERNO (Signals para Filtrado)\r\n // ------------------------------------\r\n\r\n public filterTerm: WritableSignal<string> = signal('');\r\n public sortState: WritableSignal<SortState<T>> = signal({\r\n column: null,\r\n direction: null,\r\n });\r\n\r\n public currentPage: WritableSignal<number> = signal(1); // Página actual, inicia en 1\r\n public pageSize: WritableSignal<number> = signal(10); // Elementos por página\r\n\r\n // 4. Datos filtrados (Computed Signal - LÓGICA DE BÚSQUEDA)\r\n public filteredData = computed(() => {\r\n const term = this.filterTerm().toLowerCase();\r\n const currentData = this.data();\r\n\r\n if (!term) return currentData;\r\n\r\n return currentData.filter((item) =>\r\n Object.values(item as object).some((value) => String(value).toLowerCase().includes(term)),\r\n );\r\n });\r\n\r\n public sortedAndFilteredData = computed(() => {\r\n const data = [...this.filteredData()]; // Copia para ordenar\r\n const state = this.sortState();\r\n\r\n if (!state.column || !state.direction) {\r\n return data; // Sin ordenamiento\r\n }\r\n\r\n const directionMultiplier = state.direction === 'asc' ? 1 : -1;\r\n const columnKey = state.column as keyof T;\r\n\r\n return data.sort((a, b) => {\r\n // Usamos localeCompare para ordenar strings correctamente, si no, comparación simple\r\n const aValue = a[columnKey];\r\n const bValue = b[columnKey];\r\n\r\n if (typeof aValue === 'string' && typeof bValue === 'string') {\r\n return aValue.localeCompare(bValue) * directionMultiplier;\r\n }\r\n\r\n if (aValue < bValue) {\r\n return -1 * directionMultiplier;\r\n }\r\n if (aValue > bValue) {\r\n return 1 * directionMultiplier;\r\n }\r\n return 0;\r\n });\r\n });\r\n\r\n public paginatedData = computed(() => {\r\n const data = this.sortedAndFilteredData();\r\n const size = this.pageSize();\r\n const page = this.currentPage();\r\n\r\n const start = (page - 1) * size;\r\n const end = start + size;\r\n\r\n // Retorna solo el slice (rebanada) de datos de la página actual\r\n return data.slice(start, end);\r\n });\r\n\r\n public totalPages = computed(() => {\r\n const totalItems = this.sortedAndFilteredData().length;\r\n const size = this.pageSize();\r\n return Math.ceil(totalItems / size);\r\n });\r\n\r\n public pagesToShow = computed<number[]>(() => {\r\n const total = this.totalPages();\r\n const current = this.currentPage();\r\n const maxPagesToShow = 5; // Máximo de botones numéricos a mostrar\r\n const pages: number[] = [];\r\n\r\n // Lógica simple para centrar los botones en la página actual\r\n let start = Math.max(1, current - Math.floor(maxPagesToShow / 2));\r\n let end = Math.min(total, start + maxPagesToShow - 1);\r\n\r\n // Ajuste si la tabla es pequeña\r\n if (end - start + 1 < maxPagesToShow) {\r\n start = Math.max(1, end - maxPagesToShow + 1);\r\n }\r\n\r\n for (let i = start; i <= end; i++) {\r\n pages.push(i);\r\n }\r\n return pages;\r\n });\r\n\r\n // ------------------------------------\r\n // IV. FUNCIONES\r\n // ------------------------------------\r\n onSort(columnKey: keyof T | 'actions' | 'select'): void {\r\n // Solo permitir ordenar si no es una columna de acción/selección\r\n if (columnKey === 'actions' || columnKey === 'select') return;\r\n\r\n this.sortState.update((current) => {\r\n let newDirection: SortDirection = 'asc';\r\n\r\n if (current.column === columnKey) {\r\n // Mismo column, se alterna la dirección\r\n newDirection = current.direction === 'asc' ? 'desc' : 'asc';\r\n }\r\n\r\n return {\r\n column: columnKey as keyof T,\r\n direction: newDirection,\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * FUNCIÓN DE BÚSQUEDA\r\n * Actualiza el WritableSignal interno.\r\n */\r\n onSearchChange(term: string): void {\r\n this.filterTerm.set(term);\r\n }\r\n\r\n /**\r\n * FUNCIÓN DE ACCIONES\r\n * Emite el evento usando .emit() del Output Signal.\r\n */\r\n onActionClick(action: string, rowData: T): void {\r\n this.actionClicked.emit({ action, rowData });\r\n }\r\n\r\n /**\r\n * FUNCIÓN DE EXPORTACIÓN\r\n * Emite el evento de salida, delegando la lógica al padre.\r\n */\r\n\r\n exportToExcel() {\r\n const data = this.filteredData();\r\n const columns = this.columns();\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.key.toString())?.label || col;\r\n filteredRow[headerName.toString()] = (row as any)[col.key];\r\n });\r\n return filteredRow;\r\n });\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.nameExportFile()}_${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.columns();\r\n\r\n const headers = columns.map((col) => this.getConfig(col.key.toString())?.label || col.label);\r\n\r\n // Datos del cuerpo\r\n const rows = data.map((row) => columns.map((col) => (row as any)[col.key]));\r\n\r\n // Fila del pie de página mapeada según el orden de las columnas visibles\r\n\r\n autoTable(doc, {\r\n head: [headers],\r\n body: rows,\r\n foot: [], // 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.nameExportFile()}_${new Date().getTime()}.pdf`);\r\n }\r\n\r\n\r\n\r\n getConfig(key: string): TableColumn<T> | undefined {\r\n return this.columns().find((c) => c.key === key);\r\n }\r\n\r\n goToPage(page: number): void {\r\n const total = this.totalPages();\r\n if (page >= 1 && page <= total) {\r\n this.currentPage.set(page);\r\n }\r\n }\r\n\r\n onPageSizeChange(event: Event): void {\r\n const target = event.target as HTMLSelectElement;\r\n const newSize = Number(target.value);\r\n\r\n this.pageSize.set(newSize);\r\n // Reiniciar a la página 1 después de cambiar el tamaño para evitar errores de índice\r\n this.currentPage.set(1);\r\n }\r\n}\r\n","<div class=\"container-fluid pt-3\">\r\n <div class=\"d-flex justify-content-between align-items-center mb-3\">\r\n <input\r\n type=\"text\"\r\n class=\"form-control w-25\"\r\n [placeholder]=\"filterPlaceholder()\"\r\n [ngModel]=\"filterTerm()\"\r\n (ngModelChange)=\"onSearchChange($event)\"\r\n />\r\n\r\n <div class=\"export-buttons btn-group\" role=\"group\">\r\n @if (showExportButtonsExcel()) {\r\n <button class=\"btn btn-outline-success\" (click)=\"exportToExcel()\">\r\n <i class=\"fa fa-file-excel\"></i> Exportar a Excel\r\n </button>\r\n }\r\n @if (showExportButtonsPdf()) {\r\n <button class=\"btn btn-outline-danger\" (click)=\"exportToPDF()\">\r\n <i class=\"fa fa-file-pdf\"></i> Exportar a PDF\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-hover table-bordered caption-top\">\r\n <caption>\r\n Mostrando\r\n {{\r\n paginatedData().length\r\n }}\r\n de\r\n {{\r\n sortedAndFilteredData().length\r\n }}\r\n resultados (Total:\r\n {{\r\n data().length\r\n }}).\r\n </caption>\r\n\r\n <thead>\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <th\r\n [class.sortable]=\"col.isSortable\"\r\n (click)=\"col.isSortable && onSort(col.key)\"\r\n scope=\"col\"\r\n class=\"text-nowrap\"\r\n >\r\n <div class=\"d-flex align-items-center justify-content-between\">\r\n <span class=\"fw-bold\">{{ col.label }}</span>\r\n\r\n @if (col.isSortable) {\r\n @if (col.key === sortState().column) {\r\n <i\r\n class=\"fa fa-solid ms-1\"\r\n [class.fa-sort-up]=\"sortState().direction === 'asc'\"\r\n [class.fa-sort-down]=\"sortState().direction === 'desc'\"\r\n >\r\n </i>\r\n } @else {\r\n <i class=\"fa fa-solid fa-sort text-muted ms-1\" style=\"opacity: 0.5\"></i>\r\n }\r\n }\r\n </div>\r\n </th>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <th class=\"bg-dark text-center text-white\">Acciones</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of paginatedData(); track row.id || $index) {\r\n <tr>\r\n @if (actions().length > 0 && positionActions() === 'start') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action.label }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n @for (col of columns(); track col.key) {\r\n <td class=\"text-nowrap\">\r\n @if (col.templateRef) {\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n col.templateRef;\r\n context: { $implicit: row, column: col.key }\r\n \"\r\n ></ng-container>\r\n } @else {\r\n <!-- {{ formatCellValue(row, col) }} -->\r\n @let config = getConfig(col.key.toString());\r\n @switch (config?.dataType) {\r\n @case ('date') {\r\n {{ $any(row)[col.key] | safeDate }}\r\n }\r\n @case ('currency') {\r\n {{ $any(row)[col.key] | safeCurrency }}\r\n }\r\n @case ('number') {\r\n {{ $any(row)[col.key] | safeNumber }}\r\n }\r\n @default {\r\n {{ $any(row)[col.key] }}\r\n }\r\n }\r\n }\r\n </td>\r\n }\r\n @if (actions().length > 0 && positionActions() === 'end') {\r\n <td class=\"text-center\">\r\n @for (action of actions(); track $index) {\r\n @if (!action.isVisible || action.isVisible(row)) {\r\n <button\r\n [class]=\"'btn btn-sm mx-1 ' + action.styleClass\"\r\n (click)=\"action.callback(row)\"\r\n >\r\n <i [class]=\"action.icon\"></i> {{ action.label }}\r\n </button>\r\n }\r\n }\r\n </td>\r\n }\r\n </tr>\r\n } @empty {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\" class=\"text-center\">\r\n No hay datos disponibles para mostrar.\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n <div class=\"d-flex align-items-center\">\r\n <label for=\"pageSizeSelect\" class=\"me-2 text-nowrap\">Artículos por página: </label>\r\n <select\r\n id=\"pageSizeSelect\"\r\n class=\"form-select form-select-sm w-auto\"\r\n (change)=\"onPageSizeChange($event)\"\r\n >\r\n <option value=\"10\" [selected]=\"pageSize() === 10\">10</option>\r\n <option value=\"25\" [selected]=\"pageSize() === 25\">25</option>\r\n <option value=\"50\" [selected]=\"pageSize() === 50\">50</option>\r\n <option value=\"100\" [selected]=\"pageSize() === 100\">100</option>\r\n </select>\r\n </div>\r\n\r\n <nav aria-label=\"Paginación de tabla\">\r\n <ul class=\"pagination pagination-md mb-0\">\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === 1\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() - 1)\"><<</button>\r\n </li>\r\n\r\n @for (pageNumber of pagesToShow(); track pageNumber) {\r\n <li class=\"page-item\" [class.active]=\"currentPage() === pageNumber\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(pageNumber)\">\r\n {{ pageNumber }}\r\n </button>\r\n </li>\r\n }\r\n\r\n <li class=\"page-item\" [class.disabled]=\"currentPage() === totalPages()\">\r\n <button type=\"button\" class=\"page-link\" (click)=\"goToPage(currentPage() + 1)\">>></button>\r\n </li>\r\n </ul>\r\n </nav>\r\n </div>\r\n</div>\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
CHANGED
|
@@ -41,13 +41,14 @@ declare class DataTable<T extends {
|
|
|
41
41
|
columns: _angular_core.InputSignal<TableColumn<T>[]>;
|
|
42
42
|
actions: _angular_core.InputSignal<TableAction<T>[]>;
|
|
43
43
|
filterPlaceholder: _angular_core.InputSignal<string>;
|
|
44
|
-
|
|
44
|
+
showExportButtonsExcel: _angular_core.InputSignal<boolean>;
|
|
45
|
+
showExportButtonsPdf: _angular_core.InputSignal<boolean>;
|
|
46
|
+
nameExportFile: _angular_core.InputSignal<string>;
|
|
45
47
|
positionActions: _angular_core.InputSignal<Position>;
|
|
46
48
|
actionClicked: _angular_core.OutputEmitterRef<{
|
|
47
49
|
action: string;
|
|
48
50
|
rowData: T;
|
|
49
51
|
}>;
|
|
50
|
-
exportRequested: _angular_core.OutputEmitterRef<"pdf" | "excel" | "print">;
|
|
51
52
|
filterTerm: WritableSignal<string>;
|
|
52
53
|
sortState: WritableSignal<SortState<T>>;
|
|
53
54
|
currentPage: WritableSignal<number>;
|
|
@@ -72,12 +73,13 @@ declare class DataTable<T extends {
|
|
|
72
73
|
* FUNCIÓN DE EXPORTACIÓN
|
|
73
74
|
* Emite el evento de salida, delegando la lógica al padre.
|
|
74
75
|
*/
|
|
75
|
-
|
|
76
|
+
exportToExcel(): void;
|
|
77
|
+
exportToPDF(): void;
|
|
76
78
|
getConfig(key: string): TableColumn<T> | undefined;
|
|
77
79
|
goToPage(page: number): void;
|
|
78
80
|
onPageSizeChange(event: Event): void;
|
|
79
81
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataTable<any>, never>;
|
|
80
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTable<any>, "dtbl-data-table", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "
|
|
82
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTable<any>, "dtbl-data-table", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "showExportButtonsExcel": { "alias": "showExportButtonsExcel"; "required": false; "isSignal": true; }; "showExportButtonsPdf": { "alias": "showExportButtonsPdf"; "required": false; "isSignal": true; }; "nameExportFile": { "alias": "nameExportFile"; "required": false; "isSignal": true; }; "positionActions": { "alias": "positionActions"; "required": false; "isSignal": true; }; }, { "actionClicked": "actionClicked"; }, never, never, true, never>;
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
export { DataTable };
|