@some-angular-utils/table 0.0.19 → 0.1.0
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 +29 -51
- package/fesm2022/some-angular-utils-table.mjs +191 -13
- package/fesm2022/some-angular-utils-table.mjs.map +1 -1
- package/index.d.ts +44 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,59 +1,37 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @some-angular-utils/table
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
|
+

|
|
4
5
|
|
|
5
|
-
|
|
6
|
+

|
|
7
|
+

|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
ng serve
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
|
|
14
|
-
|
|
15
|
-
## Code scaffolding
|
|
16
|
-
|
|
17
|
-
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
ng generate component component-name
|
|
9
|
+
## IMPORT
|
|
10
|
+
```ts
|
|
11
|
+
import { TableModule } from '@some-angular-utils/table';
|
|
21
12
|
```
|
|
22
13
|
|
|
23
|
-
|
|
14
|
+
## TYPESCRIPT
|
|
15
|
+
```ts
|
|
16
|
+
public url = 'https://pokeapi.co/api/v2/pokemon';
|
|
24
17
|
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
public headers = [
|
|
19
|
+
{ name: 'NOMBRE', key: 'name' },
|
|
20
|
+
{ name: 'URL', key: 'url', type: 'link', linkName: 'Ver' },
|
|
21
|
+
{ name: 'IMG', key: 'name', type: 'image', url: 'https://img.pokemondb.net/artwork/{key}.jpg' }
|
|
22
|
+
]
|
|
27
23
|
```
|
|
28
24
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
ng test
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Running end-to-end tests
|
|
48
|
-
|
|
49
|
-
For end-to-end (e2e) testing, run:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
ng e2e
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
56
|
-
|
|
57
|
-
## Additional Resources
|
|
58
|
-
|
|
59
|
-
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
25
|
+
## HTML
|
|
26
|
+
```ts
|
|
27
|
+
<sau-table
|
|
28
|
+
[url]="url"
|
|
29
|
+
contentList="results"
|
|
30
|
+
contentTotal="count"
|
|
31
|
+
pageParamName="offset"
|
|
32
|
+
limitParamName="limit"
|
|
33
|
+
[sizeBetweenPages]="10"
|
|
34
|
+
[limit]="10"
|
|
35
|
+
[headers]="headers"
|
|
36
|
+
></sau-table>
|
|
37
|
+
```
|
|
@@ -1,22 +1,200 @@
|
|
|
1
|
+
import * as i3 from '@angular/common';
|
|
2
|
+
import { CommonModule, DatePipe } from '@angular/common';
|
|
1
3
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component } from '@angular/core';
|
|
4
|
+
import { EventEmitter, Input, Output, Component } from '@angular/core';
|
|
5
|
+
import * as i2 from '@angular/router';
|
|
6
|
+
import { RouterModule } from '@angular/router';
|
|
7
|
+
import * as i1 from '@angular/common/http';
|
|
3
8
|
|
|
4
9
|
class TableModule {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
http;
|
|
11
|
+
cdr;
|
|
12
|
+
url;
|
|
13
|
+
contentList;
|
|
14
|
+
contentTotal;
|
|
15
|
+
pageParamName = 'page';
|
|
16
|
+
limitParamName = 'limit';
|
|
17
|
+
sizeInitialPage = 0;
|
|
18
|
+
sizeBetweenPages = 1;
|
|
19
|
+
headers;
|
|
20
|
+
editEvent = new EventEmitter();
|
|
21
|
+
deleteEvent = new EventEmitter();
|
|
22
|
+
loading = false;
|
|
23
|
+
items = [];
|
|
24
|
+
total = [];
|
|
25
|
+
page = 1;
|
|
26
|
+
limit = 10;
|
|
27
|
+
// Getter para obtener las páginas visibles (3 antes y 3 después de la página actual)
|
|
28
|
+
get visiblePages() {
|
|
29
|
+
const totalPages = this.total.length;
|
|
30
|
+
if (totalPages <= 7) {
|
|
31
|
+
// Si hay 7 páginas o menos, mostrar todas
|
|
32
|
+
return this.total;
|
|
33
|
+
}
|
|
34
|
+
const currentPage = this.page;
|
|
35
|
+
const start = Math.max(1, currentPage - 3);
|
|
36
|
+
const end = Math.min(totalPages, currentPage + 3);
|
|
37
|
+
const pages = [];
|
|
38
|
+
for (let i = start; i <= end; i++) {
|
|
39
|
+
pages.push(i);
|
|
40
|
+
}
|
|
41
|
+
return pages;
|
|
42
|
+
}
|
|
43
|
+
constructor(http, cdr) {
|
|
44
|
+
this.http = http;
|
|
45
|
+
this.cdr = cdr;
|
|
46
|
+
}
|
|
47
|
+
ngOnInit() {
|
|
48
|
+
if (this.url) {
|
|
49
|
+
this.getItems();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Método para obtener la página interna (0-based si sizeInitialPage es 0, 1-based si es 1)
|
|
53
|
+
getInternalPage() {
|
|
54
|
+
if (this.sizeInitialPage === 0) {
|
|
55
|
+
return (this.page - 1) * this.sizeBetweenPages;
|
|
56
|
+
}
|
|
57
|
+
return this.page * this.sizeBetweenPages;
|
|
58
|
+
}
|
|
59
|
+
getItems() {
|
|
60
|
+
this.loading = true;
|
|
61
|
+
this.cdr.detectChanges(); // Forzar detección antes de la petición
|
|
62
|
+
const internalPage = this.getInternalPage();
|
|
63
|
+
const filters = `?${this.pageParamName}=${internalPage}&${this.limitParamName}=${this.limit}`;
|
|
64
|
+
this.http.get(this.url + filters).subscribe({
|
|
65
|
+
next: (data) => {
|
|
66
|
+
if (this.contentList && data[this.contentList]) {
|
|
67
|
+
this.items = [...data[this.contentList]]; // Crear nueva referencia del array
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this.items = [...data]; // Crear nueva referencia del array
|
|
71
|
+
}
|
|
72
|
+
if (this.contentTotal) {
|
|
73
|
+
this.total = [];
|
|
74
|
+
for (let i = 0; i < data[this.contentTotal] / this.limit; i++) {
|
|
75
|
+
this.total.push(i + 1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.loading = false;
|
|
79
|
+
this.cdr.detectChanges(); // Forzar detección después de actualizar datos
|
|
80
|
+
},
|
|
81
|
+
error: (error) => {
|
|
82
|
+
console.error('ERROR obtener productos. ' + error);
|
|
83
|
+
this.loading = false;
|
|
84
|
+
this.cdr.detectChanges();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Método simple para refrescar la tabla
|
|
89
|
+
refresh() {
|
|
90
|
+
if (this.url) {
|
|
91
|
+
this.items = []; // Limpiar array primero
|
|
92
|
+
this.cdr.detectChanges(); // Forzar actualización
|
|
93
|
+
this.getItems();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
getLink(pattern = '{key}', item, value) {
|
|
97
|
+
const keyValue = this.getValue(item, value);
|
|
98
|
+
const url = pattern.replace('{key}', keyValue);
|
|
99
|
+
const isExternal = url.startsWith('http://') || url.startsWith('https://');
|
|
100
|
+
return {
|
|
101
|
+
url,
|
|
102
|
+
isExternal
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
getValue(item, key) {
|
|
106
|
+
let arrayKey = [];
|
|
107
|
+
if (!Array.isArray(key)) {
|
|
108
|
+
arrayKey.push(key);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
arrayKey = key.slice();
|
|
112
|
+
}
|
|
113
|
+
let result = '';
|
|
114
|
+
while (arrayKey.length > 0) {
|
|
115
|
+
let keys = arrayKey[0].split('.');
|
|
116
|
+
let value = item;
|
|
117
|
+
if (keys[0].includes('[]')) {
|
|
118
|
+
let arrayKey = keys[0].replace('[]', '');
|
|
119
|
+
value = value[arrayKey].map((element) => this.getValue(element, keys.slice(1).join('.'))).join(', ');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
let finalValue = item[String(key)];
|
|
123
|
+
let isArray = Array.isArray(finalValue);
|
|
124
|
+
let isBoolean = typeof finalValue === 'boolean';
|
|
125
|
+
if (isArray || isBoolean) {
|
|
126
|
+
return finalValue;
|
|
127
|
+
}
|
|
128
|
+
for (let i = 0; value && i < keys.length; i++) {
|
|
129
|
+
value = value[keys[i]];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
arrayKey.shift();
|
|
133
|
+
result += (value ?? '') + (arrayKey.length > 0 ? ' ' : '');
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
isArray(array) {
|
|
138
|
+
return Array.isArray(array);
|
|
139
|
+
}
|
|
140
|
+
changePage(page) {
|
|
141
|
+
this.page = page;
|
|
142
|
+
this.getItems();
|
|
143
|
+
}
|
|
144
|
+
// Método para ir a la primera página
|
|
145
|
+
goToFirstPage() {
|
|
146
|
+
if (this.page !== 1) {
|
|
147
|
+
this.changePage(1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Método para ir a la última página
|
|
151
|
+
goToLastPage() {
|
|
152
|
+
const lastPage = this.total.length;
|
|
153
|
+
if (this.page !== lastPage && lastPage > 0) {
|
|
154
|
+
this.changePage(lastPage);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
clickEditButton(id) {
|
|
158
|
+
this.editEvent.emit(id);
|
|
159
|
+
}
|
|
160
|
+
clickDeleteButton(id) {
|
|
161
|
+
this.deleteEvent.emit(id);
|
|
162
|
+
}
|
|
163
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TableModule, deps: [{ token: i1.HttpClient }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
164
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: TableModule, isStandalone: true, selector: "sau-table", inputs: { url: "url", contentList: "contentList", contentTotal: "contentTotal", pageParamName: "pageParamName", limitParamName: "limitParamName", sizeInitialPage: "sizeInitialPage", sizeBetweenPages: "sizeBetweenPages", headers: "headers", items: "items", limit: "limit" }, outputs: { editEvent: "editEvent", deleteEvent: "deleteEvent" }, ngImport: i0, template: "@if (loading) {\n<div>\n Loading\n</div>\n}\n\n<div class=\"overflow-auto rounded-2xl bg-white/90 backdrop-blur-lg shadow-xl border border-white/50\">\n\n <!----------------------------------- Table mobile ----------------------------------->\n <div class=\"md:hidden\">\n <!-- Mobile header -->\n <div class=\"bg-gradient-to-r from-purple-600 to-pink-600 text-white px-4 py-2 rounded-t-2xl\">\n <h3 class=\"text-base font-semibold leading-tight\">Lista de elementos</h3>\n <div class=\"w-8 h-0.5 bg-white/30 rounded-full mt-1\"></div>\n </div>\n\n <table class=\"w-full text-sm text-left rtl:text-right text-neutral-700\">\n <tbody>\n @for (item of items; track $index) {\n <tr class=\"border-b border-purple-100/50 last:border-b-0\">\n <td>\n <table class=\"w-full\">\n <tbody>\n @for (header of headers; track $index) {\n <tr [class]=\"$index%2==0?'bg-purple-50/30':''\">\n\n <th scope=\"col\"\n class=\"p-2 font-medium bg-gradient-to-r from-purple-600 to-pink-600 text-white max-w-min\">\n {{header.name}}\n </th>\n <td class=\"p-2 w-full text-neutral-800\">\n\n @if(header.type == 'table' && !isArray(header.key)){\n\n <!-- CSS-only toggle button -->\n <input type=\"checkbox\" [id]=\"'toggle-table-' + $index\" class=\"hidden peer\">\n <label [for]=\"'toggle-table-' + $index\"\n class=\"inline-flex items-center gap-2 px-3 py-2 bg-purple-100 text-purple-600 rounded-lg hover:bg-purple-200 transition-all duration-200 cursor-pointer select-none\">\n <!-- <fa-icon [icon]=\"['fas', 'chevron-down']\"\n class=\"text-xs transition-transform duration-200 peer-checked:rotate-180\"></fa-icon> -->\n <span class=\"text-sm font-medium\">\n <span class=\"peer-checked:hidden\">Mostrar</span>\n <span class=\"hidden peer-checked:inline\">Ocultar</span>\n </span>\n </label>\n\n <!-- Content that toggles -->\n <div\n class=\"mt-3 h-0 overflow-hidden opacity-0 peer-checked:h-auto peer-checked:opacity-100 peer-checked:overflow-visible transition-all duration-300 ease-in-out\">\n <sau-table [headers]=\"header.headers\"\n [items]=\"getValue(item, header.key)\"></sau-table>\n </div>\n\n }@else{\n <ng-container [ngTemplateOutlet]=\"DataTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header}\"></ng-container>\n\n }\n\n </td>\n\n </tr>\n }\n\n @if(this.url){\n <tr\n class=\"border-b-8 border-transparent bg-gradient-to-r from-purple-600 to-purple-400 p-4\">\n <td colspan=\"2\">\n <div class=\"flex justify-center gap-4 p-4\">\n @if(editEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-purple-600 bg-purple-50 hover:bg-purple-100 rounded-lg transition-all duration-200 border border-purple-200 hover:border-purple-300\"\n (click)=\"clickEditButton(item.id)\">\n <!-- <fa-icon [icon]=\"['fas', 'pen']\" class=\"text-xs\"></fa-icon> -->\n Editar\n </button>\n }\n\n @if(deleteEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-rose-600 bg-rose-50 hover:bg-rose-100 rounded-lg transition-all duration-200 border border-rose-200 hover:border-rose-300\"\n (click)=\"clickDeleteButton(item.id)\">\n <!-- <fa-icon [icon]=\"['fas', 'trash-can']\" class=\"text-xs\"></fa-icon> -->\n Eliminar\n </button>\n }\n </div>\n </td>\n </tr>\n }\n\n </tbody>\n </table>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n <!--------------------------------- Table mobile end --------------------------------->\n\n <!----------------------------------- Table desktop ----------------------------------->\n <table class=\"w-full text-sm text-center rtl:text-right text-neutral-700 hidden md:table\">\n <thead class=\"text-xs font-semibold uppercase bg-gradient-to-r from-purple-600 to-pink-600 text-white\">\n <tr>\n @for (header of headers; track $index) {\n <th scope=\"col\" class=\"p-2\">\n {{header.name}}\n </th>\n }\n\n @if(this.url){\n <th scope=\"col\" class=\"p-2\">\n Opciones\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of items; track $index) {\n <tr\n [class]=\"'min-w-max hover:bg-purple-50/50 transition-colors duration-200 border-b border-purple-100/30 last:border-b-0 ' + ($index%2==0?'bg-purple-50/20':'')\">\n\n @for (header of headers; track $index) {\n <td class=\"p-2\">\n\n @if(header.type == 'table'){\n\n @if(!isArray(header.key)){\n <sau-table [headers]=\"header.headers\" [items]=\"getValue(item, header.key)\"></sau-table>\n }\n\n }@else{\n <ng-container [ngTemplateOutlet]=\"DataTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header}\"></ng-container>\n }\n\n </td>\n }\n\n @if(this.url){\n <td class=\"px-6 py-4\">\n <div class=\"flex items-center gap-2\">\n @if(editEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center justify-center w-8 h-8 text-purple-600 bg-purple-50 hover:bg-purple-100 rounded-lg transition-all duration-200 border border-purple-200 hover:border-purple-300\"\n (click)=\"clickEditButton(item.id)\" title=\"Editar\">\n <!-- <fa-icon [icon]=\"['fas', 'pen']\" class=\"text-xs\"></fa-icon> -->\n </button>\n }\n\n @if(deleteEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center justify-center w-8 h-8 text-rose-600 bg-rose-50 hover:bg-rose-100 rounded-lg transition-all duration-200 border border-rose-200 hover:border-rose-300\"\n (click)=\"clickDeleteButton(item.id)\" title=\"Eliminar\">\n <!-- <fa-icon [icon]=\"['fas', 'trash-can']\" class=\"text-xs\"></fa-icon> -->\n </button>\n }\n </div>\n </td>\n }\n\n </tr>\n }\n </tbody>\n </table>\n <!--------------------------------- table desktop end --------------------------------->\n\n @if (items.length == 0) {\n <div class=\"flex flex-col items-center justify-center h-48 text-center\">\n <div class=\"w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mb-4\">\n <!-- <fa-icon [icon]=\"['fas', 'inbox']\" class=\"text-purple-400 text-2xl\"></fa-icon> -->\n </div>\n <p class=\"text-neutral-500 font-medium\">No hay elementos</p>\n <p class=\"text-neutral-400 text-sm\">Los elementos aparecer\u00E1n aqu\u00ED cuando est\u00E9n disponibles</p>\n </div>\n\n } @else if(total.length > 1) {\n\n <!----------------------------------- Pagination ----------------------------------->\n <div\n class=\"sticky left-0 flex flex-wrap gap-2 items-center justify-center md:justify-between p-6 bg-gradient-to-r from-purple-50/50 to-pink-50/50 border-t border-purple-200/50\">\n\n <!-- N\u00FAmeros de p\u00E1gina -->\n <div class=\"md:order-2 w-full md:w-max flex items-center justify-center gap-2\">\n @for (item of visiblePages; track $index) {\n <button (click)=\"changePage(item)\"\n [class]=\"'cursor-pointer w-10 h-10 rounded-lg font-medium text-sm transition-all duration-200 ' + (item == page ? 'bg-gradient-to-r from-purple-500 to-pink-500 text-white shadow-lg' : 'text-purple-600 hover:bg-purple-50 border border-purple-200 hover:border-purple-300')\"\n type=\"button\">\n {{item}}\n </button>\n }\n </div>\n\n <!-- Botones de navegaci\u00F3n izquierda -->\n <div class=\"md:order-1 flex items-center gap-2\">\n <!-- Bot\u00F3n ir al inicio -->\n <button type=\"button\" (click)=\"goToFirstPage()\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center px-3 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 text-sm font-medium ' + (page == 1?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Ir al inicio\">\n \u2039\u2039\n </button>\n\n <!-- Bot\u00F3n p\u00E1gina anterior -->\n <button type=\"button\" (click)=\"changePage(page-1)\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center w-10 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 ' + (page == 1?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"P\u00E1gina anterior\">\n \u2039\n </button>\n </div>\n\n <!-- Botones de navegaci\u00F3n derecha -->\n <div class=\"md:order-3 flex items-center gap-2\">\n <!-- Bot\u00F3n p\u00E1gina siguiente -->\n <button type=\"button\" (click)=\"changePage(page+1)\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center w-10 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 ' + (page == total[total.length-1]?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"P\u00E1gina siguiente\">\n \u203A\n </button>\n\n <!-- Bot\u00F3n ir al final -->\n <button type=\"button\" (click)=\"goToLastPage()\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center px-3 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 text-sm font-medium ' + (page == total[total.length-1]?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Ir al final\">\n \u203A\u203A\n </button>\n </div>\n </div>\n <!--------------------------------- pagination end --------------------------------->\n }\n\n</div>\n\n<!----------------------------------- Data template ----------------------------------->\n<ng-template #DataTemplate let-item=\"item\" let-header=\"header\">\n\n <section class=\"flex items-center gap-2\">\n\n @if(header.name == 'NOMBRE' && item.role == 'ROLE_ADMIN') {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-orange-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-orange-600', 'text-xs']\" [icon]=\"['fas', 'crown']\"></fa-icon> -->\n </div>\n }\n\n <span>\n @if (header.innerHtml) {\n <span [innerHTML]=\"getValue(item, header.key)\"></span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"DataTypeTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header, value:header.key}\"></ng-container>\n }\n\n @if(header.subKey){\n <span class=\"block text-neutral-600 text-xs min-w-max\">\n (\n <ng-container [ngTemplateOutlet]=\"DataTypeTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header, value:header.subKey}\"></ng-container>\n )\n </span>\n }\n </span>\n\n </section>\n\n</ng-template>\n<!--------------------------------- Data template end --------------------------------->\n\n<!----------------------------------- Data Type template ----------------------------------->\n<ng-template #DataTypeTemplate let-item=\"item\" let-header=\"header\" let-value=\"value\">\n\n <section class=\"inline-block min-w-max\">\n @switch (header.type) {\n\n @case ('boolean') {\n @if(getValue(item, value)){\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-emerald-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-emerald-600', 'text-xs']\" [icon]=\"['fas', 'check']\"></fa-icon> -->\n </div>\n } @else {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-rose-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-rose-600', 'text-xs']\" [icon]=\"['fas', 'xmark']\"></fa-icon> -->\n </div>\n }\n }\n\n @case ('currency'){\n <!-- {{formatEuro(getValue(item, value))}} -->\n }\n\n @case ('dateTime') {\n <span class=\"text-neutral-600 text-sm\">\n {{getValue(item, value) | date: 'dd/MM/yyyy HH:mm'}}\n </span>\n }\n\n @case ('color'){\n <span class=\"inline-block w-8 h-4 rounded-full border border-neutral-200 shadow-sm\"\n [style.background-color]=\"getValue(item, value)\"></span>\n }\n\n @case ('link'){\n @let link = getLink(header.url, item, value);\n\n @if(link.isExternal){\n <a [href]=\"link.url\" class=\"text-purple-600 hover:underline\">\n {{header.linkName}}\n </a>\n }@else{\n <a [routerLink]=\"link.url\" class=\"text-purple-600 hover:underline\" target=\"_blank\">\n {{header.linkName}}\n </a>\n }\n\n }\n\n @case ('image'){\n @let link = getLink(header.url, item, value);\n\n <img [src]=\"link.url\" [alt]=\"getValue(item, value)\" loading=\"lazy\" class=\"w-10 h-10 object-cover\">\n }\n\n @case ('login'){\n @if(item.active){\n <span class=\"inline-flex items-center gap-1\">\n\n @if(item.email_verified_at){\n <div [title]=\"item.email\" class=\"inline-flex items-center justify-center w-6 h-6 bg-blue-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-blue-600', 'text-xs']\" [icon]=\"['fas', 'envelope']\"></fa-icon> -->\n </div>\n }\n\n @if(item.google_id){\n <div [title]=\"item.google_id\"\n class=\"inline-flex items-center justify-center w-6 h-6 bg-red-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-red-600', 'text-xs']\" [icon]=\"['fab', 'google']\"></fa-icon> -->\n </div>\n }\n\n </span>\n } @else {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-rose-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-rose-600', 'text-xs']\" [icon]=\"['fas', 'xmark']\"></fa-icon> -->\n </div>\n }\n }\n\n @default {\n {{getValue(item, value)}}\n }\n }\n </section>\n\n</ng-template>\n<!--------------------------------- Data Type template end --------------------------------->", dependencies: [{ kind: "component", type: TableModule, selector: "sau-table", inputs: ["url", "contentList", "contentTotal", "pageParamName", "limitParamName", "sizeInitialPage", "sizeBetweenPages", "headers", "items", "limit"], outputs: ["editEvent", "deleteEvent"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: DatePipe, name: "date" }] });
|
|
11
165
|
}
|
|
12
166
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TableModule, decorators: [{
|
|
13
167
|
type: Component,
|
|
14
|
-
args: [{ selector: '
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
` }]
|
|
19
|
-
}] }
|
|
168
|
+
args: [{ selector: 'sau-table', imports: [
|
|
169
|
+
RouterModule,
|
|
170
|
+
DatePipe,
|
|
171
|
+
CommonModule,
|
|
172
|
+
], template: "@if (loading) {\n<div>\n Loading\n</div>\n}\n\n<div class=\"overflow-auto rounded-2xl bg-white/90 backdrop-blur-lg shadow-xl border border-white/50\">\n\n <!----------------------------------- Table mobile ----------------------------------->\n <div class=\"md:hidden\">\n <!-- Mobile header -->\n <div class=\"bg-gradient-to-r from-purple-600 to-pink-600 text-white px-4 py-2 rounded-t-2xl\">\n <h3 class=\"text-base font-semibold leading-tight\">Lista de elementos</h3>\n <div class=\"w-8 h-0.5 bg-white/30 rounded-full mt-1\"></div>\n </div>\n\n <table class=\"w-full text-sm text-left rtl:text-right text-neutral-700\">\n <tbody>\n @for (item of items; track $index) {\n <tr class=\"border-b border-purple-100/50 last:border-b-0\">\n <td>\n <table class=\"w-full\">\n <tbody>\n @for (header of headers; track $index) {\n <tr [class]=\"$index%2==0?'bg-purple-50/30':''\">\n\n <th scope=\"col\"\n class=\"p-2 font-medium bg-gradient-to-r from-purple-600 to-pink-600 text-white max-w-min\">\n {{header.name}}\n </th>\n <td class=\"p-2 w-full text-neutral-800\">\n\n @if(header.type == 'table' && !isArray(header.key)){\n\n <!-- CSS-only toggle button -->\n <input type=\"checkbox\" [id]=\"'toggle-table-' + $index\" class=\"hidden peer\">\n <label [for]=\"'toggle-table-' + $index\"\n class=\"inline-flex items-center gap-2 px-3 py-2 bg-purple-100 text-purple-600 rounded-lg hover:bg-purple-200 transition-all duration-200 cursor-pointer select-none\">\n <!-- <fa-icon [icon]=\"['fas', 'chevron-down']\"\n class=\"text-xs transition-transform duration-200 peer-checked:rotate-180\"></fa-icon> -->\n <span class=\"text-sm font-medium\">\n <span class=\"peer-checked:hidden\">Mostrar</span>\n <span class=\"hidden peer-checked:inline\">Ocultar</span>\n </span>\n </label>\n\n <!-- Content that toggles -->\n <div\n class=\"mt-3 h-0 overflow-hidden opacity-0 peer-checked:h-auto peer-checked:opacity-100 peer-checked:overflow-visible transition-all duration-300 ease-in-out\">\n <sau-table [headers]=\"header.headers\"\n [items]=\"getValue(item, header.key)\"></sau-table>\n </div>\n\n }@else{\n <ng-container [ngTemplateOutlet]=\"DataTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header}\"></ng-container>\n\n }\n\n </td>\n\n </tr>\n }\n\n @if(this.url){\n <tr\n class=\"border-b-8 border-transparent bg-gradient-to-r from-purple-600 to-purple-400 p-4\">\n <td colspan=\"2\">\n <div class=\"flex justify-center gap-4 p-4\">\n @if(editEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-purple-600 bg-purple-50 hover:bg-purple-100 rounded-lg transition-all duration-200 border border-purple-200 hover:border-purple-300\"\n (click)=\"clickEditButton(item.id)\">\n <!-- <fa-icon [icon]=\"['fas', 'pen']\" class=\"text-xs\"></fa-icon> -->\n Editar\n </button>\n }\n\n @if(deleteEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-rose-600 bg-rose-50 hover:bg-rose-100 rounded-lg transition-all duration-200 border border-rose-200 hover:border-rose-300\"\n (click)=\"clickDeleteButton(item.id)\">\n <!-- <fa-icon [icon]=\"['fas', 'trash-can']\" class=\"text-xs\"></fa-icon> -->\n Eliminar\n </button>\n }\n </div>\n </td>\n </tr>\n }\n\n </tbody>\n </table>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n <!--------------------------------- Table mobile end --------------------------------->\n\n <!----------------------------------- Table desktop ----------------------------------->\n <table class=\"w-full text-sm text-center rtl:text-right text-neutral-700 hidden md:table\">\n <thead class=\"text-xs font-semibold uppercase bg-gradient-to-r from-purple-600 to-pink-600 text-white\">\n <tr>\n @for (header of headers; track $index) {\n <th scope=\"col\" class=\"p-2\">\n {{header.name}}\n </th>\n }\n\n @if(this.url){\n <th scope=\"col\" class=\"p-2\">\n Opciones\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of items; track $index) {\n <tr\n [class]=\"'min-w-max hover:bg-purple-50/50 transition-colors duration-200 border-b border-purple-100/30 last:border-b-0 ' + ($index%2==0?'bg-purple-50/20':'')\">\n\n @for (header of headers; track $index) {\n <td class=\"p-2\">\n\n @if(header.type == 'table'){\n\n @if(!isArray(header.key)){\n <sau-table [headers]=\"header.headers\" [items]=\"getValue(item, header.key)\"></sau-table>\n }\n\n }@else{\n <ng-container [ngTemplateOutlet]=\"DataTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header}\"></ng-container>\n }\n\n </td>\n }\n\n @if(this.url){\n <td class=\"px-6 py-4\">\n <div class=\"flex items-center gap-2\">\n @if(editEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center justify-center w-8 h-8 text-purple-600 bg-purple-50 hover:bg-purple-100 rounded-lg transition-all duration-200 border border-purple-200 hover:border-purple-300\"\n (click)=\"clickEditButton(item.id)\" title=\"Editar\">\n <!-- <fa-icon [icon]=\"['fas', 'pen']\" class=\"text-xs\"></fa-icon> -->\n </button>\n }\n\n @if(deleteEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center justify-center w-8 h-8 text-rose-600 bg-rose-50 hover:bg-rose-100 rounded-lg transition-all duration-200 border border-rose-200 hover:border-rose-300\"\n (click)=\"clickDeleteButton(item.id)\" title=\"Eliminar\">\n <!-- <fa-icon [icon]=\"['fas', 'trash-can']\" class=\"text-xs\"></fa-icon> -->\n </button>\n }\n </div>\n </td>\n }\n\n </tr>\n }\n </tbody>\n </table>\n <!--------------------------------- table desktop end --------------------------------->\n\n @if (items.length == 0) {\n <div class=\"flex flex-col items-center justify-center h-48 text-center\">\n <div class=\"w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mb-4\">\n <!-- <fa-icon [icon]=\"['fas', 'inbox']\" class=\"text-purple-400 text-2xl\"></fa-icon> -->\n </div>\n <p class=\"text-neutral-500 font-medium\">No hay elementos</p>\n <p class=\"text-neutral-400 text-sm\">Los elementos aparecer\u00E1n aqu\u00ED cuando est\u00E9n disponibles</p>\n </div>\n\n } @else if(total.length > 1) {\n\n <!----------------------------------- Pagination ----------------------------------->\n <div\n class=\"sticky left-0 flex flex-wrap gap-2 items-center justify-center md:justify-between p-6 bg-gradient-to-r from-purple-50/50 to-pink-50/50 border-t border-purple-200/50\">\n\n <!-- N\u00FAmeros de p\u00E1gina -->\n <div class=\"md:order-2 w-full md:w-max flex items-center justify-center gap-2\">\n @for (item of visiblePages; track $index) {\n <button (click)=\"changePage(item)\"\n [class]=\"'cursor-pointer w-10 h-10 rounded-lg font-medium text-sm transition-all duration-200 ' + (item == page ? 'bg-gradient-to-r from-purple-500 to-pink-500 text-white shadow-lg' : 'text-purple-600 hover:bg-purple-50 border border-purple-200 hover:border-purple-300')\"\n type=\"button\">\n {{item}}\n </button>\n }\n </div>\n\n <!-- Botones de navegaci\u00F3n izquierda -->\n <div class=\"md:order-1 flex items-center gap-2\">\n <!-- Bot\u00F3n ir al inicio -->\n <button type=\"button\" (click)=\"goToFirstPage()\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center px-3 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 text-sm font-medium ' + (page == 1?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Ir al inicio\">\n \u2039\u2039\n </button>\n\n <!-- Bot\u00F3n p\u00E1gina anterior -->\n <button type=\"button\" (click)=\"changePage(page-1)\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center w-10 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 ' + (page == 1?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"P\u00E1gina anterior\">\n \u2039\n </button>\n </div>\n\n <!-- Botones de navegaci\u00F3n derecha -->\n <div class=\"md:order-3 flex items-center gap-2\">\n <!-- Bot\u00F3n p\u00E1gina siguiente -->\n <button type=\"button\" (click)=\"changePage(page+1)\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center w-10 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 ' + (page == total[total.length-1]?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"P\u00E1gina siguiente\">\n \u203A\n </button>\n\n <!-- Bot\u00F3n ir al final -->\n <button type=\"button\" (click)=\"goToLastPage()\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center px-3 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 text-sm font-medium ' + (page == total[total.length-1]?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Ir al final\">\n \u203A\u203A\n </button>\n </div>\n </div>\n <!--------------------------------- pagination end --------------------------------->\n }\n\n</div>\n\n<!----------------------------------- Data template ----------------------------------->\n<ng-template #DataTemplate let-item=\"item\" let-header=\"header\">\n\n <section class=\"flex items-center gap-2\">\n\n @if(header.name == 'NOMBRE' && item.role == 'ROLE_ADMIN') {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-orange-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-orange-600', 'text-xs']\" [icon]=\"['fas', 'crown']\"></fa-icon> -->\n </div>\n }\n\n <span>\n @if (header.innerHtml) {\n <span [innerHTML]=\"getValue(item, header.key)\"></span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"DataTypeTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header, value:header.key}\"></ng-container>\n }\n\n @if(header.subKey){\n <span class=\"block text-neutral-600 text-xs min-w-max\">\n (\n <ng-container [ngTemplateOutlet]=\"DataTypeTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header, value:header.subKey}\"></ng-container>\n )\n </span>\n }\n </span>\n\n </section>\n\n</ng-template>\n<!--------------------------------- Data template end --------------------------------->\n\n<!----------------------------------- Data Type template ----------------------------------->\n<ng-template #DataTypeTemplate let-item=\"item\" let-header=\"header\" let-value=\"value\">\n\n <section class=\"inline-block min-w-max\">\n @switch (header.type) {\n\n @case ('boolean') {\n @if(getValue(item, value)){\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-emerald-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-emerald-600', 'text-xs']\" [icon]=\"['fas', 'check']\"></fa-icon> -->\n </div>\n } @else {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-rose-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-rose-600', 'text-xs']\" [icon]=\"['fas', 'xmark']\"></fa-icon> -->\n </div>\n }\n }\n\n @case ('currency'){\n <!-- {{formatEuro(getValue(item, value))}} -->\n }\n\n @case ('dateTime') {\n <span class=\"text-neutral-600 text-sm\">\n {{getValue(item, value) | date: 'dd/MM/yyyy HH:mm'}}\n </span>\n }\n\n @case ('color'){\n <span class=\"inline-block w-8 h-4 rounded-full border border-neutral-200 shadow-sm\"\n [style.background-color]=\"getValue(item, value)\"></span>\n }\n\n @case ('link'){\n @let link = getLink(header.url, item, value);\n\n @if(link.isExternal){\n <a [href]=\"link.url\" class=\"text-purple-600 hover:underline\">\n {{header.linkName}}\n </a>\n }@else{\n <a [routerLink]=\"link.url\" class=\"text-purple-600 hover:underline\" target=\"_blank\">\n {{header.linkName}}\n </a>\n }\n\n }\n\n @case ('image'){\n @let link = getLink(header.url, item, value);\n\n <img [src]=\"link.url\" [alt]=\"getValue(item, value)\" loading=\"lazy\" class=\"w-10 h-10 object-cover\">\n }\n\n @case ('login'){\n @if(item.active){\n <span class=\"inline-flex items-center gap-1\">\n\n @if(item.email_verified_at){\n <div [title]=\"item.email\" class=\"inline-flex items-center justify-center w-6 h-6 bg-blue-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-blue-600', 'text-xs']\" [icon]=\"['fas', 'envelope']\"></fa-icon> -->\n </div>\n }\n\n @if(item.google_id){\n <div [title]=\"item.google_id\"\n class=\"inline-flex items-center justify-center w-6 h-6 bg-red-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-red-600', 'text-xs']\" [icon]=\"['fab', 'google']\"></fa-icon> -->\n </div>\n }\n\n </span>\n } @else {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-rose-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-rose-600', 'text-xs']\" [icon]=\"['fas', 'xmark']\"></fa-icon> -->\n </div>\n }\n }\n\n @default {\n {{getValue(item, value)}}\n }\n }\n </section>\n\n</ng-template>\n<!--------------------------------- Data Type template end --------------------------------->" }]
|
|
173
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: i0.ChangeDetectorRef }], propDecorators: { url: [{
|
|
174
|
+
type: Input
|
|
175
|
+
}], contentList: [{
|
|
176
|
+
type: Input
|
|
177
|
+
}], contentTotal: [{
|
|
178
|
+
type: Input
|
|
179
|
+
}], pageParamName: [{
|
|
180
|
+
type: Input
|
|
181
|
+
}], limitParamName: [{
|
|
182
|
+
type: Input
|
|
183
|
+
}], sizeInitialPage: [{
|
|
184
|
+
type: Input
|
|
185
|
+
}], sizeBetweenPages: [{
|
|
186
|
+
type: Input
|
|
187
|
+
}], headers: [{
|
|
188
|
+
type: Input
|
|
189
|
+
}], editEvent: [{
|
|
190
|
+
type: Output
|
|
191
|
+
}], deleteEvent: [{
|
|
192
|
+
type: Output
|
|
193
|
+
}], items: [{
|
|
194
|
+
type: Input
|
|
195
|
+
}], limit: [{
|
|
196
|
+
type: Input
|
|
197
|
+
}] } });
|
|
20
198
|
|
|
21
199
|
/*
|
|
22
200
|
* Public API Surface of table
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"some-angular-utils-table.mjs","sources":["../../../../projects/some-angular-utils/table/src/lib/table.ts","../../../../projects/some-angular-utils/table/src/public-api.ts","../../../../projects/some-angular-utils/table/src/some-angular-utils-table.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-table',\n imports: [],\n template: `\n <p>\n table works!\n </p>\n `,\n styles: ``\n})\nexport class TableModule {\n\n}\n","/*\n * Public API Surface of table\n */\n\nexport * from './lib/table';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;MAYa,WAAW,CAAA;uGAAX,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAPZ;;;;AAIT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAGU,WAAW,EAAA,UAAA,EAAA,CAAA;kBAVvB,SAAS;+BACE,WAAW,EAAA,OAAA,EACZ,EAAE,EAAA,QAAA,EACD;;;;AAIT,EAAA,CAAA,EAAA;;;ACTH;;AAEG;;ACFH;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"some-angular-utils-table.mjs","sources":["../../../../projects/some-angular-utils/table/src/lib/table.ts","../../../../projects/some-angular-utils/table/src/lib/table.html","../../../../projects/some-angular-utils/table/src/public-api.ts","../../../../projects/some-angular-utils/table/src/some-angular-utils-table.ts"],"sourcesContent":["import { CommonModule, DatePipe } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';\nimport { RouterModule } from '@angular/router';\n\n@Component({\n selector: 'sau-table',\n templateUrl: './table.html',\n imports: [\n RouterModule,\n DatePipe,\n CommonModule,\n ]\n})\nexport class TableModule {\n @Input() url?: string;\n @Input() contentList?: string;\n @Input() contentTotal?: string;\n @Input() pageParamName = 'page';\n @Input() limitParamName = 'limit'\n @Input() sizeInitialPage = 0\n @Input() sizeBetweenPages = 1\n @Input() headers?: { name: string, key: string | string[], subKey?: string, type?: string, innerHtml?: boolean, headers?: any }[];\n @Output() editEvent = new EventEmitter();\n @Output() deleteEvent = new EventEmitter();\n\n loading = false\n\n @Input() items: any = [];\n\n total: number[] = []\n\n page = 1\n\n @Input() limit = 10\n\n // Getter para obtener las páginas visibles (3 antes y 3 después de la página actual)\n get visiblePages(): number[] {\n const totalPages = this.total.length;\n if (totalPages <= 7) {\n // Si hay 7 páginas o menos, mostrar todas\n return this.total;\n }\n\n const currentPage = this.page;\n const start = Math.max(1, currentPage - 3);\n const end = Math.min(totalPages, currentPage + 3);\n\n const pages: number[] = [];\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n\n return pages;\n }\n\n constructor(\n private http: HttpClient,\n private cdr: ChangeDetectorRef\n ) { }\n\n ngOnInit() {\n if (this.url) {\n this.getItems();\n }\n }\n\n // Método para obtener la página interna (0-based si sizeInitialPage es 0, 1-based si es 1)\n private getInternalPage(): number {\n if (this.sizeInitialPage === 0) {\n return (this.page - 1) * this.sizeBetweenPages;\n }\n return this.page * this.sizeBetweenPages;\n }\n\n getItems() {\n this.loading = true;\n this.cdr.detectChanges(); // Forzar detección antes de la petición\n\n const internalPage = this.getInternalPage();\n const filters = `?${this.pageParamName}=${internalPage}&${this.limitParamName}=${this.limit}`;\n\n this.http.get(this.url + filters).subscribe({\n next: (data: any) => {\n\n if (this.contentList && data[this.contentList]) {\n this.items = [...data[this.contentList]]; // Crear nueva referencia del array\n } else {\n this.items = [...data]; // Crear nueva referencia del array\n }\n\n if (this.contentTotal) {\n this.total = []\n for (let i = 0; i < data[this.contentTotal] / this.limit; i++) {\n this.total.push(i + 1)\n }\n }\n\n this.loading = false;\n this.cdr.detectChanges(); // Forzar detección después de actualizar datos\n },\n error: (error: any) => {\n console.error('ERROR obtener productos. ' + error);\n this.loading = false;\n this.cdr.detectChanges();\n }\n });\n }\n\n // Método simple para refrescar la tabla\n refresh() {\n if (this.url) {\n this.items = []; // Limpiar array primero\n this.cdr.detectChanges(); // Forzar actualización\n this.getItems();\n }\n }\n\n getLink(pattern: string = '{key}', item: any, value: string | string[]): { url: string, isExternal: boolean } {\n const keyValue = this.getValue(item, value);\n const url = pattern.replace('{key}', keyValue);\n const isExternal = url.startsWith('http://') || url.startsWith('https://')\n\n return {\n url,\n isExternal\n }\n }\n\n getValue(item: any, key: string | string[]) {\n\n let arrayKey = [];\n\n if (!Array.isArray(key)) {\n arrayKey.push(key);\n } else {\n arrayKey = key.slice();\n }\n\n let result = ''\n\n while (arrayKey.length > 0) {\n\n let keys = arrayKey[0].split('.');\n let value = item;\n\n if (keys[0].includes('[]')) {\n let arrayKey = keys[0].replace('[]', '');\n\n value = value[arrayKey].map((element: any) => this.getValue(element, keys.slice(1).join('.'))).join(', ');\n\n } else {\n let finalValue = item[String(key)]\n\n let isArray = Array.isArray(finalValue)\n let isBoolean = typeof finalValue === 'boolean'\n\n if (isArray || isBoolean) {\n return finalValue\n }\n\n for (let i = 0; value && i < keys.length; i++) {\n value = value[keys[i]];\n }\n }\n\n arrayKey.shift();\n\n result += (value ?? '') + (arrayKey.length > 0 ? ' ' : '');\n\n }\n\n return result;\n }\n\n isArray(array: any): boolean {\n return Array.isArray(array)\n }\n\n changePage(page: number) {\n this.page = page\n this.getItems()\n }\n\n // Método para ir a la primera página\n goToFirstPage() {\n if (this.page !== 1) {\n this.changePage(1);\n }\n }\n\n // Método para ir a la última página\n goToLastPage() {\n const lastPage = this.total.length;\n if (this.page !== lastPage && lastPage > 0) {\n this.changePage(lastPage);\n }\n }\n\n clickEditButton(id?: number) {\n this.editEvent.emit(id)\n }\n\n clickDeleteButton(id?: number) {\n this.deleteEvent.emit(id);\n }\n\n}\n","@if (loading) {\n<div>\n Loading\n</div>\n}\n\n<div class=\"overflow-auto rounded-2xl bg-white/90 backdrop-blur-lg shadow-xl border border-white/50\">\n\n <!----------------------------------- Table mobile ----------------------------------->\n <div class=\"md:hidden\">\n <!-- Mobile header -->\n <div class=\"bg-gradient-to-r from-purple-600 to-pink-600 text-white px-4 py-2 rounded-t-2xl\">\n <h3 class=\"text-base font-semibold leading-tight\">Lista de elementos</h3>\n <div class=\"w-8 h-0.5 bg-white/30 rounded-full mt-1\"></div>\n </div>\n\n <table class=\"w-full text-sm text-left rtl:text-right text-neutral-700\">\n <tbody>\n @for (item of items; track $index) {\n <tr class=\"border-b border-purple-100/50 last:border-b-0\">\n <td>\n <table class=\"w-full\">\n <tbody>\n @for (header of headers; track $index) {\n <tr [class]=\"$index%2==0?'bg-purple-50/30':''\">\n\n <th scope=\"col\"\n class=\"p-2 font-medium bg-gradient-to-r from-purple-600 to-pink-600 text-white max-w-min\">\n {{header.name}}\n </th>\n <td class=\"p-2 w-full text-neutral-800\">\n\n @if(header.type == 'table' && !isArray(header.key)){\n\n <!-- CSS-only toggle button -->\n <input type=\"checkbox\" [id]=\"'toggle-table-' + $index\" class=\"hidden peer\">\n <label [for]=\"'toggle-table-' + $index\"\n class=\"inline-flex items-center gap-2 px-3 py-2 bg-purple-100 text-purple-600 rounded-lg hover:bg-purple-200 transition-all duration-200 cursor-pointer select-none\">\n <!-- <fa-icon [icon]=\"['fas', 'chevron-down']\"\n class=\"text-xs transition-transform duration-200 peer-checked:rotate-180\"></fa-icon> -->\n <span class=\"text-sm font-medium\">\n <span class=\"peer-checked:hidden\">Mostrar</span>\n <span class=\"hidden peer-checked:inline\">Ocultar</span>\n </span>\n </label>\n\n <!-- Content that toggles -->\n <div\n class=\"mt-3 h-0 overflow-hidden opacity-0 peer-checked:h-auto peer-checked:opacity-100 peer-checked:overflow-visible transition-all duration-300 ease-in-out\">\n <sau-table [headers]=\"header.headers\"\n [items]=\"getValue(item, header.key)\"></sau-table>\n </div>\n\n }@else{\n <ng-container [ngTemplateOutlet]=\"DataTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header}\"></ng-container>\n\n }\n\n </td>\n\n </tr>\n }\n\n @if(this.url){\n <tr\n class=\"border-b-8 border-transparent bg-gradient-to-r from-purple-600 to-purple-400 p-4\">\n <td colspan=\"2\">\n <div class=\"flex justify-center gap-4 p-4\">\n @if(editEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-purple-600 bg-purple-50 hover:bg-purple-100 rounded-lg transition-all duration-200 border border-purple-200 hover:border-purple-300\"\n (click)=\"clickEditButton(item.id)\">\n <!-- <fa-icon [icon]=\"['fas', 'pen']\" class=\"text-xs\"></fa-icon> -->\n Editar\n </button>\n }\n\n @if(deleteEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-rose-600 bg-rose-50 hover:bg-rose-100 rounded-lg transition-all duration-200 border border-rose-200 hover:border-rose-300\"\n (click)=\"clickDeleteButton(item.id)\">\n <!-- <fa-icon [icon]=\"['fas', 'trash-can']\" class=\"text-xs\"></fa-icon> -->\n Eliminar\n </button>\n }\n </div>\n </td>\n </tr>\n }\n\n </tbody>\n </table>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n <!--------------------------------- Table mobile end --------------------------------->\n\n <!----------------------------------- Table desktop ----------------------------------->\n <table class=\"w-full text-sm text-center rtl:text-right text-neutral-700 hidden md:table\">\n <thead class=\"text-xs font-semibold uppercase bg-gradient-to-r from-purple-600 to-pink-600 text-white\">\n <tr>\n @for (header of headers; track $index) {\n <th scope=\"col\" class=\"p-2\">\n {{header.name}}\n </th>\n }\n\n @if(this.url){\n <th scope=\"col\" class=\"p-2\">\n Opciones\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of items; track $index) {\n <tr\n [class]=\"'min-w-max hover:bg-purple-50/50 transition-colors duration-200 border-b border-purple-100/30 last:border-b-0 ' + ($index%2==0?'bg-purple-50/20':'')\">\n\n @for (header of headers; track $index) {\n <td class=\"p-2\">\n\n @if(header.type == 'table'){\n\n @if(!isArray(header.key)){\n <sau-table [headers]=\"header.headers\" [items]=\"getValue(item, header.key)\"></sau-table>\n }\n\n }@else{\n <ng-container [ngTemplateOutlet]=\"DataTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header}\"></ng-container>\n }\n\n </td>\n }\n\n @if(this.url){\n <td class=\"px-6 py-4\">\n <div class=\"flex items-center gap-2\">\n @if(editEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center justify-center w-8 h-8 text-purple-600 bg-purple-50 hover:bg-purple-100 rounded-lg transition-all duration-200 border border-purple-200 hover:border-purple-300\"\n (click)=\"clickEditButton(item.id)\" title=\"Editar\">\n <!-- <fa-icon [icon]=\"['fas', 'pen']\" class=\"text-xs\"></fa-icon> -->\n </button>\n }\n\n @if(deleteEvent.observers.length > 0){\n <button\n class=\"inline-flex items-center justify-center w-8 h-8 text-rose-600 bg-rose-50 hover:bg-rose-100 rounded-lg transition-all duration-200 border border-rose-200 hover:border-rose-300\"\n (click)=\"clickDeleteButton(item.id)\" title=\"Eliminar\">\n <!-- <fa-icon [icon]=\"['fas', 'trash-can']\" class=\"text-xs\"></fa-icon> -->\n </button>\n }\n </div>\n </td>\n }\n\n </tr>\n }\n </tbody>\n </table>\n <!--------------------------------- table desktop end --------------------------------->\n\n @if (items.length == 0) {\n <div class=\"flex flex-col items-center justify-center h-48 text-center\">\n <div class=\"w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mb-4\">\n <!-- <fa-icon [icon]=\"['fas', 'inbox']\" class=\"text-purple-400 text-2xl\"></fa-icon> -->\n </div>\n <p class=\"text-neutral-500 font-medium\">No hay elementos</p>\n <p class=\"text-neutral-400 text-sm\">Los elementos aparecerán aquí cuando estén disponibles</p>\n </div>\n\n } @else if(total.length > 1) {\n\n <!----------------------------------- Pagination ----------------------------------->\n <div\n class=\"sticky left-0 flex flex-wrap gap-2 items-center justify-center md:justify-between p-6 bg-gradient-to-r from-purple-50/50 to-pink-50/50 border-t border-purple-200/50\">\n\n <!-- Números de página -->\n <div class=\"md:order-2 w-full md:w-max flex items-center justify-center gap-2\">\n @for (item of visiblePages; track $index) {\n <button (click)=\"changePage(item)\"\n [class]=\"'cursor-pointer w-10 h-10 rounded-lg font-medium text-sm transition-all duration-200 ' + (item == page ? 'bg-gradient-to-r from-purple-500 to-pink-500 text-white shadow-lg' : 'text-purple-600 hover:bg-purple-50 border border-purple-200 hover:border-purple-300')\"\n type=\"button\">\n {{item}}\n </button>\n }\n </div>\n\n <!-- Botones de navegación izquierda -->\n <div class=\"md:order-1 flex items-center gap-2\">\n <!-- Botón ir al inicio -->\n <button type=\"button\" (click)=\"goToFirstPage()\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center px-3 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 text-sm font-medium ' + (page == 1?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Ir al inicio\">\n ‹‹\n </button>\n\n <!-- Botón página anterior -->\n <button type=\"button\" (click)=\"changePage(page-1)\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center w-10 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 ' + (page == 1?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Página anterior\">\n ‹\n </button>\n </div>\n\n <!-- Botones de navegación derecha -->\n <div class=\"md:order-3 flex items-center gap-2\">\n <!-- Botón página siguiente -->\n <button type=\"button\" (click)=\"changePage(page+1)\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center w-10 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 ' + (page == total[total.length-1]?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Página siguiente\">\n ›\n </button>\n\n <!-- Botón ir al final -->\n <button type=\"button\" (click)=\"goToLastPage()\"\n [class]=\"'cursor-pointer inline-flex items-center justify-center px-3 h-10 text-purple-600 bg-white border border-purple-200 rounded-lg hover:bg-purple-50 transition-all duration-200 text-sm font-medium ' + (page == total[total.length-1]?'opacity-50 pointer-events-none':'hover:border-purple-300')\"\n title=\"Ir al final\">\n ››\n </button>\n </div>\n </div>\n <!--------------------------------- pagination end --------------------------------->\n }\n\n</div>\n\n<!----------------------------------- Data template ----------------------------------->\n<ng-template #DataTemplate let-item=\"item\" let-header=\"header\">\n\n <section class=\"flex items-center gap-2\">\n\n @if(header.name == 'NOMBRE' && item.role == 'ROLE_ADMIN') {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-orange-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-orange-600', 'text-xs']\" [icon]=\"['fas', 'crown']\"></fa-icon> -->\n </div>\n }\n\n <span>\n @if (header.innerHtml) {\n <span [innerHTML]=\"getValue(item, header.key)\"></span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"DataTypeTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header, value:header.key}\"></ng-container>\n }\n\n @if(header.subKey){\n <span class=\"block text-neutral-600 text-xs min-w-max\">\n (\n <ng-container [ngTemplateOutlet]=\"DataTypeTemplate\"\n [ngTemplateOutletContext]=\"{item:item, header:header, value:header.subKey}\"></ng-container>\n )\n </span>\n }\n </span>\n\n </section>\n\n</ng-template>\n<!--------------------------------- Data template end --------------------------------->\n\n<!----------------------------------- Data Type template ----------------------------------->\n<ng-template #DataTypeTemplate let-item=\"item\" let-header=\"header\" let-value=\"value\">\n\n <section class=\"inline-block min-w-max\">\n @switch (header.type) {\n\n @case ('boolean') {\n @if(getValue(item, value)){\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-emerald-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-emerald-600', 'text-xs']\" [icon]=\"['fas', 'check']\"></fa-icon> -->\n </div>\n } @else {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-rose-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-rose-600', 'text-xs']\" [icon]=\"['fas', 'xmark']\"></fa-icon> -->\n </div>\n }\n }\n\n @case ('currency'){\n <!-- {{formatEuro(getValue(item, value))}} -->\n }\n\n @case ('dateTime') {\n <span class=\"text-neutral-600 text-sm\">\n {{getValue(item, value) | date: 'dd/MM/yyyy HH:mm'}}\n </span>\n }\n\n @case ('color'){\n <span class=\"inline-block w-8 h-4 rounded-full border border-neutral-200 shadow-sm\"\n [style.background-color]=\"getValue(item, value)\"></span>\n }\n\n @case ('link'){\n @let link = getLink(header.url, item, value);\n\n @if(link.isExternal){\n <a [href]=\"link.url\" class=\"text-purple-600 hover:underline\">\n {{header.linkName}}\n </a>\n }@else{\n <a [routerLink]=\"link.url\" class=\"text-purple-600 hover:underline\" target=\"_blank\">\n {{header.linkName}}\n </a>\n }\n\n }\n\n @case ('image'){\n @let link = getLink(header.url, item, value);\n\n <img [src]=\"link.url\" [alt]=\"getValue(item, value)\" loading=\"lazy\" class=\"w-10 h-10 object-cover\">\n }\n\n @case ('login'){\n @if(item.active){\n <span class=\"inline-flex items-center gap-1\">\n\n @if(item.email_verified_at){\n <div [title]=\"item.email\" class=\"inline-flex items-center justify-center w-6 h-6 bg-blue-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-blue-600', 'text-xs']\" [icon]=\"['fas', 'envelope']\"></fa-icon> -->\n </div>\n }\n\n @if(item.google_id){\n <div [title]=\"item.google_id\"\n class=\"inline-flex items-center justify-center w-6 h-6 bg-red-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-red-600', 'text-xs']\" [icon]=\"['fab', 'google']\"></fa-icon> -->\n </div>\n }\n\n </span>\n } @else {\n <div class=\"inline-flex items-center justify-center w-6 h-6 bg-rose-100 rounded-full\">\n <!-- <fa-icon [ngClass]=\"['text-rose-600', 'text-xs']\" [icon]=\"['fas', 'xmark']\"></fa-icon> -->\n </div>\n }\n }\n\n @default {\n {{getValue(item, value)}}\n }\n }\n </section>\n\n</ng-template>\n<!--------------------------------- Data Type template end --------------------------------->","/*\n * Public API Surface of table\n */\n\nexport * from './lib/table';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;MAca,WAAW,CAAA;AA2CZ,IAAA,IAAA;AACA,IAAA,GAAA;AA3CD,IAAA,GAAG;AACH,IAAA,WAAW;AACX,IAAA,YAAY;IACZ,aAAa,GAAG,MAAM;IACtB,cAAc,GAAG,OAAO;IACxB,eAAe,GAAG,CAAC;IACnB,gBAAgB,GAAG,CAAC;AACpB,IAAA,OAAO;AACN,IAAA,SAAS,GAAG,IAAI,YAAY,EAAE;AAC9B,IAAA,WAAW,GAAG,IAAI,YAAY,EAAE;IAE1C,OAAO,GAAG,KAAK;IAEN,KAAK,GAAQ,EAAE;IAExB,KAAK,GAAa,EAAE;IAEpB,IAAI,GAAG,CAAC;IAEC,KAAK,GAAG,EAAE;;AAGnB,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM;AACpC,QAAA,IAAI,UAAU,IAAI,CAAC,EAAE;;YAEnB,OAAO,IAAI,CAAC,KAAK;QACnB;AAEA,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI;AAC7B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC;AAC1C,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,GAAG,CAAC,CAAC;QAEjD,MAAM,KAAK,GAAa,EAAE;AAC1B,QAAA,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE;AACjC,YAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACf;AAEA,QAAA,OAAO,KAAK;IACd;IAEA,WAAA,CACU,IAAgB,EAChB,GAAsB,EAAA;QADtB,IAAA,CAAA,IAAI,GAAJ,IAAI;QACJ,IAAA,CAAA,GAAG,GAAH,GAAG;IACT;IAEJ,QAAQ,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,QAAQ,EAAE;QACjB;IACF;;IAGQ,eAAe,GAAA;AACrB,QAAA,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC,EAAE;YAC9B,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,gBAAgB;QAChD;AACA,QAAA,OAAO,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,gBAAgB;IAC1C;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;AAEzB,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE;AAC3C,QAAA,MAAM,OAAO,GAAG,CAAA,CAAA,EAAI,IAAI,CAAC,aAAa,CAAA,CAAA,EAAI,YAAY,CAAA,CAAA,EAAI,IAAI,CAAC,cAAc,CAAA,CAAA,EAAI,IAAI,CAAC,KAAK,EAAE;AAE7F,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,SAAS,CAAC;AAC1C,YAAA,IAAI,EAAE,CAAC,IAAS,KAAI;gBAElB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;AAC9C,oBAAA,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC3C;qBAAO;oBACL,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;gBACzB;AAEA,gBAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,oBAAA,IAAI,CAAC,KAAK,GAAG,EAAE;oBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;wBAC7D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;oBACxB;gBACF;AAEA,gBAAA,IAAI,CAAC,OAAO,GAAG,KAAK;AACpB,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC3B,CAAC;AACD,YAAA,KAAK,EAAE,CAAC,KAAU,KAAI;AACpB,gBAAA,OAAO,CAAC,KAAK,CAAC,2BAA2B,GAAG,KAAK,CAAC;AAClD,gBAAA,IAAI,CAAC,OAAO,GAAG,KAAK;AACpB,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;YAC1B;AACD,SAAA,CAAC;IACJ;;IAGA,OAAO,GAAA;AACL,QAAA,IAAI,IAAI,CAAC,GAAG,EAAE;AACZ,YAAA,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;AAChB,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,EAAE;QACjB;IACF;AAEA,IAAA,OAAO,CAAC,OAAA,GAAkB,OAAO,EAAE,IAAS,EAAE,KAAwB,EAAA;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QAC3C,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;AAC9C,QAAA,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;QAE1E,OAAO;YACL,GAAG;YACH;SACD;IACH;IAEA,QAAQ,CAAC,IAAS,EAAE,GAAsB,EAAA;QAExC,IAAI,QAAQ,GAAG,EAAE;QAEjB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AACvB,YAAA,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;QACpB;aAAO;AACL,YAAA,QAAQ,GAAG,GAAG,CAAC,KAAK,EAAE;QACxB;QAEA,IAAI,MAAM,GAAG,EAAE;AAEf,QAAA,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;YAE1B,IAAI,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;YACjC,IAAI,KAAK,GAAG,IAAI;YAEhB,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AAC1B,gBAAA,IAAI,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;AAExC,gBAAA,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,OAAY,KAAK,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAE3G;iBAAO;gBACL,IAAI,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAElC,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;AACvC,gBAAA,IAAI,SAAS,GAAG,OAAO,UAAU,KAAK,SAAS;AAE/C,gBAAA,IAAI,OAAO,IAAI,SAAS,EAAE;AACxB,oBAAA,OAAO,UAAU;gBACnB;AAEA,gBAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC7C,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACxB;YACF;YAEA,QAAQ,CAAC,KAAK,EAAE;YAEhB,MAAM,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;QAE5D;AAEA,QAAA,OAAO,MAAM;IACf;AAEA,IAAA,OAAO,CAAC,KAAU,EAAA;AAChB,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;IAC7B;AAEA,IAAA,UAAU,CAAC,IAAY,EAAA;AACrB,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI,CAAC,QAAQ,EAAE;IACjB;;IAGA,aAAa,GAAA;AACX,QAAA,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;AACnB,YAAA,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACpB;IACF;;IAGA,YAAY,GAAA;AACV,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,GAAG,CAAC,EAAE;AAC1C,YAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC3B;IACF;AAEA,IAAA,eAAe,CAAC,EAAW,EAAA;AACzB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACzB;AAEA,IAAA,iBAAiB,CAAC,EAAW,EAAA;AAC3B,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;IAC3B;uGA/LW,WAAW,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAX,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,KAAA,EAAA,WAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,aAAA,EAAA,eAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,SAAA,EAAA,KAAA,EAAA,OAAA,EAAA,KAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECdxB,4tiBAiW6F,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDnVhF,WAAW,mPALpB,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAEZ,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EADZ,QAAQ,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA;;2FAIC,WAAW,EAAA,UAAA,EAAA,CAAA;kBATvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,WAAW,EAAA,OAAA,EAEZ;wBACP,YAAY;wBACZ,QAAQ;wBACR,YAAY;AACb,qBAAA,EAAA,QAAA,EAAA,4tiBAAA,EAAA;+GAGQ,GAAG,EAAA,CAAA;sBAAX;gBACQ,WAAW,EAAA,CAAA;sBAAnB;gBACQ,YAAY,EAAA,CAAA;sBAApB;gBACQ,aAAa,EAAA,CAAA;sBAArB;gBACQ,cAAc,EAAA,CAAA;sBAAtB;gBACQ,eAAe,EAAA,CAAA;sBAAvB;gBACQ,gBAAgB,EAAA,CAAA;sBAAxB;gBACQ,OAAO,EAAA,CAAA;sBAAf;gBACS,SAAS,EAAA,CAAA;sBAAlB;gBACS,WAAW,EAAA,CAAA;sBAApB;gBAIQ,KAAK,EAAA,CAAA;sBAAb;gBAMQ,KAAK,EAAA,CAAA;sBAAb;;;AElCH;;AAEG;;ACFH;;AAEG;;;;"}
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,51 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
1
2
|
import * as i0 from '@angular/core';
|
|
3
|
+
import { EventEmitter, ChangeDetectorRef } from '@angular/core';
|
|
2
4
|
|
|
3
5
|
declare class TableModule {
|
|
6
|
+
private http;
|
|
7
|
+
private cdr;
|
|
8
|
+
url?: string;
|
|
9
|
+
contentList?: string;
|
|
10
|
+
contentTotal?: string;
|
|
11
|
+
pageParamName: string;
|
|
12
|
+
limitParamName: string;
|
|
13
|
+
sizeInitialPage: number;
|
|
14
|
+
sizeBetweenPages: number;
|
|
15
|
+
headers?: {
|
|
16
|
+
name: string;
|
|
17
|
+
key: string | string[];
|
|
18
|
+
subKey?: string;
|
|
19
|
+
type?: string;
|
|
20
|
+
innerHtml?: boolean;
|
|
21
|
+
headers?: any;
|
|
22
|
+
}[];
|
|
23
|
+
editEvent: EventEmitter<any>;
|
|
24
|
+
deleteEvent: EventEmitter<any>;
|
|
25
|
+
loading: boolean;
|
|
26
|
+
items: any;
|
|
27
|
+
total: number[];
|
|
28
|
+
page: number;
|
|
29
|
+
limit: number;
|
|
30
|
+
get visiblePages(): number[];
|
|
31
|
+
constructor(http: HttpClient, cdr: ChangeDetectorRef);
|
|
32
|
+
ngOnInit(): void;
|
|
33
|
+
private getInternalPage;
|
|
34
|
+
getItems(): void;
|
|
35
|
+
refresh(): void;
|
|
36
|
+
getLink(pattern: string, item: any, value: string | string[]): {
|
|
37
|
+
url: string;
|
|
38
|
+
isExternal: boolean;
|
|
39
|
+
};
|
|
40
|
+
getValue(item: any, key: string | string[]): any;
|
|
41
|
+
isArray(array: any): boolean;
|
|
42
|
+
changePage(page: number): void;
|
|
43
|
+
goToFirstPage(): void;
|
|
44
|
+
goToLastPage(): void;
|
|
45
|
+
clickEditButton(id?: number): void;
|
|
46
|
+
clickDeleteButton(id?: number): void;
|
|
4
47
|
static ɵfac: i0.ɵɵFactoryDeclaration<TableModule, never>;
|
|
5
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<TableModule, "
|
|
48
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TableModule, "sau-table", never, { "url": { "alias": "url"; "required": false; }; "contentList": { "alias": "contentList"; "required": false; }; "contentTotal": { "alias": "contentTotal"; "required": false; }; "pageParamName": { "alias": "pageParamName"; "required": false; }; "limitParamName": { "alias": "limitParamName"; "required": false; }; "sizeInitialPage": { "alias": "sizeInitialPage"; "required": false; }; "sizeBetweenPages": { "alias": "sizeBetweenPages"; "required": false; }; "headers": { "alias": "headers"; "required": false; }; "items": { "alias": "items"; "required": false; }; "limit": { "alias": "limit"; "required": false; }; }, { "editEvent": "editEvent"; "deleteEvent": "deleteEvent"; }, never, never, true, never>;
|
|
6
49
|
}
|
|
7
50
|
|
|
8
51
|
export { TableModule };
|