ng-components-tsi 0.0.70 → 0.0.72
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.
|
@@ -4160,7 +4160,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
4160
4160
|
* @Input withCheckbox - Mostrar checkboxes de selección
|
|
4161
4161
|
* @Input lazyLoad - Activa carga diferida de hijos (emite expandEvent)
|
|
4162
4162
|
* @Input indentSize - Píxeles de indentación por nivel (default: 20)
|
|
4163
|
-
* @Input maxLevels - Límite de niveles expandibles (0 = sin límite)
|
|
4163
|
+
* @Input maxLevels - Límite de niveles expandibles (0 = sin límite). A partir del
|
|
4164
|
+
* último nivel permitido no se muestra el chevron de expandir,
|
|
4165
|
+
* aunque `lazyLoad` esté activo.
|
|
4166
|
+
* @Input hasChildrenKey - Campo del dato origen que indica si el nodo tiene hijos
|
|
4167
|
+
* (ej. 'tieneHijos'). Con `lazyLoad` activo, sin este campo se
|
|
4168
|
+
* asume que toda fila puede tener hijos hasta que se consulten;
|
|
4169
|
+
* definiéndolo, las filas hoja no muestran chevron.
|
|
4164
4170
|
* @Input customLevels - Niveles que renderizan su bloque de datos con `#levelTemplate`
|
|
4165
4171
|
* en vez de la grilla de `columns` (permite que cada nivel tenga
|
|
4166
4172
|
* su propia organización/estructura visual)
|
|
@@ -4193,6 +4199,12 @@ class TableUltimatePivotComponent {
|
|
|
4193
4199
|
lazyLoad = input(false);
|
|
4194
4200
|
indentSize = input(20);
|
|
4195
4201
|
maxLevels = input(0);
|
|
4202
|
+
/** Nombre del campo del dato origen que indica explícitamente si el nodo tiene hijos
|
|
4203
|
+
* (ej. 'tieneHijos'). Útil con `lazyLoad`: sin esto, todo nodo se asume expandible
|
|
4204
|
+
* porque no se conocen sus hijos hasta pedirlos; si el backend ya informa qué filas
|
|
4205
|
+
* son hoja, declarar esta propiedad evita mostrar el chevron (y disparar el lazy load)
|
|
4206
|
+
* en esas filas. Si no se define, se mantiene el comportamiento por defecto. */
|
|
4207
|
+
hasChildrenKey = input(null);
|
|
4196
4208
|
/** Niveles (0-based) cuyo bloque de datos se delega al `#levelTemplate` proyectado,
|
|
4197
4209
|
* en lugar de la grilla estándar de `columns`. Ej: [1, 2].
|
|
4198
4210
|
* Las filas de estos niveles no muestran el chevron de expandir propio: si el nivel
|
|
@@ -4221,7 +4233,7 @@ class TableUltimatePivotComponent {
|
|
|
4221
4233
|
scrollTop = signal(0);
|
|
4222
4234
|
containerHeight = signal(0);
|
|
4223
4235
|
expandedIds = signal(new Set());
|
|
4224
|
-
loadingIds =
|
|
4236
|
+
loadingIds = model(new Set());
|
|
4225
4237
|
// ── Sort ──────────────────────────────────────────────────────────────────────
|
|
4226
4238
|
sortField = signal(null);
|
|
4227
4239
|
sortDir = signal('none');
|
|
@@ -4279,17 +4291,21 @@ class TableUltimatePivotComponent {
|
|
|
4279
4291
|
const ck = this.childrenKey();
|
|
4280
4292
|
const maxL = this.maxLevels();
|
|
4281
4293
|
const lazy = this.lazyLoad();
|
|
4294
|
+
const hcKey = this.hasChildrenKey();
|
|
4295
|
+
// Nivel a partir del cual ya no se permite seguir desplegando (0 = sin límite)
|
|
4296
|
+
const withinMaxLevels = maxL === 0 || level < maxL - 1;
|
|
4282
4297
|
for (const node of nodes) {
|
|
4283
4298
|
const id = node.idListTsi;
|
|
4284
4299
|
const children = node[ck];
|
|
4285
|
-
const
|
|
4300
|
+
const hasOwnChildren = Array.isArray(children) && children.length > 0;
|
|
4301
|
+
// Si el dato trae un indicador explícito de "tiene hijos", manda sobre la
|
|
4302
|
+
// suposición de lazyLoad (así una fila hoja no muestra chevron innecesario).
|
|
4303
|
+
const hasChildren = withinMaxLevels && (hcKey && node[hcKey] !== undefined ? !!node[hcKey] : (hasOwnChildren || lazy));
|
|
4286
4304
|
const isExpanded = expanded.has(id);
|
|
4287
4305
|
const isLoading = loading.has(id);
|
|
4288
4306
|
result.push({ ...node, _level: level, _hasChildren: hasChildren, _isExpanded: isExpanded, _isLoading: isLoading });
|
|
4289
|
-
if (isExpanded && !isLoading &&
|
|
4290
|
-
|
|
4291
|
-
result.push(...this.flattenVisible(children, level + 1, expanded, loading));
|
|
4292
|
-
}
|
|
4307
|
+
if (withinMaxLevels && isExpanded && !isLoading && hasOwnChildren) {
|
|
4308
|
+
result.push(...this.flattenVisible(children, level + 1, expanded, loading));
|
|
4293
4309
|
}
|
|
4294
4310
|
}
|
|
4295
4311
|
return result;
|
|
@@ -4588,13 +4604,13 @@ class TableUltimatePivotComponent {
|
|
|
4588
4604
|
return fields.reduce((acc, f) => acc + (obj[f] ?? ''), '');
|
|
4589
4605
|
}
|
|
4590
4606
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TableUltimatePivotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4591
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TableUltimatePivotComponent, isStandalone: true, selector: "app-table-ultimate-pivot", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, childrenKey: { classPropertyName: "childrenKey", publicName: "childrenKey", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, buffer: { classPropertyName: "buffer", publicName: "buffer", isSignal: true, isRequired: false, transformFunction: null }, altoContainer: { classPropertyName: "altoContainer", publicName: "altoContainer", isSignal: true, isRequired: false, transformFunction: null }, altoContenedor: { classPropertyName: "altoContenedor", publicName: "altoContenedor", isSignal: true, isRequired: false, transformFunction: null }, minAlto: { classPropertyName: "minAlto", publicName: "minAlto", isSignal: true, isRequired: false, transformFunction: null }, identifier: { classPropertyName: "identifier", publicName: "identifier", isSignal: true, isRequired: false, transformFunction: null }, withFiltro: { classPropertyName: "withFiltro", publicName: "withFiltro", isSignal: true, isRequired: false, transformFunction: null }, withCheckbox: { classPropertyName: "withCheckbox", publicName: "withCheckbox", isSignal: true, isRequired: false, transformFunction: null }, withHeight: { classPropertyName: "withHeight", publicName: "withHeight", isSignal: true, isRequired: false, transformFunction: null }, lazyLoad: { classPropertyName: "lazyLoad", publicName: "lazyLoad", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, maxLevels: { classPropertyName: "maxLevels", publicName: "maxLevels", isSignal: true, isRequired: false, transformFunction: null }, customLevels: { classPropertyName: "customLevels", publicName: "customLevels", isSignal: true, isRequired: false, transformFunction: null }, rendered: { classPropertyName: "rendered", publicName: "rendered", isSignal: true, isRequired: false, transformFunction: null }, rowClassFn: { classPropertyName: "rowClassFn", publicName: "rowClassFn", isSignal: true, isRequired: false, transformFunction: null }, expandOn: { classPropertyName: "expandOn", publicName: "expandOn", isSignal: true, isRequired: false, transformFunction: null }, variante: { classPropertyName: "variante", publicName: "variante", isSignal: true, isRequired: false, transformFunction: null }, withCellSelect: { classPropertyName: "withCellSelect", publicName: "withCellSelect", isSignal: true, isRequired: false, transformFunction: null }, selectedRow: { classPropertyName: "selectedRow", publicName: "selectedRow", isSignal: true, isRequired: false, transformFunction: null }, selectItems: { classPropertyName: "selectItems", publicName: "selectItems", isSignal: true, isRequired: false, transformFunction: null }, selectedCell: { classPropertyName: "selectedCell", publicName: "selectedCell", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowEvent: "rowEvent", cellEvent: "cellEvent", expandEvent: "expandEvent", selectedRow: "selectedRowChange", selectItems: "selectItemsChange", selectedCell: "selectedCellChange" }, host: { properties: { "class.ll-variant--modern": "variante() === \"modern\"" } }, queries: [{ propertyName: "customActions", first: true, predicate: ["customActions"], descendants: true, isSignal: true }, { propertyName: "contentFilter", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "levelTemplate", first: true, predicate: ["levelTemplate"], descendants: true, isSignal: true }, { propertyName: "columnDefs", predicate: TsiColumnDefDirective, isSignal: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (withFiltro()) {\n<div class=\"ll-search-bar\">\n <div class=\"ll-search-bar__left\">\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\n </div>\n <div class=\"ll-search-bar__right\">\n <div class=\"ll-search-group\">\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\n <div class=\"ll-search-input-wrap\">\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\"\n [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn btn-dark boton-buscar fs-7\">\n <i class=\"fas fa-cog\"></i>\n </button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Filtros</div>\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\n (change)=\"toggleFiltros($event)\" id=\"filter_pv_todos\" />\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\" for=\"filter_pv_todos\">Todos</label>\n </div>\n @for (col of columns(); track col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'filter_pv_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\n for=\"{{ 'filter_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </div>\n </div>\n </div>\n</div>\n}\n\n<div #scrollContainer class=\"ll-scroll-container\"\n [style.height]=\"withHeight() ? heightStyle() : ''\"\n [style.max-height]=\"heightStyle()\"\n (scroll)=\"onScroll($event)\">\n <table class=\"ll-table\">\n\n <!-- \u2500\u2500 HEADER sticky \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <thead class=\"ll-thead\">\n <tr>\n <!-- Columna de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <th class=\"ll-pivot-th-expand\"></th>\n }\n\n @if (withCheckbox()) {\n <th class=\"cw-20\">\n <label>\n <input type=\"checkbox\" name=\"chk_pv_all\" id=\"chk_pv_all\"\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\n </label>\n </th>\n }\n\n @if (customActions()) {\n <th class=\"cw-40\">\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn p-0 d-flex mx-auto border-0 icon-table\"><i class=\"fas fa-cog\"></i></button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Columnas</div>\n @for (col of columns(); track col.caption) {\n @if (col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'switch_pv_' + col.caption }}\" [(ngModel)]=\"visibilidadColumn()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\n for=\"{{ 'switch_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </th>\n }\n\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\n <span class=\"ll-th-content\">\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\n @if (sortField() === col.fieldname) {\n <i class=\"ms-1\"\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6' : 'fas fa-angle-down fs-6'\"></i>\n } @else {\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n\n <!-- \u2500\u2500 BODY virtual \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <tbody>\n <!-- Spacer superior -->\n @if (paddingTop() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n\n <!-- Filas visibles -->\n @for (row of visibleRows(); track row.idListTsi) {\n @let idList = row.idListTsi;\n <tr class=\"ll-row\"\n [ngClass]=\"getLevelClass(row._level)\"\n [class.ll-row--selected]=\"isSelected(row, idList)\"\n (click)=\"selectRow(row, idList)\"\n (dblclick)=\"onDoubleClick(row)\"\n (contextmenu)=\"onRightClick($event, row)\">\n\n <!-- Celda dedicada de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <td class=\"ll-pivot-expand-cell\" [style.padding-left]=\"getIndentPx(row._level)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner\" role=\"status\"></span>\n } @else if (row._hasChildren && !customLevels().includes(row._level)) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf\"></span>\n }\n </td>\n }\n\n @if (withCheckbox()) {\n <td class=\"text-center b-table\">\n <label>\n <input type=\"checkbox\" [name]=\"'chk_pv_' + idList\" [id]=\"'chk_pv_' + idList\"\n animatedCheckbox [checked]=\"isItemSelected(idList)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toogleItem(idList, $event)\">\n </label>\n </td>\n }\n\n @if (customActions()) {\n <td class=\"text-center\">\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row, level: row._level }\"></ng-container>\n </td>\n }\n\n @if (customLevels().includes(row._level) && levelTemplate()) {\n <td [attr.colspan]=\"dataColSpan()\">\n <ng-container *ngTemplateOutlet=\"levelTemplate(); context: { $implicit: row, level: row._level, columns: columns() }\">\n </ng-container>\n </td>\n } @else {\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n @if (columnDefMap().has(col.fieldname)) {\n <td>\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else if (col.template) {\n <td>\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else {\n @switch (col.tipo) {\n\n @case ('cell-render') {\n @let resolverItem = resolveCell(col.fieldname, row);\n @if (resolverItem) {\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\n @if (resolverItem.icon) {\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\n } @else if (resolverItem.class) {\n <span [ngClass]=\"resolverItem.class\">{{ resolverItem.text }}</span>\n } @else {\n {{ resolverItem.text }}\n }\n </td>\n }\n }\n\n @default {\n @if (col.fieldname === expandOn()) {\n <!-- Celda con \u00EDcono de expansi\u00F3n incrustado -->\n <td class=\"ll-pivot-expand-inline {{ getPosition(col) }}\"\n [class.cursor-pointer]=\"row._hasChildren\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [style.padding-left]=\"getIndentPx(row._level)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n (click)=\"row._hasChildren ? toggleExpand($event, row) : (withCellSelect() ? onCellClick($event, row, col.fieldname) : null)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner me-1\" role=\"status\"></span>\n } @else if (row._hasChildren) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer me-1\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf me-1\"></span>\n }\n <span [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"></span>\n </td>\n } @else {\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [class.ll-cell--selectable]=\"withCellSelect()\"\n class=\"{{ getPosition(col) }}\"\n (click)=\"withCellSelect() ? onCellClick($event, row, col.fieldname) : null\">\n </td>\n }\n }\n\n }\n }\n }\n }\n }\n\n </tr>\n }\n\n <!-- Estado vac\u00EDo -->\n @if (rowFilter().length === 0) {\n <tr>\n <td [attr.colspan]=\"colSpan()\"\n class=\"ll-empty\">\n Sin datos\n </td>\n </tr>\n }\n\n <!-- Spacer inferior -->\n @if (paddingBottom() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n </tbody>\n\n </table>\n</div>\n\n", styles: [":host(.ll-variant--modern) .ll-search-bar .ll-search-label{display:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control{width:250px!important;min-width:250px!important;border-radius:5px!important;border:1px solid rgba(0,0,0,.12);background-color:#fff;font-size:12px;padding-left:34px;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:10px center;background-size:14px 14px;transition:border-color .15s ease,box-shadow .15s ease;height:30px!important;font-weight:400}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control::placeholder{color:#9ca3af}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control:focus{border-color:#1e293b;box-shadow:0 0 0 3px #1e293b14;outline:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar{border-radius:5px;height:30px!important;width:30px!important;min-width:30px!important;background-color:#fff!important;border:1px solid rgba(0,0,0,.12)!important;color:#546074!important}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar:hover{background-color:#f3f4f6!important;border-color:#0003!important}:host(.ll-variant--modern) .ll-scroll-container{border:1px solid rgba(0,0,0,.08);box-shadow:0 1px 3px #0000000f,0 4px 16px #0000000a;background:#fff}:host(.ll-variant--modern) .ll-table{border-collapse:separate;border-spacing:0;background:#fff}:host(.ll-variant--modern) .ll-thead tr th{background:#f1f1f1;color:#333!important;border:none;border-bottom:1px solid rgba(0,0,0,.1);border-top:1px solid rgba(0,0,0,.1);box-shadow:none;font-weight:700}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap}.ll-search-bar__left{display:flex;align-items:center;gap:6px;flex:1;flex-wrap:wrap}.ll-search-bar__right{display:flex;align-items:center;gap:4px;flex-shrink:0}.ll-search-bar__right .ll-search-group{display:flex;align-items:center;gap:4px}.ll-search-bar__right .ll-search-group .ll-search-label{white-space:nowrap}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{display:flex;align-items:center}@media (max-width: 576px){.ll-search-bar__right{width:100%;justify-content:space-between}.ll-search-bar__right .ll-search-group{flex-direction:column;align-items:flex-start;width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap input{flex:1}}.ll-scroll-container{width:100%;overflow-y:auto;overflow-x:auto;display:block;position:relative;border:var(--border-table-header);border-radius:0;overflow-anchor:none}.ll-scroll-container::-webkit-scrollbar{width:5px;height:5px}.ll-scroll-container::-webkit-scrollbar-track{background:transparent}.ll-scroll-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:10px}.ll-scroll-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3}.ll-thead tr th{font-size:11px;font-weight:600;text-align:start;padding:12px 10px;max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.02em;color:var(--text-color);background-color:var(--background-header-table);border:none;border-bottom:var(--border-table-header);box-shadow:none}.ll-th-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.ll-th-sortable:hover{background-color:var(--bs-table-header-hover-bg)!important}.ll-th-content{display:flex;align-items:center;gap:4px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.3}.ll-pivot-th-expand{width:32px;min-width:32px;max-width:32px}.ll-row{height:34px;cursor:pointer;background-color:#fff;transition:background-color .12s ease}.ll-row:hover{background-color:#eff6ff!important}.ll-row:hover td:first-child{border-left-color:#93c5fd!important}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--selected td:first-child{border-left-color:transparent!important}.ll-row td{font-size:11px;font-weight:400;color:#202433!important;vertical-align:middle;padding:0 10px;border:none;border-bottom:1px solid #f1f5f9;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ll-row--level-0{background-color:#f0f0f0}.ll-row--level-0 td{font-weight:700;color:#1e3a5f;border-bottom:2px solid #e4e4e4}.ll-row--level-0 td:first-child{border-left:4px solid #2563eb!important}.ll-row--level-1 td{font-weight:600;color:#1e3a5f}.ll-row--level-1 td:first-child{border-left:3px solid #38bdf8!important}.ll-row--level-2 td:first-child{border-left:3px solid #34d399!important}.ll-row--level-3 td:first-child{border-left:3px solid #a78bfa!important}.ll-cell--selectable{cursor:cell;transition:background-color .1s}.ll-cell--selectable:hover:not(.ll-cell--selected){background-color:#2563eb0f!important}.ll-cell--selected{background-color:#2563eb21!important;box-shadow:inset 0 0 0 2px #2563eb;color:#1e3a5f!important}.ll-pivot-expand-inline{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ll-pivot-expand-inline .ll-pivot-toggle,.ll-pivot-expand-inline .ll-pivot-leaf,.ll-pivot-expand-inline .ll-pivot-spinner{vertical-align:middle}.ll-pivot-expand-inline span:last-child{vertical-align:middle}.ll-pivot-expand-inline.cursor-pointer:hover span:last-child{text-decoration:underline;text-underline-offset:2px}.ll-pivot-expand-cell{width:32px;min-width:32px;text-align:left;vertical-align:middle}.ll-pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;transition:background-color .15s,border-color .15s;border:1px solid transparent}.ll-pivot-toggle:hover{background-color:#dbeafe;border-color:#93c5fd}.ll-pivot-toggle i{font-size:9px;color:#3b82f6}.ll-pivot-leaf{display:inline-block;width:10px;height:2px;border-radius:2px;background-color:#cbd5e1;vertical-align:middle;margin-left:5px}.ll-pivot-spinner{width:12px;height:12px;border-width:2px;vertical-align:middle}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:32px 16px;color:#94a3b8;font-size:12px;font-style:italic;letter-spacing:.02em}@media (max-width: 1600px){.ll-thead tr th,.ll-row td{font-size:10px}}.popover-menu-column{position:absolute;top:100%;left:0;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.4rem .75rem;border-bottom:1px solid #7e7e7e;position:sticky;top:0;text-align:center}.popover-menu-column::-webkit-scrollbar{width:5px}.popover-menu-column::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.popover-menu-filter{position:absolute;top:85%;right:0;background-color:#fff;border:1px solid #ddd;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto;z-index:2}.popover-menu-filter::-webkit-scrollbar{width:5px}.popover-menu-filter::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-filter::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.cw-25{min-width:40px}.icon-table{color:#2e2e2ed8;font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DropdownCdkComponent, selector: "app-dropdown-cdk", inputs: ["inline", "altoContainer"] }, { kind: "directive", type: AnimatedCheckboxDirective, selector: "input[type=checkbox][animatedCheckbox]", inputs: ["cbClass"] }], animations: [fadeInOut, dropdownAnimation] });
|
|
4607
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TableUltimatePivotComponent, isStandalone: true, selector: "app-table-ultimate-pivot", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, childrenKey: { classPropertyName: "childrenKey", publicName: "childrenKey", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, buffer: { classPropertyName: "buffer", publicName: "buffer", isSignal: true, isRequired: false, transformFunction: null }, altoContainer: { classPropertyName: "altoContainer", publicName: "altoContainer", isSignal: true, isRequired: false, transformFunction: null }, altoContenedor: { classPropertyName: "altoContenedor", publicName: "altoContenedor", isSignal: true, isRequired: false, transformFunction: null }, minAlto: { classPropertyName: "minAlto", publicName: "minAlto", isSignal: true, isRequired: false, transformFunction: null }, identifier: { classPropertyName: "identifier", publicName: "identifier", isSignal: true, isRequired: false, transformFunction: null }, withFiltro: { classPropertyName: "withFiltro", publicName: "withFiltro", isSignal: true, isRequired: false, transformFunction: null }, withCheckbox: { classPropertyName: "withCheckbox", publicName: "withCheckbox", isSignal: true, isRequired: false, transformFunction: null }, withHeight: { classPropertyName: "withHeight", publicName: "withHeight", isSignal: true, isRequired: false, transformFunction: null }, lazyLoad: { classPropertyName: "lazyLoad", publicName: "lazyLoad", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, maxLevels: { classPropertyName: "maxLevels", publicName: "maxLevels", isSignal: true, isRequired: false, transformFunction: null }, hasChildrenKey: { classPropertyName: "hasChildrenKey", publicName: "hasChildrenKey", isSignal: true, isRequired: false, transformFunction: null }, customLevels: { classPropertyName: "customLevels", publicName: "customLevels", isSignal: true, isRequired: false, transformFunction: null }, rendered: { classPropertyName: "rendered", publicName: "rendered", isSignal: true, isRequired: false, transformFunction: null }, rowClassFn: { classPropertyName: "rowClassFn", publicName: "rowClassFn", isSignal: true, isRequired: false, transformFunction: null }, expandOn: { classPropertyName: "expandOn", publicName: "expandOn", isSignal: true, isRequired: false, transformFunction: null }, variante: { classPropertyName: "variante", publicName: "variante", isSignal: true, isRequired: false, transformFunction: null }, withCellSelect: { classPropertyName: "withCellSelect", publicName: "withCellSelect", isSignal: true, isRequired: false, transformFunction: null }, selectedRow: { classPropertyName: "selectedRow", publicName: "selectedRow", isSignal: true, isRequired: false, transformFunction: null }, selectItems: { classPropertyName: "selectItems", publicName: "selectItems", isSignal: true, isRequired: false, transformFunction: null }, selectedCell: { classPropertyName: "selectedCell", publicName: "selectedCell", isSignal: true, isRequired: false, transformFunction: null }, loadingIds: { classPropertyName: "loadingIds", publicName: "loadingIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowEvent: "rowEvent", cellEvent: "cellEvent", expandEvent: "expandEvent", selectedRow: "selectedRowChange", selectItems: "selectItemsChange", selectedCell: "selectedCellChange", loadingIds: "loadingIdsChange" }, host: { properties: { "class.ll-variant--modern": "variante() === \"modern\"" } }, queries: [{ propertyName: "customActions", first: true, predicate: ["customActions"], descendants: true, isSignal: true }, { propertyName: "contentFilter", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "levelTemplate", first: true, predicate: ["levelTemplate"], descendants: true, isSignal: true }, { propertyName: "columnDefs", predicate: TsiColumnDefDirective, isSignal: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (withFiltro()) {\n<div class=\"ll-search-bar\">\n <div class=\"ll-search-bar__left\">\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\n </div>\n <div class=\"ll-search-bar__right\">\n <div class=\"ll-search-group\">\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\n <div class=\"ll-search-input-wrap\">\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\"\n [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn btn-dark boton-buscar fs-7\">\n <i class=\"fas fa-cog\"></i>\n </button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Filtros</div>\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\n (change)=\"toggleFiltros($event)\" id=\"filter_pv_todos\" />\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\" for=\"filter_pv_todos\">Todos</label>\n </div>\n @for (col of columns(); track col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'filter_pv_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\n for=\"{{ 'filter_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </div>\n </div>\n </div>\n</div>\n}\n\n<div #scrollContainer class=\"ll-scroll-container\"\n [style.height]=\"withHeight() ? heightStyle() : ''\"\n [style.max-height]=\"heightStyle()\"\n (scroll)=\"onScroll($event)\">\n <table class=\"ll-table\">\n\n <!-- \u2500\u2500 HEADER sticky \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <thead class=\"ll-thead\">\n <tr>\n <!-- Columna de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <th class=\"ll-pivot-th-expand\"></th>\n }\n\n @if (withCheckbox()) {\n <th class=\"cw-20\">\n <label>\n <input type=\"checkbox\" name=\"chk_pv_all\" id=\"chk_pv_all\"\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\n </label>\n </th>\n }\n\n @if (customActions()) {\n <th class=\"cw-40\">\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn p-0 d-flex mx-auto border-0 icon-table\"><i class=\"fas fa-cog\"></i></button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Columnas</div>\n @for (col of columns(); track col.caption) {\n @if (col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'switch_pv_' + col.caption }}\" [(ngModel)]=\"visibilidadColumn()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\n for=\"{{ 'switch_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </th>\n }\n\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\n <span class=\"ll-th-content\">\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\n @if (sortField() === col.fieldname) {\n <i class=\"ms-1\"\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6' : 'fas fa-angle-down fs-6'\"></i>\n } @else {\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n\n <!-- \u2500\u2500 BODY virtual \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <tbody>\n <!-- Spacer superior -->\n @if (paddingTop() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n\n <!-- Filas visibles -->\n @for (row of visibleRows(); track row.idListTsi) {\n @let idList = row.idListTsi;\n <tr class=\"ll-row\"\n [ngClass]=\"getLevelClass(row._level)\"\n [class.ll-row--selected]=\"isSelected(row, idList)\"\n (click)=\"selectRow(row, idList)\"\n (dblclick)=\"onDoubleClick(row)\"\n (contextmenu)=\"onRightClick($event, row)\">\n\n <!-- Celda dedicada de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <td class=\"ll-pivot-expand-cell\" [style.padding-left]=\"getIndentPx(row._level)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner\" role=\"status\"></span>\n } @else if (row._hasChildren && !customLevels().includes(row._level)) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf\"></span>\n }\n </td>\n }\n\n @if (withCheckbox()) {\n <td class=\"text-center b-table\">\n <label>\n <input type=\"checkbox\" [name]=\"'chk_pv_' + idList\" [id]=\"'chk_pv_' + idList\"\n animatedCheckbox [checked]=\"isItemSelected(idList)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toogleItem(idList, $event)\">\n </label>\n </td>\n }\n\n @if (customActions()) {\n <td class=\"text-center\">\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row, level: row._level }\"></ng-container>\n </td>\n }\n\n @if (customLevels().includes(row._level) && levelTemplate()) {\n <td [attr.colspan]=\"dataColSpan()\">\n <ng-container *ngTemplateOutlet=\"levelTemplate(); context: { $implicit: row, level: row._level, columns: columns() }\">\n </ng-container>\n </td>\n } @else {\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n @if (columnDefMap().has(col.fieldname)) {\n <td>\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else if (col.template) {\n <td>\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else {\n @switch (col.tipo) {\n\n @case ('cell-render') {\n @let resolverItem = resolveCell(col.fieldname, row);\n @if (resolverItem) {\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\n @if (resolverItem.icon) {\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\n } @else if (resolverItem.class) {\n <span [ngClass]=\"resolverItem.class\">{{ resolverItem.text }}</span>\n } @else {\n {{ resolverItem.text }}\n }\n </td>\n }\n }\n\n @default {\n @if (col.fieldname === expandOn()) {\n <!-- Celda con \u00EDcono de expansi\u00F3n incrustado -->\n <td class=\"ll-pivot-expand-inline {{ getPosition(col) }}\"\n [class.cursor-pointer]=\"row._hasChildren\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [style.padding-left]=\"getIndentPx(row._level)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n (click)=\"row._hasChildren ? toggleExpand($event, row) : (withCellSelect() ? onCellClick($event, row, col.fieldname) : null)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner me-1\" role=\"status\"></span>\n } @else if (row._hasChildren) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer me-1\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf me-1\"></span>\n }\n <span [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"></span>\n </td>\n } @else {\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [class.ll-cell--selectable]=\"withCellSelect()\"\n class=\"{{ getPosition(col) }}\"\n (click)=\"withCellSelect() ? onCellClick($event, row, col.fieldname) : null\">\n </td>\n }\n }\n\n }\n }\n }\n }\n }\n\n </tr>\n }\n\n <!-- Estado vac\u00EDo -->\n @if (rowFilter().length === 0) {\n <tr>\n <td [attr.colspan]=\"colSpan()\"\n class=\"ll-empty\">\n Sin datos\n </td>\n </tr>\n }\n\n <!-- Spacer inferior -->\n @if (paddingBottom() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n </tbody>\n\n </table>\n</div>\n\n", styles: [":host(.ll-variant--modern) .ll-search-bar .ll-search-label{display:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control{width:250px!important;min-width:250px!important;border-radius:5px!important;border:1px solid rgba(0,0,0,.12);background-color:#fff;font-size:12px;padding-left:34px;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:10px center;background-size:14px 14px;transition:border-color .15s ease,box-shadow .15s ease;height:30px!important;font-weight:400}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control::placeholder{color:#9ca3af}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control:focus{border-color:#1e293b;box-shadow:0 0 0 3px #1e293b14;outline:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar{border-radius:5px;height:30px!important;width:30px!important;min-width:30px!important;background-color:#fff!important;border:1px solid rgba(0,0,0,.12)!important;color:#546074!important}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar:hover{background-color:#f3f4f6!important;border-color:#0003!important}:host(.ll-variant--modern) .ll-scroll-container{border:none!important;box-shadow:0 1px 3px #0000000f,0 4px 16px #0000000a;background:#fff}:host(.ll-variant--modern) .ll-table{border-collapse:separate;border-spacing:0;background:#fff}:host(.ll-variant--modern) .ll-thead tr th{background:#f1f1f1;color:#333!important;border:none;border-bottom:1px solid rgba(0,0,0,.1);border-top:1px solid rgba(0,0,0,.1);box-shadow:none;font-weight:700}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}:host(.ll-variant--modern) .ll-row--level-0{background-color:#fff}:host(.ll-variant--modern) .ll-row--level-1{background-color:#f5f5f5}:host(.ll-variant--modern) .ll-row--level-2{background-color:#eee}:host(.ll-variant--modern) .ll-row--level-3{background-color:#e0e0e0}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap}.ll-search-bar__left{display:flex;align-items:center;gap:6px;flex:1;flex-wrap:wrap}.ll-search-bar__right{display:flex;align-items:center;gap:4px;flex-shrink:0}.ll-search-bar__right .ll-search-group{display:flex;align-items:center;gap:4px}.ll-search-bar__right .ll-search-group .ll-search-label{white-space:nowrap}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{display:flex;align-items:center}@media (max-width: 576px){.ll-search-bar__right{width:100%;justify-content:space-between}.ll-search-bar__right .ll-search-group{flex-direction:column;align-items:flex-start;width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap input{flex:1}}.ll-scroll-container{width:100%;overflow-y:auto;overflow-x:auto;display:block;position:relative;border:var(--border-table-header);border-radius:0;overflow-anchor:none}.ll-scroll-container::-webkit-scrollbar{width:5px;height:5px}.ll-scroll-container::-webkit-scrollbar-track{background:transparent}.ll-scroll-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:10px}.ll-scroll-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3}.ll-thead tr th{font-size:11px;font-weight:600;text-align:start;padding:12px 10px;max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.02em;color:var(--text-color);background-color:var(--background-header-table);border:none;border-bottom:var(--border-table-header);box-shadow:none}.ll-th-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.ll-th-sortable:hover{background-color:var(--bs-table-header-hover-bg)!important}.ll-th-content{display:flex;align-items:center;gap:4px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.3}.ll-pivot-th-expand{width:32px;min-width:32px;max-width:32px}.ll-row{height:34px;cursor:pointer;background-color:#f0f0f0;transition:background-color .12s ease}.ll-row:hover{background-color:#eff6ff!important}.ll-row:hover td:first-child{border-left-color:#93c5fd!important}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--selected td:first-child{border-left-color:transparent!important}.ll-row td{font-size:11px;font-weight:400;color:#202433!important;vertical-align:middle;padding:0 10px;border:none;border-bottom:1px solid #f1f5f9;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;border-bottom:2px solid #e4e4e4}.ll-row--level-0{background-color:#fff}.ll-row--level-0 td{font-weight:700;color:#1e3a5f}.ll-row--level-0 td:first-child{border-left:4px solid #2563eb!important}.ll-row--level-1 td{font-weight:600;color:#1e3a5f}.ll-row--level-1 td:first-child{border-left:3px solid #38bdf8!important}.ll-row--level-2 td:first-child{border-left:3px solid #34d399!important}.ll-row--level-3 td:first-child{border-left:3px solid #a78bfa!important}.ll-cell--selectable{cursor:cell;transition:background-color .1s}.ll-cell--selectable:hover:not(.ll-cell--selected){background-color:#2563eb0f!important}.ll-cell--selected{background-color:#2563eb21!important;box-shadow:inset 0 0 0 2px #2563eb;color:#1e3a5f!important}.ll-pivot-expand-inline{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ll-pivot-expand-inline .ll-pivot-toggle,.ll-pivot-expand-inline .ll-pivot-leaf,.ll-pivot-expand-inline .ll-pivot-spinner{vertical-align:middle}.ll-pivot-expand-inline span:last-child{vertical-align:middle}.ll-pivot-expand-inline.cursor-pointer:hover span:last-child{text-decoration:underline;text-underline-offset:2px}.ll-pivot-expand-cell{width:32px;min-width:32px;text-align:left;vertical-align:middle}.ll-pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;transition:background-color .15s,border-color .15s;border:1px solid transparent}.ll-pivot-toggle:hover{background-color:#dbeafe;border-color:#93c5fd}.ll-pivot-toggle i{font-size:9px;color:#3b82f6}.ll-pivot-leaf{display:inline-block;width:10px;height:2px;border-radius:2px;background-color:#cbd5e1;vertical-align:middle;margin-left:5px}.ll-pivot-spinner{width:12px;height:12px;border-width:2px;vertical-align:middle}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:32px 16px;color:#94a3b8;font-size:12px;font-style:italic;letter-spacing:.02em}@media (max-width: 1600px){.ll-thead tr th,.ll-row td{font-size:10px}}.popover-menu-column{position:absolute;top:100%;left:0;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.4rem .75rem;border-bottom:1px solid #7e7e7e;position:sticky;top:0;text-align:center}.popover-menu-column::-webkit-scrollbar{width:5px}.popover-menu-column::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.popover-menu-filter{position:absolute;top:85%;right:0;background-color:#fff;border:1px solid #ddd;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto;z-index:2}.popover-menu-filter::-webkit-scrollbar{width:5px}.popover-menu-filter::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-filter::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.cw-25{min-width:40px}.icon-table{color:#2e2e2ed8;font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DropdownCdkComponent, selector: "app-dropdown-cdk", inputs: ["inline", "altoContainer"] }, { kind: "directive", type: AnimatedCheckboxDirective, selector: "input[type=checkbox][animatedCheckbox]", inputs: ["cbClass"] }], animations: [fadeInOut, dropdownAnimation] });
|
|
4592
4608
|
}
|
|
4593
4609
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TableUltimatePivotComponent, decorators: [{
|
|
4594
4610
|
type: Component,
|
|
4595
4611
|
args: [{ selector: 'app-table-ultimate-pivot', standalone: true, imports: [FormsModule, CommonModule, DropdownCdkComponent, AnimatedCheckboxDirective, NgTemplateOutlet], animations: [fadeInOut, dropdownAnimation], host: {
|
|
4596
4612
|
'[class.ll-variant--modern]': 'variante() === "modern"'
|
|
4597
|
-
}, template: "@if (withFiltro()) {\n<div class=\"ll-search-bar\">\n <div class=\"ll-search-bar__left\">\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\n </div>\n <div class=\"ll-search-bar__right\">\n <div class=\"ll-search-group\">\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\n <div class=\"ll-search-input-wrap\">\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\"\n [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn btn-dark boton-buscar fs-7\">\n <i class=\"fas fa-cog\"></i>\n </button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Filtros</div>\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\n (change)=\"toggleFiltros($event)\" id=\"filter_pv_todos\" />\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\" for=\"filter_pv_todos\">Todos</label>\n </div>\n @for (col of columns(); track col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'filter_pv_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\n for=\"{{ 'filter_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </div>\n </div>\n </div>\n</div>\n}\n\n<div #scrollContainer class=\"ll-scroll-container\"\n [style.height]=\"withHeight() ? heightStyle() : ''\"\n [style.max-height]=\"heightStyle()\"\n (scroll)=\"onScroll($event)\">\n <table class=\"ll-table\">\n\n <!-- \u2500\u2500 HEADER sticky \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <thead class=\"ll-thead\">\n <tr>\n <!-- Columna de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <th class=\"ll-pivot-th-expand\"></th>\n }\n\n @if (withCheckbox()) {\n <th class=\"cw-20\">\n <label>\n <input type=\"checkbox\" name=\"chk_pv_all\" id=\"chk_pv_all\"\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\n </label>\n </th>\n }\n\n @if (customActions()) {\n <th class=\"cw-40\">\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn p-0 d-flex mx-auto border-0 icon-table\"><i class=\"fas fa-cog\"></i></button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Columnas</div>\n @for (col of columns(); track col.caption) {\n @if (col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'switch_pv_' + col.caption }}\" [(ngModel)]=\"visibilidadColumn()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\n for=\"{{ 'switch_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </th>\n }\n\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\n <span class=\"ll-th-content\">\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\n @if (sortField() === col.fieldname) {\n <i class=\"ms-1\"\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6' : 'fas fa-angle-down fs-6'\"></i>\n } @else {\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n\n <!-- \u2500\u2500 BODY virtual \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <tbody>\n <!-- Spacer superior -->\n @if (paddingTop() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n\n <!-- Filas visibles -->\n @for (row of visibleRows(); track row.idListTsi) {\n @let idList = row.idListTsi;\n <tr class=\"ll-row\"\n [ngClass]=\"getLevelClass(row._level)\"\n [class.ll-row--selected]=\"isSelected(row, idList)\"\n (click)=\"selectRow(row, idList)\"\n (dblclick)=\"onDoubleClick(row)\"\n (contextmenu)=\"onRightClick($event, row)\">\n\n <!-- Celda dedicada de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <td class=\"ll-pivot-expand-cell\" [style.padding-left]=\"getIndentPx(row._level)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner\" role=\"status\"></span>\n } @else if (row._hasChildren && !customLevels().includes(row._level)) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf\"></span>\n }\n </td>\n }\n\n @if (withCheckbox()) {\n <td class=\"text-center b-table\">\n <label>\n <input type=\"checkbox\" [name]=\"'chk_pv_' + idList\" [id]=\"'chk_pv_' + idList\"\n animatedCheckbox [checked]=\"isItemSelected(idList)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toogleItem(idList, $event)\">\n </label>\n </td>\n }\n\n @if (customActions()) {\n <td class=\"text-center\">\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row, level: row._level }\"></ng-container>\n </td>\n }\n\n @if (customLevels().includes(row._level) && levelTemplate()) {\n <td [attr.colspan]=\"dataColSpan()\">\n <ng-container *ngTemplateOutlet=\"levelTemplate(); context: { $implicit: row, level: row._level, columns: columns() }\">\n </ng-container>\n </td>\n } @else {\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n @if (columnDefMap().has(col.fieldname)) {\n <td>\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else if (col.template) {\n <td>\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else {\n @switch (col.tipo) {\n\n @case ('cell-render') {\n @let resolverItem = resolveCell(col.fieldname, row);\n @if (resolverItem) {\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\n @if (resolverItem.icon) {\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\n } @else if (resolverItem.class) {\n <span [ngClass]=\"resolverItem.class\">{{ resolverItem.text }}</span>\n } @else {\n {{ resolverItem.text }}\n }\n </td>\n }\n }\n\n @default {\n @if (col.fieldname === expandOn()) {\n <!-- Celda con \u00EDcono de expansi\u00F3n incrustado -->\n <td class=\"ll-pivot-expand-inline {{ getPosition(col) }}\"\n [class.cursor-pointer]=\"row._hasChildren\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [style.padding-left]=\"getIndentPx(row._level)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n (click)=\"row._hasChildren ? toggleExpand($event, row) : (withCellSelect() ? onCellClick($event, row, col.fieldname) : null)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner me-1\" role=\"status\"></span>\n } @else if (row._hasChildren) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer me-1\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf me-1\"></span>\n }\n <span [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"></span>\n </td>\n } @else {\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [class.ll-cell--selectable]=\"withCellSelect()\"\n class=\"{{ getPosition(col) }}\"\n (click)=\"withCellSelect() ? onCellClick($event, row, col.fieldname) : null\">\n </td>\n }\n }\n\n }\n }\n }\n }\n }\n\n </tr>\n }\n\n <!-- Estado vac\u00EDo -->\n @if (rowFilter().length === 0) {\n <tr>\n <td [attr.colspan]=\"colSpan()\"\n class=\"ll-empty\">\n Sin datos\n </td>\n </tr>\n }\n\n <!-- Spacer inferior -->\n @if (paddingBottom() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n </tbody>\n\n </table>\n</div>\n\n", styles: [":host(.ll-variant--modern) .ll-search-bar .ll-search-label{display:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control{width:250px!important;min-width:250px!important;border-radius:5px!important;border:1px solid rgba(0,0,0,.12);background-color:#fff;font-size:12px;padding-left:34px;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:10px center;background-size:14px 14px;transition:border-color .15s ease,box-shadow .15s ease;height:30px!important;font-weight:400}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control::placeholder{color:#9ca3af}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control:focus{border-color:#1e293b;box-shadow:0 0 0 3px #1e293b14;outline:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar{border-radius:5px;height:30px!important;width:30px!important;min-width:30px!important;background-color:#fff!important;border:1px solid rgba(0,0,0,.12)!important;color:#546074!important}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar:hover{background-color:#f3f4f6!important;border-color:#0003!important}:host(.ll-variant--modern) .ll-scroll-container{border:1px solid rgba(0,0,0,.08);box-shadow:0 1px 3px #0000000f,0 4px 16px #0000000a;background:#fff}:host(.ll-variant--modern) .ll-table{border-collapse:separate;border-spacing:0;background:#fff}:host(.ll-variant--modern) .ll-thead tr th{background:#f1f1f1;color:#333!important;border:none;border-bottom:1px solid rgba(0,0,0,.1);border-top:1px solid rgba(0,0,0,.1);box-shadow:none;font-weight:700}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap}.ll-search-bar__left{display:flex;align-items:center;gap:6px;flex:1;flex-wrap:wrap}.ll-search-bar__right{display:flex;align-items:center;gap:4px;flex-shrink:0}.ll-search-bar__right .ll-search-group{display:flex;align-items:center;gap:4px}.ll-search-bar__right .ll-search-group .ll-search-label{white-space:nowrap}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{display:flex;align-items:center}@media (max-width: 576px){.ll-search-bar__right{width:100%;justify-content:space-between}.ll-search-bar__right .ll-search-group{flex-direction:column;align-items:flex-start;width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap input{flex:1}}.ll-scroll-container{width:100%;overflow-y:auto;overflow-x:auto;display:block;position:relative;border:var(--border-table-header);border-radius:0;overflow-anchor:none}.ll-scroll-container::-webkit-scrollbar{width:5px;height:5px}.ll-scroll-container::-webkit-scrollbar-track{background:transparent}.ll-scroll-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:10px}.ll-scroll-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3}.ll-thead tr th{font-size:11px;font-weight:600;text-align:start;padding:12px 10px;max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.02em;color:var(--text-color);background-color:var(--background-header-table);border:none;border-bottom:var(--border-table-header);box-shadow:none}.ll-th-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.ll-th-sortable:hover{background-color:var(--bs-table-header-hover-bg)!important}.ll-th-content{display:flex;align-items:center;gap:4px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.3}.ll-pivot-th-expand{width:32px;min-width:32px;max-width:32px}.ll-row{height:34px;cursor:pointer;background-color:#fff;transition:background-color .12s ease}.ll-row:hover{background-color:#eff6ff!important}.ll-row:hover td:first-child{border-left-color:#93c5fd!important}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--selected td:first-child{border-left-color:transparent!important}.ll-row td{font-size:11px;font-weight:400;color:#202433!important;vertical-align:middle;padding:0 10px;border:none;border-bottom:1px solid #f1f5f9;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ll-row--level-0{background-color:#f0f0f0}.ll-row--level-0 td{font-weight:700;color:#1e3a5f;border-bottom:2px solid #e4e4e4}.ll-row--level-0 td:first-child{border-left:4px solid #2563eb!important}.ll-row--level-1 td{font-weight:600;color:#1e3a5f}.ll-row--level-1 td:first-child{border-left:3px solid #38bdf8!important}.ll-row--level-2 td:first-child{border-left:3px solid #34d399!important}.ll-row--level-3 td:first-child{border-left:3px solid #a78bfa!important}.ll-cell--selectable{cursor:cell;transition:background-color .1s}.ll-cell--selectable:hover:not(.ll-cell--selected){background-color:#2563eb0f!important}.ll-cell--selected{background-color:#2563eb21!important;box-shadow:inset 0 0 0 2px #2563eb;color:#1e3a5f!important}.ll-pivot-expand-inline{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ll-pivot-expand-inline .ll-pivot-toggle,.ll-pivot-expand-inline .ll-pivot-leaf,.ll-pivot-expand-inline .ll-pivot-spinner{vertical-align:middle}.ll-pivot-expand-inline span:last-child{vertical-align:middle}.ll-pivot-expand-inline.cursor-pointer:hover span:last-child{text-decoration:underline;text-underline-offset:2px}.ll-pivot-expand-cell{width:32px;min-width:32px;text-align:left;vertical-align:middle}.ll-pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;transition:background-color .15s,border-color .15s;border:1px solid transparent}.ll-pivot-toggle:hover{background-color:#dbeafe;border-color:#93c5fd}.ll-pivot-toggle i{font-size:9px;color:#3b82f6}.ll-pivot-leaf{display:inline-block;width:10px;height:2px;border-radius:2px;background-color:#cbd5e1;vertical-align:middle;margin-left:5px}.ll-pivot-spinner{width:12px;height:12px;border-width:2px;vertical-align:middle}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:32px 16px;color:#94a3b8;font-size:12px;font-style:italic;letter-spacing:.02em}@media (max-width: 1600px){.ll-thead tr th,.ll-row td{font-size:10px}}.popover-menu-column{position:absolute;top:100%;left:0;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.4rem .75rem;border-bottom:1px solid #7e7e7e;position:sticky;top:0;text-align:center}.popover-menu-column::-webkit-scrollbar{width:5px}.popover-menu-column::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.popover-menu-filter{position:absolute;top:85%;right:0;background-color:#fff;border:1px solid #ddd;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto;z-index:2}.popover-menu-filter::-webkit-scrollbar{width:5px}.popover-menu-filter::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-filter::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.cw-25{min-width:40px}.icon-table{color:#2e2e2ed8;font-size:12px}\n"] }]
|
|
4613
|
+
}, template: "@if (withFiltro()) {\n<div class=\"ll-search-bar\">\n <div class=\"ll-search-bar__left\">\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\n </div>\n <div class=\"ll-search-bar__right\">\n <div class=\"ll-search-group\">\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\n <div class=\"ll-search-input-wrap\">\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\"\n [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn btn-dark boton-buscar fs-7\">\n <i class=\"fas fa-cog\"></i>\n </button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Filtros</div>\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\n (change)=\"toggleFiltros($event)\" id=\"filter_pv_todos\" />\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\" for=\"filter_pv_todos\">Todos</label>\n </div>\n @for (col of columns(); track col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'filter_pv_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\n for=\"{{ 'filter_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </div>\n </div>\n </div>\n</div>\n}\n\n<div #scrollContainer class=\"ll-scroll-container\"\n [style.height]=\"withHeight() ? heightStyle() : ''\"\n [style.max-height]=\"heightStyle()\"\n (scroll)=\"onScroll($event)\">\n <table class=\"ll-table\">\n\n <!-- \u2500\u2500 HEADER sticky \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <thead class=\"ll-thead\">\n <tr>\n <!-- Columna de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <th class=\"ll-pivot-th-expand\"></th>\n }\n\n @if (withCheckbox()) {\n <th class=\"cw-20\">\n <label>\n <input type=\"checkbox\" name=\"chk_pv_all\" id=\"chk_pv_all\"\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\n </label>\n </th>\n }\n\n @if (customActions()) {\n <th class=\"cw-40\">\n <app-dropdown-cdk>\n <ng-template #trigger>\n <button class=\"btn p-0 d-flex mx-auto border-0 icon-table\"><i class=\"fas fa-cog\"></i></button>\n </ng-template>\n <ng-template #content>\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\n <div class=\"popover-title fs-7 bg-white\">Columnas</div>\n @for (col of columns(); track col.caption) {\n @if (col.caption) {\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\n id=\"{{ 'switch_pv_' + col.caption }}\" [(ngModel)]=\"visibilidadColumn()[col.fieldname]\" />\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\n for=\"{{ 'switch_pv_' + col.caption }}\">{{ col.caption }}</label>\n </div>\n }\n }\n </div>\n </ng-template>\n </app-dropdown-cdk>\n </th>\n }\n\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\n <span class=\"ll-th-content\">\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\n @if (sortField() === col.fieldname) {\n <i class=\"ms-1\"\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6' : 'fas fa-angle-down fs-6'\"></i>\n } @else {\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n\n <!-- \u2500\u2500 BODY virtual \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <tbody>\n <!-- Spacer superior -->\n @if (paddingTop() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n\n <!-- Filas visibles -->\n @for (row of visibleRows(); track row.idListTsi) {\n @let idList = row.idListTsi;\n <tr class=\"ll-row\"\n [ngClass]=\"getLevelClass(row._level)\"\n [class.ll-row--selected]=\"isSelected(row, idList)\"\n (click)=\"selectRow(row, idList)\"\n (dblclick)=\"onDoubleClick(row)\"\n (contextmenu)=\"onRightClick($event, row)\">\n\n <!-- Celda dedicada de expansi\u00F3n: solo cuando no hay expandOn -->\n @if (!expandOn()) {\n <td class=\"ll-pivot-expand-cell\" [style.padding-left]=\"getIndentPx(row._level)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner\" role=\"status\"></span>\n } @else if (row._hasChildren && !customLevels().includes(row._level)) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf\"></span>\n }\n </td>\n }\n\n @if (withCheckbox()) {\n <td class=\"text-center b-table\">\n <label>\n <input type=\"checkbox\" [name]=\"'chk_pv_' + idList\" [id]=\"'chk_pv_' + idList\"\n animatedCheckbox [checked]=\"isItemSelected(idList)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toogleItem(idList, $event)\">\n </label>\n </td>\n }\n\n @if (customActions()) {\n <td class=\"text-center\">\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row, level: row._level }\"></ng-container>\n </td>\n }\n\n @if (customLevels().includes(row._level) && levelTemplate()) {\n <td [attr.colspan]=\"dataColSpan()\">\n <ng-container *ngTemplateOutlet=\"levelTemplate(); context: { $implicit: row, level: row._level, columns: columns() }\">\n </ng-container>\n </td>\n } @else {\n @for (col of columns(); track $index) {\n @if (validaVisibilidad(col.visible) && visibilidadColumn()[col.fieldname] !== false) {\n @if (columnDefMap().has(col.fieldname)) {\n <td>\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else if (col.template) {\n <td>\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col, level: row._level }\">\n </ng-container>\n </td>\n } @else {\n @switch (col.tipo) {\n\n @case ('cell-render') {\n @let resolverItem = resolveCell(col.fieldname, row);\n @if (resolverItem) {\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\n @if (resolverItem.icon) {\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\n } @else if (resolverItem.class) {\n <span [ngClass]=\"resolverItem.class\">{{ resolverItem.text }}</span>\n } @else {\n {{ resolverItem.text }}\n }\n </td>\n }\n }\n\n @default {\n @if (col.fieldname === expandOn()) {\n <!-- Celda con \u00EDcono de expansi\u00F3n incrustado -->\n <td class=\"ll-pivot-expand-inline {{ getPosition(col) }}\"\n [class.cursor-pointer]=\"row._hasChildren\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [style.padding-left]=\"getIndentPx(row._level)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n (click)=\"row._hasChildren ? toggleExpand($event, row) : (withCellSelect() ? onCellClick($event, row, col.fieldname) : null)\">\n @if (row._isLoading) {\n <span class=\"spinner-border spinner-border-sm ll-pivot-spinner me-1\" role=\"status\"></span>\n } @else if (row._hasChildren) {\n <a class=\"ll-pivot-toggle text-dark cursor-pointer me-1\" (click)=\"toggleExpand($event, row)\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!row._isExpanded\"\n [class.fa-chevron-down]=\"row._isExpanded\"></i>\n </a>\n } @else {\n <span class=\"ll-pivot-leaf me-1\"></span>\n }\n <span [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"></span>\n </td>\n } @else {\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\n [attr.title]=\"row[col.fieldname] || null\"\n [ngClass]=\"rowClassFn() ? rowClassFn()!(row) : null\"\n [class.ll-cell--selected]=\"withCellSelect() && isCellSelected(idList, col.fieldname)\"\n [class.ll-cell--selectable]=\"withCellSelect()\"\n class=\"{{ getPosition(col) }}\"\n (click)=\"withCellSelect() ? onCellClick($event, row, col.fieldname) : null\">\n </td>\n }\n }\n\n }\n }\n }\n }\n }\n\n </tr>\n }\n\n <!-- Estado vac\u00EDo -->\n @if (rowFilter().length === 0) {\n <tr>\n <td [attr.colspan]=\"colSpan()\"\n class=\"ll-empty\">\n Sin datos\n </td>\n </tr>\n }\n\n <!-- Spacer inferior -->\n @if (paddingBottom() > 0) {\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\n <td [attr.colspan]=\"colSpan()\"></td>\n </tr>\n }\n </tbody>\n\n </table>\n</div>\n\n", styles: [":host(.ll-variant--modern) .ll-search-bar .ll-search-label{display:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control{width:250px!important;min-width:250px!important;border-radius:5px!important;border:1px solid rgba(0,0,0,.12);background-color:#fff;font-size:12px;padding-left:34px;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:10px center;background-size:14px 14px;transition:border-color .15s ease,box-shadow .15s ease;height:30px!important;font-weight:400}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control::placeholder{color:#9ca3af}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap input.form-control:focus{border-color:#1e293b;box-shadow:0 0 0 3px #1e293b14;outline:none}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar{border-radius:5px;height:30px!important;width:30px!important;min-width:30px!important;background-color:#fff!important;border:1px solid rgba(0,0,0,.12)!important;color:#546074!important}:host(.ll-variant--modern) .ll-search-bar .ll-search-input-wrap .boton-buscar:hover{background-color:#f3f4f6!important;border-color:#0003!important}:host(.ll-variant--modern) .ll-scroll-container{border:none!important;box-shadow:0 1px 3px #0000000f,0 4px 16px #0000000a;background:#fff}:host(.ll-variant--modern) .ll-table{border-collapse:separate;border-spacing:0;background:#fff}:host(.ll-variant--modern) .ll-thead tr th{background:#f1f1f1;color:#333!important;border:none;border-bottom:1px solid rgba(0,0,0,.1);border-top:1px solid rgba(0,0,0,.1);box-shadow:none;font-weight:700}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}:host(.ll-variant--modern) .ll-row--level-0{background-color:#fff}:host(.ll-variant--modern) .ll-row--level-1{background-color:#f5f5f5}:host(.ll-variant--modern) .ll-row--level-2{background-color:#eee}:host(.ll-variant--modern) .ll-row--level-3{background-color:#e0e0e0}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap}.ll-search-bar__left{display:flex;align-items:center;gap:6px;flex:1;flex-wrap:wrap}.ll-search-bar__right{display:flex;align-items:center;gap:4px;flex-shrink:0}.ll-search-bar__right .ll-search-group{display:flex;align-items:center;gap:4px}.ll-search-bar__right .ll-search-group .ll-search-label{white-space:nowrap}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{display:flex;align-items:center}@media (max-width: 576px){.ll-search-bar__right{width:100%;justify-content:space-between}.ll-search-bar__right .ll-search-group{flex-direction:column;align-items:flex-start;width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap{width:100%}.ll-search-bar__right .ll-search-group .ll-search-input-wrap input{flex:1}}.ll-scroll-container{width:100%;overflow-y:auto;overflow-x:auto;display:block;position:relative;border:var(--border-table-header);border-radius:0;overflow-anchor:none}.ll-scroll-container::-webkit-scrollbar{width:5px;height:5px}.ll-scroll-container::-webkit-scrollbar-track{background:transparent}.ll-scroll-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:10px}.ll-scroll-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3}.ll-thead tr th{font-size:11px;font-weight:600;text-align:start;padding:12px 10px;max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.02em;color:var(--text-color);background-color:var(--background-header-table);border:none;border-bottom:var(--border-table-header);box-shadow:none}.ll-th-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.ll-th-sortable:hover{background-color:var(--bs-table-header-hover-bg)!important}.ll-th-content{display:flex;align-items:center;gap:4px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.3}.ll-pivot-th-expand{width:32px;min-width:32px;max-width:32px}.ll-row{height:34px;cursor:pointer;background-color:#f0f0f0;transition:background-color .12s ease}.ll-row:hover{background-color:#eff6ff!important}.ll-row:hover td:first-child{border-left-color:#93c5fd!important}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--selected td:first-child{border-left-color:transparent!important}.ll-row td{font-size:11px;font-weight:400;color:#202433!important;vertical-align:middle;padding:0 10px;border:none;border-bottom:1px solid #f1f5f9;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;border-bottom:2px solid #e4e4e4}.ll-row--level-0{background-color:#fff}.ll-row--level-0 td{font-weight:700;color:#1e3a5f}.ll-row--level-0 td:first-child{border-left:4px solid #2563eb!important}.ll-row--level-1 td{font-weight:600;color:#1e3a5f}.ll-row--level-1 td:first-child{border-left:3px solid #38bdf8!important}.ll-row--level-2 td:first-child{border-left:3px solid #34d399!important}.ll-row--level-3 td:first-child{border-left:3px solid #a78bfa!important}.ll-cell--selectable{cursor:cell;transition:background-color .1s}.ll-cell--selectable:hover:not(.ll-cell--selected){background-color:#2563eb0f!important}.ll-cell--selected{background-color:#2563eb21!important;box-shadow:inset 0 0 0 2px #2563eb;color:#1e3a5f!important}.ll-pivot-expand-inline{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ll-pivot-expand-inline .ll-pivot-toggle,.ll-pivot-expand-inline .ll-pivot-leaf,.ll-pivot-expand-inline .ll-pivot-spinner{vertical-align:middle}.ll-pivot-expand-inline span:last-child{vertical-align:middle}.ll-pivot-expand-inline.cursor-pointer:hover span:last-child{text-decoration:underline;text-underline-offset:2px}.ll-pivot-expand-cell{width:32px;min-width:32px;text-align:left;vertical-align:middle}.ll-pivot-toggle{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;transition:background-color .15s,border-color .15s;border:1px solid transparent}.ll-pivot-toggle:hover{background-color:#dbeafe;border-color:#93c5fd}.ll-pivot-toggle i{font-size:9px;color:#3b82f6}.ll-pivot-leaf{display:inline-block;width:10px;height:2px;border-radius:2px;background-color:#cbd5e1;vertical-align:middle;margin-left:5px}.ll-pivot-spinner{width:12px;height:12px;border-width:2px;vertical-align:middle}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:32px 16px;color:#94a3b8;font-size:12px;font-style:italic;letter-spacing:.02em}@media (max-width: 1600px){.ll-thead tr th,.ll-row td{font-size:10px}}.popover-menu-column{position:absolute;top:100%;left:0;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.4rem .75rem;border-bottom:1px solid #7e7e7e;position:sticky;top:0;text-align:center}.popover-menu-column::-webkit-scrollbar{width:5px}.popover-menu-column::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.popover-menu-filter{position:absolute;top:85%;right:0;background-color:#fff;border:1px solid #ddd;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:300px;width:250px;overflow-y:auto;z-index:2}.popover-menu-filter::-webkit-scrollbar{width:5px}.popover-menu-filter::-webkit-scrollbar-track{background:#f1f1f1;border-radius:4px}.popover-menu-filter::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.cw-25{min-width:40px}.icon-table{color:#2e2e2ed8;font-size:12px}\n"] }]
|
|
4598
4614
|
}] });
|
|
4599
4615
|
|
|
4600
4616
|
class TableAgrupadaComponent {
|