ng-firebase-table-kxp 1.0.13 → 1.0.14
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/esm2020/lib/components/table/table.component.mjs +7 -7
- package/esm2020/lib/services/table.service.mjs +9 -2
- package/fesm2015/ng-firebase-table-kxp.mjs +14 -8
- package/fesm2015/ng-firebase-table-kxp.mjs.map +1 -1
- package/fesm2020/ng-firebase-table-kxp.mjs +14 -7
- package/fesm2020/ng-firebase-table-kxp.mjs.map +1 -1
- package/lib/components/table/table.component.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1069,7 +1069,14 @@ class TableService {
|
|
|
1069
1069
|
indexFields.push(arrange.sortBy.field);
|
|
1070
1070
|
}
|
|
1071
1071
|
if (indexFields.length > 1) {
|
|
1072
|
-
|
|
1072
|
+
// Obter o projectId dinamicamente do Firebase
|
|
1073
|
+
const projectId = this.ngFire?.firestore?.app?.options
|
|
1074
|
+
?.projectId;
|
|
1075
|
+
if (!projectId) {
|
|
1076
|
+
console.warn('Não foi possível obter o projectId do Firebase');
|
|
1077
|
+
return null;
|
|
1078
|
+
}
|
|
1079
|
+
const baseUrl = `https://console.firebase.google.com/project/${projectId}/firestore/indexes`;
|
|
1073
1080
|
const queryParams = new URLSearchParams({
|
|
1074
1081
|
create_composite: `collection=${collection}&fields=${indexFields.join(',')}`,
|
|
1075
1082
|
});
|
|
@@ -1186,6 +1193,8 @@ class TableComponent {
|
|
|
1186
1193
|
this.showTooltip = false;
|
|
1187
1194
|
this.tooltipContent = '';
|
|
1188
1195
|
this.tooltipPosition = { x: 0, y: 0 };
|
|
1196
|
+
// Validador de data armazenado como propriedade para compatibilidade com ngx-mask
|
|
1197
|
+
this.dateValidator = this.tableService.dateFormatValidator();
|
|
1189
1198
|
this.filtersForm = new FormArray([this.createFilterGroup()]);
|
|
1190
1199
|
}
|
|
1191
1200
|
createFilterGroup() {
|
|
@@ -1193,10 +1202,8 @@ class TableComponent {
|
|
|
1193
1202
|
selectFilter: new FormControl(''),
|
|
1194
1203
|
typeFilter: new FormControl(''),
|
|
1195
1204
|
selectItem: new FormControl(''),
|
|
1196
|
-
initialDate: new FormControl('', [
|
|
1197
|
-
|
|
1198
|
-
]),
|
|
1199
|
-
finalDate: new FormControl('', [this.tableService.dateFormatValidator()]),
|
|
1205
|
+
initialDate: new FormControl('', [this.dateValidator]),
|
|
1206
|
+
finalDate: new FormControl('', [this.dateValidator]),
|
|
1200
1207
|
});
|
|
1201
1208
|
}
|
|
1202
1209
|
addFilter(filterData) {
|
|
@@ -2202,10 +2209,10 @@ class TableComponent {
|
|
|
2202
2209
|
}
|
|
2203
2210
|
}
|
|
2204
2211
|
TableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TableComponent, deps: [{ token: i1$1.Router }, { token: TableService }, { token: i1.AngularFirestore }], target: i0.ɵɵFactoryTarget.Component });
|
|
2205
|
-
TableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TableComponent, selector: "lib-table", inputs: { data: "data", downloadTable: "downloadTable" }, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }], ngImport: i0, template: "<div *ngIf=\"data\" class=\"card-body\">\n <div class=\"flex flex-col justify-between gap-6\">\n <!-- UNIFIED CONTROL PANEL: FILTERS, SORT & ACTIONS -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"\n data.pagination === true &&\n (dropdownItems.length > 0 ||\n sortableDropdownItems.length > 0 ||\n data.actionButton)\n \"\n >\n <!-- PANEL HEADER: Title, Custom Action, and Global Actions -->\n <div\n class=\"mb-4 flex flex-col items-start justify-between gap-4 border-b-2 border-gray-200 pb-4 md:flex-row md:items-center\"\n >\n <!-- Left Side: Title & Main Action Button -->\n <div class=\"flex flex-wrap items-center gap-4\">\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-filter text-xl text-blue-500\"></i>\n <span class=\"text-lg font-semibold text-gray-700\"\n >Filtros e A\u00E7\u00F5es</span\n >\n </div>\n <button\n *ngIf=\"data.actionButton && data.actionButton.condition\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i\n *ngIf=\"data.actionButton.icon\"\n [class]=\"data.actionButton.icon\"\n ></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- Right Side: Search, Reset, Export -->\n <div\n class=\"flex flex-wrap gap-3\"\n *ngIf=\"\n this.hasFilterableColumn === true || this.hasSortableColumn === true\n \"\n >\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Pesquisar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"\n $any(arrange) && downloadTable !== undefined\n ? downloadTable($any(arrange), data.conditions || [])\n : null\n \"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n\n <!-- FILTERS CONTENT (WITH REFINEMENTS) -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option *ngFor=\"let item of getAvailableFilterOptions()\" [value]=\"item\">\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Sort -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Sort Dropdown -->\n <div\n class=\"w-full sm:w-auto sm:min-w-[250px]\"\n *ngIf=\"sortableDropdownItems.length > 0\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Ordenar por</mat-label>\n <mat-select placeholder=\"Selecione...\" [formControl]=\"selectSort\">\n <mat-option\n *ngFor=\"let item of sortableDropdownItems\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-sort-alpha-down text-cyan-600\"></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n\n <!-- SIMPLE SEARCH (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && hasFilterableColumn === true\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-blue-500\"></i>\n Buscar\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n (keyup)=\"applyFilter(filterInput.value)\"\n placeholder=\"Digite para filtrar...\"\n #filterInput\n />\n <mat-icon matSuffix class=\"text-gray-500\">search</mat-icon>\n </mat-form-field>\n <button\n *ngIf=\"data.actionButton\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' float-right flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i *ngIf=\"data.actionButton.icon\" [class]=\"data.actionButton.icon\"></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- FILTERS PANEL (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && dropdownItems.length > 0\"\n >\n <!-- FILTERS CONTENT -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option *ngFor=\"let item of getAvailableFilterOptions()\" [value]=\"item\">\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Actions -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex flex-wrap gap-3\">\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Aplicar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"handleDownload()\"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"flex flex-col\">\n <div\n class=\"mx-auto flex flex-col\"\n *ngIf=\"data.tabs && data.tabs.tabsData && data.tabs.tabsData.length > 0\"\n >\n <!-- Calcular quantos grupos de 6 tabs existem -->\n <ng-container\n *ngFor=\"\n let groupIndex of getTabGroups(data.tabs.tabsData);\n let i = index\n \"\n >\n <div class=\"mx-auto flex flex-row\">\n <ng-container\n *ngFor=\"\n let tab of getTabGroup(data.tabs.tabsData, groupIndex);\n let j = index\n \"\n >\n <button\n class=\"border-2 border-gray-300 bg-gray-200 px-4 py-2 font-medium transition hover:brightness-95\"\n [ngClass]=\"\n isTabSelected(getRealTabIndex(i, j))\n ? 'border-b-0 brightness-110'\n : ''\n \"\n (click)=\"onTableSelected(i, j)\"\n >\n {{ tab.label }}\n <span\n *ngIf=\"tab.counter !== undefined\"\n class=\"ml-2 text-xs font-bold\"\n [ngClass]=\"tab.counterClass\"\n >\n {{ tab.counter }}\n </span>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class=\"mat-elevation-z8 w-full overflow-x-auto rounded-xl\">\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n #sort=\"matSort\"\n matSortActive=\"createdAt\"\n matSortDirection=\"desc\"\n >\n <ng-container\n *ngFor=\"let col of data.displayedColumns\"\n matColumnDef=\"{{ col.property }}\"\n >\n <ng-container *matHeaderCellDef>\n <!-- IF THE COLUMN IS NOT SORTABLE, THEN DON'T SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"!col.isSortable || data.pagination === true\"\n mat-header-cell\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <!-- IF THE COLUMN IS SORTABLE, THEN SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"col.isSortable && data.pagination === false\"\n mat-header-cell\n mat-sort-header\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n (click)=\"col.method ? col.method(row) : null\"\n (mouseenter)=\"onCellMouseEnter($event, row, col)\"\n (mouseleave)=\"onCellMouseLeave()\"\n (mousemove)=\"onCellMouseMove($event)\"\n >\n <!-- CHECK IF THE COLUMN MUST BE DISPLAYED -->\n <span *ngIf=\"!col.image && !col.iconClass && !col.method\">\n <ng-container>\n <span\n *ngIf=\"\n col.charLimit &&\n row[col.property] &&\n row[col.property].length > col.charLimit;\n else withinLimit\n \"\n >\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row) }}\n </span>\n </span>\n </ng-container>\n <ng-template #withinLimit>\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row, true) }}\n </span>\n </ng-template>\n </span>\n <!------------------- IMAGE ------------------>\n <img\n *ngIf=\"\n col.image && col.image.path && !col.iconClass && !col.method\n \"\n [src]=\"col.image.path + '/' + row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <img\n *ngIf=\"\n col.image && col.image.url && !col.iconClass && !col.method\n \"\n [src]=\"row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <ng-container *ngIf=\"col.iconClass\">\n <button\n *ngFor=\"let iconClass of col.iconClass\"\n (click)=\"\n iconClass.buttonMethod\n ? iconClass.buttonMethod(row, $event)\n : $event.stopPropagation()\n \"\n >\n <span\n [ngClass]=\"iconClass.class\"\n *ngIf=\"\n iconClass.condition === undefined ||\n (iconClass.condition !== undefined &&\n $any(iconClass.condition)(row))\n \"\n >{{ iconClass.text }}</span\n >\n </button>\n </ng-container>\n </td>\n </ng-container>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnProperties\"></tr>\n <tr\n [ngClass]=\"{\n 'example-element-row': data.isNotClickable === true,\n 'example-element-row cursor-pointer': !data.isNotClickable\n }\"\n mat-row\n *matRowDef=\"let row; columns: columnProperties\"\n (click)=\"goToDetails(row)\"\n ></tr>\n\n <!-- ROW SHOWN WHEN THERE IS NO MATCHING DATA. -->\n <tr class=\"mat-row\" *matNoDataRow>\n <td *ngIf=\"!isLoading\" class=\"mat-cell p-4\" colspan=\"4\">\n Nenhum resultado encontrado para a busca\n </td>\n </tr>\n </table>\n\n <div class=\"flex justify-center\" *ngIf=\"isLoading\">\n <mat-spinner></mat-spinner>\n </div>\n\n <div class=\"paginator-container\">\n <mat-paginator\n #paginator\n [pageSizeOptions]=\"[25, 50, 100]\"\n [pageSize]=\"pageSize\"\n [length]=\"totalItems\"\n showFirstLastButtons\n aria-label=\"Select page of periodic elements\"\n (page)=\"onPageChange($event)\"\n [ngClass]=\"{\n 'hide-length':\n ['filter', 'filterByDate', 'equals'].includes(\n this.currentArrange\n ) || this.data.filterFn,\n 'hide-next-button': !hasNextPage && data.pagination === true,\n 'hide-last-button':\n (!hasNextPage && data.pagination === true) || this.data.filterFn\n }\"\n >\n </mat-paginator>\n <div\n *ngIf=\"\n !isLoading &&\n dataSource?.data &&\n dataSource.data.length > 0 &&\n data?.filterFn\n \"\n class=\"page-number-display\"\n >\n {{ currentPageNumber }}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- TOOLTIP PERSONALIZADO -->\n <div\n *ngIf=\"showTooltip\"\n class=\"fixed z-50 max-w-md break-words rounded-lg bg-gray-800 px-3 py-2 text-sm text-white shadow-lg\"\n [style.left.px]=\"tooltipPosition.x\"\n [style.top.px]=\"tooltipPosition.y\"\n [style.pointer-events]=\"'none'\"\n >\n {{ tooltipContent }}\n </div>\n</div>\n", styles: ["::ng-deep .hide-length .mat-mdc-paginator-range-label{display:none}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-next.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base{visibility:hidden}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-last.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base.ng-star-inserted{visibility:hidden}::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field.ng-tns-c162-1.mdc-text-field--filled{width:25dvw}::ng-deep .custom-filter .mat-mdc-text-field-wrapper{width:20dvw;max-width:300px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i6.MatNoDataRow, selector: "ng-template[matNoDataRow]" }, { kind: "component", type: i7.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "directive", type: i8.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i11.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i12.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i14.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i15.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i16.NgxMaskDirective, selector: "input[mask], textarea[mask]", inputs: ["mask", "specialCharacters", "patterns", "prefix", "suffix", "thousandSeparator", "decimalMarker", "dropSpecialCharacters", "hiddenInput", "showMaskTyped", "placeHolderCharacter", "shownMaskExpression", "showTemplate", "clearIfNotMatch", "validation", "separatorLimit", "allowNegativeNumbers", "leadZeroDateTime", "leadZero", "triggerOnMaskChange", "apm", "inputTransformFn", "outputTransformFn", "keepCharacterPositions"], outputs: ["maskFilled"], exportAs: ["mask", "ngxMask"] }] });
|
|
2212
|
+
TableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TableComponent, selector: "lib-table", inputs: { data: "data", downloadTable: "downloadTable" }, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }], ngImport: i0, template: "<div *ngIf=\"data\" class=\"card-body\">\n <div class=\"flex flex-col justify-between gap-6\">\n <!-- UNIFIED CONTROL PANEL: FILTERS, SORT & ACTIONS -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"\n data.pagination === true &&\n (dropdownItems.length > 0 ||\n sortableDropdownItems.length > 0 ||\n data.actionButton)\n \"\n >\n <!-- PANEL HEADER: Title, Custom Action, and Global Actions -->\n <div\n class=\"mb-4 flex flex-col items-start justify-between gap-4 border-b-2 border-gray-200 pb-4 md:flex-row md:items-center\"\n >\n <!-- Left Side: Title & Main Action Button -->\n <div class=\"flex flex-wrap items-center gap-4\">\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-filter text-xl text-blue-500\"></i>\n <span class=\"text-lg font-semibold text-gray-700\"\n >Filtros e A\u00E7\u00F5es</span\n >\n </div>\n <button\n *ngIf=\"data.actionButton && data.actionButton.condition\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i\n *ngIf=\"data.actionButton.icon\"\n [class]=\"data.actionButton.icon\"\n ></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- Right Side: Search, Reset, Export -->\n <div\n class=\"flex flex-wrap gap-3\"\n *ngIf=\"\n this.hasFilterableColumn === true || this.hasSortableColumn === true\n \"\n >\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Pesquisar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"\n $any(arrange) && downloadTable !== undefined\n ? downloadTable($any(arrange), data.conditions || [])\n : null\n \"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n\n <!-- FILTERS CONTENT (WITH REFINEMENTS) -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option\n *ngFor=\"let item of getAvailableFilterOptions()\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n type=\"text\"\n matInput\n (keydown.enter)=\"search($event)\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n type=\"text\"\n (keydown.enter)=\"search($event)\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Sort -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Sort Dropdown -->\n <div\n class=\"w-full sm:w-auto sm:min-w-[250px]\"\n *ngIf=\"sortableDropdownItems.length > 0\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Ordenar por</mat-label>\n <mat-select placeholder=\"Selecione...\" [formControl]=\"selectSort\">\n <mat-option\n *ngFor=\"let item of sortableDropdownItems\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-sort-alpha-down text-cyan-600\"></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n\n <!-- SIMPLE SEARCH (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && hasFilterableColumn === true\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-blue-500\"></i>\n Buscar\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n (keyup)=\"applyFilter(filterInput.value)\"\n placeholder=\"Digite para filtrar...\"\n #filterInput\n />\n <mat-icon matSuffix class=\"text-gray-500\">search</mat-icon>\n </mat-form-field>\n <button\n *ngIf=\"data.actionButton\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' float-right flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i *ngIf=\"data.actionButton.icon\" [class]=\"data.actionButton.icon\"></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- FILTERS PANEL (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && dropdownItems.length > 0\"\n >\n <!-- FILTERS CONTENT -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option\n *ngFor=\"let item of getAvailableFilterOptions()\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n type=\"text\"\n matInput\n (keydown.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n type=\"text\"\n (keydown.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Actions -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex flex-wrap gap-3\">\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Aplicar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"handleDownload()\"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"flex flex-col\">\n <div\n class=\"mx-auto flex flex-col\"\n *ngIf=\"data.tabs && data.tabs.tabsData && data.tabs.tabsData.length > 0\"\n >\n <!-- Calcular quantos grupos de 6 tabs existem -->\n <ng-container\n *ngFor=\"\n let groupIndex of getTabGroups(data.tabs.tabsData);\n let i = index\n \"\n >\n <div class=\"mx-auto flex flex-row\">\n <ng-container\n *ngFor=\"\n let tab of getTabGroup(data.tabs.tabsData, groupIndex);\n let j = index\n \"\n >\n <button\n class=\"border-2 border-gray-300 bg-gray-200 px-4 py-2 font-medium transition hover:brightness-95\"\n [ngClass]=\"\n isTabSelected(getRealTabIndex(i, j))\n ? 'border-b-0 brightness-110'\n : ''\n \"\n (click)=\"onTableSelected(i, j)\"\n >\n {{ tab.label }}\n <span\n *ngIf=\"tab.counter !== undefined\"\n class=\"ml-2 text-xs font-bold\"\n [ngClass]=\"tab.counterClass\"\n >\n {{ tab.counter }}\n </span>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class=\"mat-elevation-z8 w-full overflow-x-auto rounded-xl\">\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n #sort=\"matSort\"\n matSortActive=\"createdAt\"\n matSortDirection=\"desc\"\n >\n <ng-container\n *ngFor=\"let col of data.displayedColumns\"\n matColumnDef=\"{{ col.property }}\"\n >\n <ng-container *matHeaderCellDef>\n <!-- IF THE COLUMN IS NOT SORTABLE, THEN DON'T SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"!col.isSortable || data.pagination === true\"\n mat-header-cell\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <!-- IF THE COLUMN IS SORTABLE, THEN SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"col.isSortable && data.pagination === false\"\n mat-header-cell\n mat-sort-header\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n (click)=\"col.method ? col.method(row) : null\"\n (mouseenter)=\"onCellMouseEnter($event, row, col)\"\n (mouseleave)=\"onCellMouseLeave()\"\n (mousemove)=\"onCellMouseMove($event)\"\n >\n <!-- CHECK IF THE COLUMN MUST BE DISPLAYED -->\n <span *ngIf=\"!col.image && !col.iconClass && !col.method\">\n <ng-container>\n <span\n *ngIf=\"\n col.charLimit &&\n row[col.property] &&\n row[col.property].length > col.charLimit;\n else withinLimit\n \"\n >\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row) }}\n </span>\n </span>\n </ng-container>\n <ng-template #withinLimit>\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row, true) }}\n </span>\n </ng-template>\n </span>\n <!------------------- IMAGE ------------------>\n <img\n *ngIf=\"\n col.image && col.image.path && !col.iconClass && !col.method\n \"\n [src]=\"col.image.path + '/' + row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <img\n *ngIf=\"\n col.image && col.image.url && !col.iconClass && !col.method\n \"\n [src]=\"row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <ng-container *ngIf=\"col.iconClass\">\n <button\n *ngFor=\"let iconClass of col.iconClass\"\n (click)=\"\n iconClass.buttonMethod\n ? iconClass.buttonMethod(row, $event)\n : $event.stopPropagation()\n \"\n >\n <span\n [ngClass]=\"iconClass.class\"\n *ngIf=\"\n iconClass.condition === undefined ||\n (iconClass.condition !== undefined &&\n $any(iconClass.condition)(row))\n \"\n >{{ iconClass.text }}</span\n >\n </button>\n </ng-container>\n </td>\n </ng-container>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnProperties\"></tr>\n <tr\n [ngClass]=\"{\n 'example-element-row': data.isNotClickable === true,\n 'example-element-row cursor-pointer': !data.isNotClickable\n }\"\n mat-row\n *matRowDef=\"let row; columns: columnProperties\"\n (click)=\"goToDetails(row)\"\n ></tr>\n\n <!-- ROW SHOWN WHEN THERE IS NO MATCHING DATA. -->\n <tr class=\"mat-row\" *matNoDataRow>\n <td *ngIf=\"!isLoading\" class=\"mat-cell p-4\" colspan=\"4\">\n Nenhum resultado encontrado para a busca\n </td>\n </tr>\n </table>\n\n <div class=\"flex justify-center\" *ngIf=\"isLoading\">\n <mat-spinner></mat-spinner>\n </div>\n\n <div class=\"paginator-container\">\n <mat-paginator\n #paginator\n [pageSizeOptions]=\"[25, 50, 100]\"\n [pageSize]=\"pageSize\"\n [length]=\"totalItems\"\n showFirstLastButtons\n aria-label=\"Select page of periodic elements\"\n (page)=\"onPageChange($event)\"\n [ngClass]=\"{\n 'hide-length':\n ['filter', 'filterByDate', 'equals'].includes(\n this.currentArrange\n ) || this.data.filterFn,\n 'hide-next-button': !hasNextPage && data.pagination === true,\n 'hide-last-button':\n (!hasNextPage && data.pagination === true) || this.data.filterFn\n }\"\n >\n </mat-paginator>\n <div\n *ngIf=\"\n !isLoading &&\n dataSource?.data &&\n dataSource.data.length > 0 &&\n data?.filterFn\n \"\n class=\"page-number-display\"\n >\n {{ currentPageNumber }}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- TOOLTIP PERSONALIZADO -->\n <div\n *ngIf=\"showTooltip\"\n class=\"fixed z-50 max-w-md break-words rounded-lg bg-gray-800 px-3 py-2 text-sm text-white shadow-lg\"\n [style.left.px]=\"tooltipPosition.x\"\n [style.top.px]=\"tooltipPosition.y\"\n [style.pointer-events]=\"'none'\"\n >\n {{ tooltipContent }}\n </div>\n</div>\n", styles: ["::ng-deep .hide-length .mat-mdc-paginator-range-label{display:none}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-next.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base{visibility:hidden}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-last.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base.ng-star-inserted{visibility:hidden}::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field.ng-tns-c162-1.mdc-text-field--filled{width:25dvw}::ng-deep .custom-filter .mat-mdc-text-field-wrapper{width:20dvw;max-width:300px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i6.MatNoDataRow, selector: "ng-template[matNoDataRow]" }, { kind: "component", type: i7.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "directive", type: i8.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i11.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i12.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i14.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i15.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i16.NgxMaskDirective, selector: "input[mask], textarea[mask]", inputs: ["mask", "specialCharacters", "patterns", "prefix", "suffix", "thousandSeparator", "decimalMarker", "dropSpecialCharacters", "hiddenInput", "showMaskTyped", "placeHolderCharacter", "shownMaskExpression", "showTemplate", "clearIfNotMatch", "validation", "separatorLimit", "allowNegativeNumbers", "leadZeroDateTime", "leadZero", "triggerOnMaskChange", "apm", "inputTransformFn", "outputTransformFn", "keepCharacterPositions"], outputs: ["maskFilled"], exportAs: ["mask", "ngxMask"] }] });
|
|
2206
2213
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TableComponent, decorators: [{
|
|
2207
2214
|
type: Component,
|
|
2208
|
-
args: [{ selector: 'lib-table', template: "<div *ngIf=\"data\" class=\"card-body\">\n <div class=\"flex flex-col justify-between gap-6\">\n <!-- UNIFIED CONTROL PANEL: FILTERS, SORT & ACTIONS -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"\n data.pagination === true &&\n (dropdownItems.length > 0 ||\n sortableDropdownItems.length > 0 ||\n data.actionButton)\n \"\n >\n <!-- PANEL HEADER: Title, Custom Action, and Global Actions -->\n <div\n class=\"mb-4 flex flex-col items-start justify-between gap-4 border-b-2 border-gray-200 pb-4 md:flex-row md:items-center\"\n >\n <!-- Left Side: Title & Main Action Button -->\n <div class=\"flex flex-wrap items-center gap-4\">\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-filter text-xl text-blue-500\"></i>\n <span class=\"text-lg font-semibold text-gray-700\"\n >Filtros e A\u00E7\u00F5es</span\n >\n </div>\n <button\n *ngIf=\"data.actionButton && data.actionButton.condition\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i\n *ngIf=\"data.actionButton.icon\"\n [class]=\"data.actionButton.icon\"\n ></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- Right Side: Search, Reset, Export -->\n <div\n class=\"flex flex-wrap gap-3\"\n *ngIf=\"\n this.hasFilterableColumn === true || this.hasSortableColumn === true\n \"\n >\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Pesquisar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"\n $any(arrange) && downloadTable !== undefined\n ? downloadTable($any(arrange), data.conditions || [])\n : null\n \"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n\n <!-- FILTERS CONTENT (WITH REFINEMENTS) -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option *ngFor=\"let item of getAvailableFilterOptions()\" [value]=\"item\">\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Sort -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Sort Dropdown -->\n <div\n class=\"w-full sm:w-auto sm:min-w-[250px]\"\n *ngIf=\"sortableDropdownItems.length > 0\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Ordenar por</mat-label>\n <mat-select placeholder=\"Selecione...\" [formControl]=\"selectSort\">\n <mat-option\n *ngFor=\"let item of sortableDropdownItems\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-sort-alpha-down text-cyan-600\"></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n\n <!-- SIMPLE SEARCH (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && hasFilterableColumn === true\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-blue-500\"></i>\n Buscar\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n (keyup)=\"applyFilter(filterInput.value)\"\n placeholder=\"Digite para filtrar...\"\n #filterInput\n />\n <mat-icon matSuffix class=\"text-gray-500\">search</mat-icon>\n </mat-form-field>\n <button\n *ngIf=\"data.actionButton\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' float-right flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i *ngIf=\"data.actionButton.icon\" [class]=\"data.actionButton.icon\"></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- FILTERS PANEL (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && dropdownItems.length > 0\"\n >\n <!-- FILTERS CONTENT -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option *ngFor=\"let item of getAvailableFilterOptions()\" [value]=\"item\">\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Actions -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex flex-wrap gap-3\">\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Aplicar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"handleDownload()\"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"flex flex-col\">\n <div\n class=\"mx-auto flex flex-col\"\n *ngIf=\"data.tabs && data.tabs.tabsData && data.tabs.tabsData.length > 0\"\n >\n <!-- Calcular quantos grupos de 6 tabs existem -->\n <ng-container\n *ngFor=\"\n let groupIndex of getTabGroups(data.tabs.tabsData);\n let i = index\n \"\n >\n <div class=\"mx-auto flex flex-row\">\n <ng-container\n *ngFor=\"\n let tab of getTabGroup(data.tabs.tabsData, groupIndex);\n let j = index\n \"\n >\n <button\n class=\"border-2 border-gray-300 bg-gray-200 px-4 py-2 font-medium transition hover:brightness-95\"\n [ngClass]=\"\n isTabSelected(getRealTabIndex(i, j))\n ? 'border-b-0 brightness-110'\n : ''\n \"\n (click)=\"onTableSelected(i, j)\"\n >\n {{ tab.label }}\n <span\n *ngIf=\"tab.counter !== undefined\"\n class=\"ml-2 text-xs font-bold\"\n [ngClass]=\"tab.counterClass\"\n >\n {{ tab.counter }}\n </span>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class=\"mat-elevation-z8 w-full overflow-x-auto rounded-xl\">\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n #sort=\"matSort\"\n matSortActive=\"createdAt\"\n matSortDirection=\"desc\"\n >\n <ng-container\n *ngFor=\"let col of data.displayedColumns\"\n matColumnDef=\"{{ col.property }}\"\n >\n <ng-container *matHeaderCellDef>\n <!-- IF THE COLUMN IS NOT SORTABLE, THEN DON'T SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"!col.isSortable || data.pagination === true\"\n mat-header-cell\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <!-- IF THE COLUMN IS SORTABLE, THEN SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"col.isSortable && data.pagination === false\"\n mat-header-cell\n mat-sort-header\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n (click)=\"col.method ? col.method(row) : null\"\n (mouseenter)=\"onCellMouseEnter($event, row, col)\"\n (mouseleave)=\"onCellMouseLeave()\"\n (mousemove)=\"onCellMouseMove($event)\"\n >\n <!-- CHECK IF THE COLUMN MUST BE DISPLAYED -->\n <span *ngIf=\"!col.image && !col.iconClass && !col.method\">\n <ng-container>\n <span\n *ngIf=\"\n col.charLimit &&\n row[col.property] &&\n row[col.property].length > col.charLimit;\n else withinLimit\n \"\n >\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row) }}\n </span>\n </span>\n </ng-container>\n <ng-template #withinLimit>\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row, true) }}\n </span>\n </ng-template>\n </span>\n <!------------------- IMAGE ------------------>\n <img\n *ngIf=\"\n col.image && col.image.path && !col.iconClass && !col.method\n \"\n [src]=\"col.image.path + '/' + row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <img\n *ngIf=\"\n col.image && col.image.url && !col.iconClass && !col.method\n \"\n [src]=\"row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <ng-container *ngIf=\"col.iconClass\">\n <button\n *ngFor=\"let iconClass of col.iconClass\"\n (click)=\"\n iconClass.buttonMethod\n ? iconClass.buttonMethod(row, $event)\n : $event.stopPropagation()\n \"\n >\n <span\n [ngClass]=\"iconClass.class\"\n *ngIf=\"\n iconClass.condition === undefined ||\n (iconClass.condition !== undefined &&\n $any(iconClass.condition)(row))\n \"\n >{{ iconClass.text }}</span\n >\n </button>\n </ng-container>\n </td>\n </ng-container>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnProperties\"></tr>\n <tr\n [ngClass]=\"{\n 'example-element-row': data.isNotClickable === true,\n 'example-element-row cursor-pointer': !data.isNotClickable\n }\"\n mat-row\n *matRowDef=\"let row; columns: columnProperties\"\n (click)=\"goToDetails(row)\"\n ></tr>\n\n <!-- ROW SHOWN WHEN THERE IS NO MATCHING DATA. -->\n <tr class=\"mat-row\" *matNoDataRow>\n <td *ngIf=\"!isLoading\" class=\"mat-cell p-4\" colspan=\"4\">\n Nenhum resultado encontrado para a busca\n </td>\n </tr>\n </table>\n\n <div class=\"flex justify-center\" *ngIf=\"isLoading\">\n <mat-spinner></mat-spinner>\n </div>\n\n <div class=\"paginator-container\">\n <mat-paginator\n #paginator\n [pageSizeOptions]=\"[25, 50, 100]\"\n [pageSize]=\"pageSize\"\n [length]=\"totalItems\"\n showFirstLastButtons\n aria-label=\"Select page of periodic elements\"\n (page)=\"onPageChange($event)\"\n [ngClass]=\"{\n 'hide-length':\n ['filter', 'filterByDate', 'equals'].includes(\n this.currentArrange\n ) || this.data.filterFn,\n 'hide-next-button': !hasNextPage && data.pagination === true,\n 'hide-last-button':\n (!hasNextPage && data.pagination === true) || this.data.filterFn\n }\"\n >\n </mat-paginator>\n <div\n *ngIf=\"\n !isLoading &&\n dataSource?.data &&\n dataSource.data.length > 0 &&\n data?.filterFn\n \"\n class=\"page-number-display\"\n >\n {{ currentPageNumber }}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- TOOLTIP PERSONALIZADO -->\n <div\n *ngIf=\"showTooltip\"\n class=\"fixed z-50 max-w-md break-words rounded-lg bg-gray-800 px-3 py-2 text-sm text-white shadow-lg\"\n [style.left.px]=\"tooltipPosition.x\"\n [style.top.px]=\"tooltipPosition.y\"\n [style.pointer-events]=\"'none'\"\n >\n {{ tooltipContent }}\n </div>\n</div>\n", styles: ["::ng-deep .hide-length .mat-mdc-paginator-range-label{display:none}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-next.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base{visibility:hidden}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-last.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base.ng-star-inserted{visibility:hidden}::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field.ng-tns-c162-1.mdc-text-field--filled{width:25dvw}::ng-deep .custom-filter .mat-mdc-text-field-wrapper{width:20dvw;max-width:300px}\n"] }]
|
|
2215
|
+
args: [{ selector: 'lib-table', template: "<div *ngIf=\"data\" class=\"card-body\">\n <div class=\"flex flex-col justify-between gap-6\">\n <!-- UNIFIED CONTROL PANEL: FILTERS, SORT & ACTIONS -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"\n data.pagination === true &&\n (dropdownItems.length > 0 ||\n sortableDropdownItems.length > 0 ||\n data.actionButton)\n \"\n >\n <!-- PANEL HEADER: Title, Custom Action, and Global Actions -->\n <div\n class=\"mb-4 flex flex-col items-start justify-between gap-4 border-b-2 border-gray-200 pb-4 md:flex-row md:items-center\"\n >\n <!-- Left Side: Title & Main Action Button -->\n <div class=\"flex flex-wrap items-center gap-4\">\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-filter text-xl text-blue-500\"></i>\n <span class=\"text-lg font-semibold text-gray-700\"\n >Filtros e A\u00E7\u00F5es</span\n >\n </div>\n <button\n *ngIf=\"data.actionButton && data.actionButton.condition\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i\n *ngIf=\"data.actionButton.icon\"\n [class]=\"data.actionButton.icon\"\n ></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- Right Side: Search, Reset, Export -->\n <div\n class=\"flex flex-wrap gap-3\"\n *ngIf=\"\n this.hasFilterableColumn === true || this.hasSortableColumn === true\n \"\n >\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Pesquisar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"\n $any(arrange) && downloadTable !== undefined\n ? downloadTable($any(arrange), data.conditions || [])\n : null\n \"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n\n <!-- FILTERS CONTENT (WITH REFINEMENTS) -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option\n *ngFor=\"let item of getAvailableFilterOptions()\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n type=\"text\"\n matInput\n (keydown.enter)=\"search($event)\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n type=\"text\"\n (keydown.enter)=\"search($event)\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Sort -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Sort Dropdown -->\n <div\n class=\"w-full sm:w-auto sm:min-w-[250px]\"\n *ngIf=\"sortableDropdownItems.length > 0\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Ordenar por</mat-label>\n <mat-select placeholder=\"Selecione...\" [formControl]=\"selectSort\">\n <mat-option\n *ngFor=\"let item of sortableDropdownItems\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i class=\"fa fa-sort-alpha-down text-cyan-600\"></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </div>\n\n <!-- SIMPLE SEARCH (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && hasFilterableColumn === true\"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-blue-500\"></i>\n Buscar\n </mat-label>\n <input\n matInput\n (keyup.enter)=\"search($event)\"\n (keyup)=\"applyFilter(filterInput.value)\"\n placeholder=\"Digite para filtrar...\"\n #filterInput\n />\n <mat-icon matSuffix class=\"text-gray-500\">search</mat-icon>\n </mat-form-field>\n <button\n *ngIf=\"data.actionButton\"\n [ngClass]=\"\n (data.actionButton.colorClass || 'bg-blue-500') +\n ' float-right flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium text-white hover:opacity-70'\n \"\n [routerLink]=\"data.actionButton.routerLink\"\n (click)=\"\n data.actionButton.method ? data.actionButton.method($event) : null\n \"\n >\n <i *ngIf=\"data.actionButton.icon\" [class]=\"data.actionButton.icon\"></i>\n {{ data.actionButton.label }}\n </button>\n </div>\n\n <!-- FILTERS PANEL (for non-paginated tables) -->\n <div\n class=\"rounded-xl border border-gray-200 bg-white p-4 shadow-lg\"\n *ngIf=\"data.pagination === false && dropdownItems.length > 0\"\n >\n <!-- FILTERS CONTENT -->\n <div class=\"mb-4 space-y-3\" *ngIf=\"filtersForm.controls.length > 0\">\n <div\n [formGroup]=\"$any(filterGroup)\"\n *ngFor=\"let filterGroup of filtersForm.controls; let i = index\"\n class=\"flex flex-wrap items-center gap-3 rounded-lg border border-gray-200 p-2\"\n >\n <!-- FILTER TYPE SELECTOR -->\n <div class=\"min-w-[200px] flex-1\" *ngIf=\"dropdownItems.length > 0\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>Tipo de filtro</mat-label>\n <mat-select\n placeholder=\"Selecione o tipo...\"\n formControlName=\"selectFilter\"\n (selectionChange)=\"onSelectFilterChange()\"\n >\n <mat-option\n *ngFor=\"let item of getAvailableFilterOptions()\"\n [value]=\"item\"\n >\n <div class=\"flex items-center gap-2\">\n <i\n [class]=\"item.icon || 'fa fa-filter'\"\n class=\"text-sm text-blue-500\"\n ></i>\n <span>{{ item.title }}</span>\n </div>\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- TEXT FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange === 'filter'\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-search text-gray-400\"></i>\n <span>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Filtrar\"\n }}</span>\n </mat-label>\n <input\n (keyup.enter)=\"search($event)\"\n formControlName=\"typeFilter\"\n matInput\n placeholder=\"Digite para filtrar...\"\n #input\n />\n </mat-form-field>\n </div>\n\n <!-- DROPDOWN FILTER -->\n <div\n class=\"min-w-[200px] flex-1\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value &&\n $any(filterGroup)\n .get('selectFilter')\n ?.value.hasOwnProperty('items')\n \"\n >\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-label>{{\n $any(filterGroup).get(\"selectFilter\")?.value?.title ||\n \"Selecione\"\n }}</mat-label>\n <mat-select\n placeholder=\"Selecione...\"\n formControlName=\"selectItem\"\n multiple\n >\n <mat-option\n *ngFor=\"\n let item of $any(filterGroup).get('selectFilter')?.value\n .items\n \"\n [value]=\"item\"\n >\n {{ item.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n\n <!-- DATE FILTER -->\n <div\n class=\"min-w-[340px] flex-auto\"\n *ngIf=\"\n $any(filterGroup).get('selectFilter')?.value?.arrange ===\n 'filterByDate'\n \"\n >\n <div\n class=\"flex flex-col items-stretch gap-3 sm:flex-row sm:items-center\"\n >\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Inicial</span>\n </mat-label>\n <input\n type=\"text\"\n matInput\n (keydown.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n formControlName=\"initialDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"flex-1\">\n <mat-label class=\"flex items-center gap-2\">\n <i class=\"fa fa-calendar text-gray-400\"></i>\n <span>Data Final</span>\n </mat-label>\n <input\n type=\"text\"\n (keydown.enter)=\"search($event)\"\n (blur)=\"onDateFilterChange()\"\n matInput\n formControlName=\"finalDate\"\n [dropSpecialCharacters]=\"false\"\n mask=\"d0/M0/0000\"\n placeholder=\"DD/MM/AAAA\"\n maxlength=\"10\"\n />\n </mat-form-field>\n </div>\n </div>\n\n <!-- REMOVE FILTER BUTTON -->\n <div *ngIf=\"filtersForm.length > 1\" class=\"ml-auto flex-shrink-0\">\n <button\n (click)=\"removeFilter(i)\"\n class=\"flex h-10 w-10 items-center justify-center rounded-full transition-colors duration-300 hover:bg-red-100\"\n matTooltip=\"Remover filtro\"\n >\n <i class=\"fa fa-trash text-red-500 hover:text-red-600\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- PANEL FOOTER: Add Filter & Actions -->\n <div\n class=\"-mb-2 flex flex-col items-center justify-between gap-4 border-t border-gray-200 pt-4 sm:flex-row\"\n >\n <!-- Add Filter Button -->\n <div *ngIf=\"dropdownItems.length > 0\">\n <button\n (click)=\"addFilter()\"\n class=\"transform rounded-full border-2 border-blue-300 bg-blue-50 px-6 py-2 text-sm font-medium text-blue-600 transition-all duration-300 hover:-translate-y-0.5 hover:border-blue-400 hover:bg-blue-100 hover:shadow-md\"\n matTooltip=\"Adicionar novo filtro\"\n >\n <i class=\"fa fa-plus mr-2\"></i>\n Adicionar Filtro\n </button>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"flex flex-wrap gap-3\">\n <button\n (click)=\"search()\"\n type=\"button\"\n class=\"flex items-center gap-2 rounded-lg bg-green-600 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700\"\n matTooltip=\"Aplicar filtros\"\n >\n <i class=\"fa fa-search\"></i>\n Aplicar\n </button>\n\n <button\n (click)=\"resetFilter()\"\n class=\"flex items-center gap-2 rounded-lg bg-red-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-red-600\"\n matTooltip=\"Limpar filtros\"\n >\n <i class=\"fas fa-redo-alt\"></i>\n Resetar\n </button>\n\n <button\n *ngIf=\"data.download !== false && downloadTable\"\n class=\"flex items-center gap-2 rounded-lg bg-orange-500 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-orange-600\"\n matTooltipPosition=\"above\"\n matTooltip=\"Exportar Tabela\"\n [disabled]=\"\n this.dataSource && this.dataSource.filteredData.length <= 0\n \"\n (click)=\"handleDownload()\"\n >\n <i class=\"fa fa-download\"></i>\n Exportar\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"flex flex-col\">\n <div\n class=\"mx-auto flex flex-col\"\n *ngIf=\"data.tabs && data.tabs.tabsData && data.tabs.tabsData.length > 0\"\n >\n <!-- Calcular quantos grupos de 6 tabs existem -->\n <ng-container\n *ngFor=\"\n let groupIndex of getTabGroups(data.tabs.tabsData);\n let i = index\n \"\n >\n <div class=\"mx-auto flex flex-row\">\n <ng-container\n *ngFor=\"\n let tab of getTabGroup(data.tabs.tabsData, groupIndex);\n let j = index\n \"\n >\n <button\n class=\"border-2 border-gray-300 bg-gray-200 px-4 py-2 font-medium transition hover:brightness-95\"\n [ngClass]=\"\n isTabSelected(getRealTabIndex(i, j))\n ? 'border-b-0 brightness-110'\n : ''\n \"\n (click)=\"onTableSelected(i, j)\"\n >\n {{ tab.label }}\n <span\n *ngIf=\"tab.counter !== undefined\"\n class=\"ml-2 text-xs font-bold\"\n [ngClass]=\"tab.counterClass\"\n >\n {{ tab.counter }}\n </span>\n </button>\n </ng-container>\n </div>\n </ng-container>\n </div>\n <div class=\"mat-elevation-z8 w-full overflow-x-auto rounded-xl\">\n <table\n mat-table\n [dataSource]=\"dataSource\"\n matSort\n #sort=\"matSort\"\n matSortActive=\"createdAt\"\n matSortDirection=\"desc\"\n >\n <ng-container\n *ngFor=\"let col of data.displayedColumns\"\n matColumnDef=\"{{ col.property }}\"\n >\n <ng-container *matHeaderCellDef>\n <!-- IF THE COLUMN IS NOT SORTABLE, THEN DON'T SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"!col.isSortable || data.pagination === true\"\n mat-header-cell\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <!-- IF THE COLUMN IS SORTABLE, THEN SHOW THE SORT BUTTONS -->\n <th\n *ngIf=\"col.isSortable && data.pagination === false\"\n mat-header-cell\n mat-sort-header\n [ngClass]=\"\n (data.color?.bg ? ' ' + $any(data.color).bg : '') +\n (data.color?.text ? ' ' + $any(data.color).text : '')\n \"\n >\n {{ col.title }}\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n (click)=\"col.method ? col.method(row) : null\"\n (mouseenter)=\"onCellMouseEnter($event, row, col)\"\n (mouseleave)=\"onCellMouseLeave()\"\n (mousemove)=\"onCellMouseMove($event)\"\n >\n <!-- CHECK IF THE COLUMN MUST BE DISPLAYED -->\n <span *ngIf=\"!col.image && !col.iconClass && !col.method\">\n <ng-container>\n <span\n *ngIf=\"\n col.charLimit &&\n row[col.property] &&\n row[col.property].length > col.charLimit;\n else withinLimit\n \"\n >\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row) }}\n </span>\n </span>\n </ng-container>\n <ng-template #withinLimit>\n <a\n *ngIf=\"col.hasLink === true\"\n [href]=\"row[col.property]\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <a\n *ngIf=\"col.hasLink && isString(col.hasLink)\"\n [href]=\"col.hasLink\"\n target=\"_blank\"\n >\n {{ getDisplayValue(col, row, true) }}\n </a>\n <span\n *ngIf=\"col.hasLink !== true && !isString(col.hasLink)\"\n >\n {{ getDisplayValue(col, row, true) }}\n </span>\n </ng-template>\n </span>\n <!------------------- IMAGE ------------------>\n <img\n *ngIf=\"\n col.image && col.image.path && !col.iconClass && !col.method\n \"\n [src]=\"col.image.path + '/' + row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <img\n *ngIf=\"\n col.image && col.image.url && !col.iconClass && !col.method\n \"\n [src]=\"row[col.property]\"\n [ngClass]=\"col.image.class\"\n alt=\"Imagem\"\n />\n <ng-container *ngIf=\"col.iconClass\">\n <button\n *ngFor=\"let iconClass of col.iconClass\"\n (click)=\"\n iconClass.buttonMethod\n ? iconClass.buttonMethod(row, $event)\n : $event.stopPropagation()\n \"\n >\n <span\n [ngClass]=\"iconClass.class\"\n *ngIf=\"\n iconClass.condition === undefined ||\n (iconClass.condition !== undefined &&\n $any(iconClass.condition)(row))\n \"\n >{{ iconClass.text }}</span\n >\n </button>\n </ng-container>\n </td>\n </ng-container>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"columnProperties\"></tr>\n <tr\n [ngClass]=\"{\n 'example-element-row': data.isNotClickable === true,\n 'example-element-row cursor-pointer': !data.isNotClickable\n }\"\n mat-row\n *matRowDef=\"let row; columns: columnProperties\"\n (click)=\"goToDetails(row)\"\n ></tr>\n\n <!-- ROW SHOWN WHEN THERE IS NO MATCHING DATA. -->\n <tr class=\"mat-row\" *matNoDataRow>\n <td *ngIf=\"!isLoading\" class=\"mat-cell p-4\" colspan=\"4\">\n Nenhum resultado encontrado para a busca\n </td>\n </tr>\n </table>\n\n <div class=\"flex justify-center\" *ngIf=\"isLoading\">\n <mat-spinner></mat-spinner>\n </div>\n\n <div class=\"paginator-container\">\n <mat-paginator\n #paginator\n [pageSizeOptions]=\"[25, 50, 100]\"\n [pageSize]=\"pageSize\"\n [length]=\"totalItems\"\n showFirstLastButtons\n aria-label=\"Select page of periodic elements\"\n (page)=\"onPageChange($event)\"\n [ngClass]=\"{\n 'hide-length':\n ['filter', 'filterByDate', 'equals'].includes(\n this.currentArrange\n ) || this.data.filterFn,\n 'hide-next-button': !hasNextPage && data.pagination === true,\n 'hide-last-button':\n (!hasNextPage && data.pagination === true) || this.data.filterFn\n }\"\n >\n </mat-paginator>\n <div\n *ngIf=\"\n !isLoading &&\n dataSource?.data &&\n dataSource.data.length > 0 &&\n data?.filterFn\n \"\n class=\"page-number-display\"\n >\n {{ currentPageNumber }}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- TOOLTIP PERSONALIZADO -->\n <div\n *ngIf=\"showTooltip\"\n class=\"fixed z-50 max-w-md break-words rounded-lg bg-gray-800 px-3 py-2 text-sm text-white shadow-lg\"\n [style.left.px]=\"tooltipPosition.x\"\n [style.top.px]=\"tooltipPosition.y\"\n [style.pointer-events]=\"'none'\"\n >\n {{ tooltipContent }}\n </div>\n</div>\n", styles: ["::ng-deep .hide-length .mat-mdc-paginator-range-label{display:none}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-next.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base{visibility:hidden}::ng-deep .hide-next-button .mat-mdc-tooltip-trigger.mat-mdc-paginator-navigation-last.mdc-icon-button.mat-mdc-icon-button.mat-unthemed.mat-mdc-button-base.ng-star-inserted{visibility:hidden}::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field.ng-tns-c162-1.mdc-text-field--filled{width:25dvw}::ng-deep .custom-filter .mat-mdc-text-field-wrapper{width:20dvw;max-width:300px}\n"] }]
|
|
2209
2216
|
}], ctorParameters: function () { return [{ type: i1$1.Router }, { type: TableService }, { type: i1.AngularFirestore }]; }, propDecorators: { data: [{
|
|
2210
2217
|
type: Input
|
|
2211
2218
|
}], downloadTable: [{
|