ng-components-tsi 0.0.71 → 0.0.73
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/fesm2022/ng-components-tsi.mjs +48 -17
- package/fesm2022/ng-components-tsi.mjs.map +1 -1
- package/lib/modals/general/md-generico/md-generico.component.d.ts +2 -2
- package/lib/ui/forms/inputs/autocomplete-cdk/autocomplete.component.d.ts +4 -1
- package/lib/ui/forms/inputs/input/input.component.d.ts +4 -4
- package/lib/ui/forms/inputs/input-radio/input-radio.component.d.ts +1 -1
- package/lib/ui/forms/lists/list-option/list-option.component.d.ts +1 -1
- package/lib/ui/tables/paginador/paginador.component.d.ts +1 -1
- package/lib/ui/tables/table-ultimate/table-ultimate.component.d.ts +1 -1
- package/lib/ui/tables/table-ultimate-pivot/table-ultimate-pivot.component.d.ts +15 -3
- package/package.json +1 -1
|
@@ -942,6 +942,7 @@ class AutocompleteV2Component {
|
|
|
942
942
|
customBorderColor = input('');
|
|
943
943
|
customBoxShadow = input('');
|
|
944
944
|
customTransition = input('');
|
|
945
|
+
firstItemDefault = input(false);
|
|
945
946
|
// NUEVAS VARIABLES
|
|
946
947
|
lista = input([]);
|
|
947
948
|
filterQuery = signal('');
|
|
@@ -951,6 +952,7 @@ class AutocompleteV2Component {
|
|
|
951
952
|
value = model(null);
|
|
952
953
|
searchText = model('');
|
|
953
954
|
listaMap = computed(() => this.toKeyValue(this.lista(), this.keyCodigo(), this.keyDescri()));
|
|
955
|
+
firstItem = computed(() => getFirstItem(this.lista()));
|
|
954
956
|
withCheckTodos = input(false);
|
|
955
957
|
listboxId = computed(() => 'listbox_' + this.label());
|
|
956
958
|
selectedIndex = computed(() => {
|
|
@@ -962,13 +964,25 @@ class AutocompleteV2Component {
|
|
|
962
964
|
allDisabled = model();
|
|
963
965
|
altoContainer = input(200);
|
|
964
966
|
resizeObserver;
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
const
|
|
968
|
-
if (
|
|
967
|
+
effectDefaultValue = effect(() => {
|
|
968
|
+
if (this.firstItemDefault()) {
|
|
969
|
+
const firstItem = this.firstItem();
|
|
970
|
+
if (!firstItem)
|
|
969
971
|
return;
|
|
970
|
-
this.
|
|
971
|
-
|
|
972
|
+
this.selectItem(firstItem);
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
const map = this.listaMap();
|
|
976
|
+
if (Object.keys(map).length === 0)
|
|
977
|
+
return;
|
|
978
|
+
this.blurKey();
|
|
979
|
+
});
|
|
980
|
+
constructor() {
|
|
981
|
+
// effect(() => {
|
|
982
|
+
// const map = this.listaMap()
|
|
983
|
+
// if (Object.keys(map).length == 0) return;
|
|
984
|
+
// this.blurKey()
|
|
985
|
+
// })
|
|
972
986
|
effect(() => {
|
|
973
987
|
const el = this.inputRef()?.nativeElement;
|
|
974
988
|
if (!el)
|
|
@@ -993,6 +1007,7 @@ class AutocompleteV2Component {
|
|
|
993
1007
|
this.filterQuery.set('');
|
|
994
1008
|
this.showDropdown.set(false);
|
|
995
1009
|
this.highlightedIndex.set(-1);
|
|
1010
|
+
this.changeInput.emit();
|
|
996
1011
|
}
|
|
997
1012
|
openDropdown() {
|
|
998
1013
|
this.filterQuery.set('');
|
|
@@ -1067,7 +1082,7 @@ class AutocompleteV2Component {
|
|
|
1067
1082
|
itemElement?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
1068
1083
|
}
|
|
1069
1084
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: AutocompleteV2Component, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1070
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: AutocompleteV2Component, isStandalone: true, selector: "app-autocomplete-v2", inputs: { wlabel: { classPropertyName: "wlabel", publicName: "wlabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isRequired: { classPropertyName: "isRequired", publicName: "isRequired", isSignal: true, isRequired: false, transformFunction: null }, keyCodigo: { classPropertyName: "keyCodigo", publicName: "keyCodigo", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, withTodos: { classPropertyName: "withTodos", publicName: "withTodos", isSignal: true, isRequired: false, transformFunction: null }, searchIdText: { classPropertyName: "searchIdText", publicName: "searchIdText", isSignal: true, isRequired: false, transformFunction: null }, disabled1: { classPropertyName: "disabled1", publicName: "disabled1", isSignal: true, isRequired: false, transformFunction: null }, disabled2: { classPropertyName: "disabled2", publicName: "disabled2", isSignal: true, isRequired: false, transformFunction: null }, isVertical: { classPropertyName: "isVertical", publicName: "isVertical", isSignal: true, isRequired: false, transformFunction: null }, joinInfo: { classPropertyName: "joinInfo", publicName: "joinInfo", isSignal: true, isRequired: false, transformFunction: null }, activeFocus: { classPropertyName: "activeFocus", publicName: "activeFocus", isSignal: true, isRequired: false, transformFunction: null }, customBorderColor: { classPropertyName: "customBorderColor", publicName: "customBorderColor", isSignal: true, isRequired: false, transformFunction: null }, customBoxShadow: { classPropertyName: "customBoxShadow", publicName: "customBoxShadow", isSignal: true, isRequired: false, transformFunction: null }, customTransition: { classPropertyName: "customTransition", publicName: "customTransition", isSignal: true, isRequired: false, transformFunction: null }, lista: { classPropertyName: "lista", publicName: "lista", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null }, withCheckTodos: { classPropertyName: "withCheckTodos", publicName: "withCheckTodos", isSignal: true, isRequired: false, transformFunction: null }, allDisabled: { classPropertyName: "allDisabled", publicName: "allDisabled", isSignal: true, isRequired: false, transformFunction: null }, altoContainer: { classPropertyName: "altoContainer", publicName: "altoContainer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchIdText: "searchIdTextChange", disabled1: "disabled1Change", disabled2: "disabled2Change", changeInput: "changeInput", value: "valueChange", searchText: "searchTextChange", allDisabled: "allDisabledChange" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, isSignal: true }, { propertyName: "autocompleteItems", predicate: ["autocompleteItem"], descendants: true }], ngImport: i0, template: "@if (isVertical()) {\r\n<label for=\"{{'id_' + label()}}\" [style.min-width]=\"wlabel() + 'px'\"> {{label()}} @if (isRequired()) {<span\r\n class=\"fw-bold text-danger\">(*)</span>}</label>\r\n}\r\n<div class=\"d-flex align-items-center\">\r\n @if (!isVertical()) {\r\n <label for=\"{{'id_' + label()}}\" [style.min-width]=\"wlabel() + 'px'\">{{label()}} @if (isRequired()) { <span\r\n class=\"fw-bold text-danger\">(*)</span>}</label>\r\n }\r\n\r\n <div class=\"autocomplete d-flex \">\r\n @if(computedType()){\r\n <div class=\"content-1 me-1\">\r\n <input type=\"text\" class=\"form-control show-input\"\r\n [attr.data-active-focus]=\"activeFocus() == false ? 'false' : ''\"\r\n [style.--focus-border-color]=\"customBorderColor()\" [style.--focus-box-shadow]=\"customBoxShadow()\"\r\n [style.--focus-transition]=\"customTransition()\" [disabled]=\"allDisabled() ? true : disabled1()\"\r\n [(ngModel)]=\"value\" (blur)=\"blurKey()\" id=\"{{'id_value_' + label()}}\" name=\"{{'id_value_' + label()}}\" />\r\n </div>\r\n }\r\n\r\n <div class=\"input-container content-2 me-2\">\r\n <input type=\"text\" [autocomplete]=\"false\" [(ngModel)]=\"searchText\" class=\"form-control pe-4\" cdkOverlayOrigin\r\n #autocomplete=\"cdkOverlayOrigin\" #inputRef [attr.data-active-focus]=\"activeFocus() == false ? 'false' : ''\"\r\n [style.--focus-border-color]=\"customBorderColor()\" [style.--focus-box-shadow]=\"customBoxShadow()\"\r\n [style.--focus-transition]=\"customTransition()\" [disabled]=\"allDisabled() ? true : disabled2()\"\r\n id=\"{{'id_' + label()}}\" name=\"{{'id_' + label()}}\" role=\"combobox\" aria-autocomplete=\"list\"\r\n aria-haspopup=\"listbox\" [attr.aria-expanded]=\"showDropdown()\" [attr.aria-controls]=\"listboxId()\"\r\n [attr.aria-activedescendant]=\"highlightedIndex() >= 0 ? (listboxId() + '_opt_' + highlightedIndex()) : null\"\r\n (input)=\"onSearchInput()\" (blur)=\"onBlur()\" (focus)=\"openDropdown()\" (keydown)=\"onKeyDown($event)\" />\r\n <i class=\"dropdown-arrow fa-solid fa-chevron-down\" [class.rotate-up]=\"showDropdown()\"></i>\r\n <!-- @if (searchText().length > 0) {\r\n <button @fadeInOut type=\"button\" class=\"btn-clear text-dark\" [disabled]=\"allDisabled() ? true : disabled2()\"\r\n (mousedown)=\"$event.preventDefault()\" (click)=\"clear(); inputRef.focus()\">\r\n ×\r\n </button>\r\n } @else {\r\n <i class=\"dropdown-arrow fa-solid fa-chevron-down\" [class.rotate-up]=\"showDropdown()\"></i>\r\n } -->\r\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"autocomplete\"\r\n [cdkConnectedOverlayOpen]=\"showDropdown()\" [cdkConnectedOverlayHasBackdrop]=\"true\"\r\n [cdkConnectedOverlayWidth]=\"withInput()\" (backdropClick)=\"onBlur()\"\r\n cdkConnectedOverlayPanelClass=\"autocomplete-overlay\" cdkConnectedOverlayBackdropClass=\"transparent-backdrop\">\r\n\r\n <ul [style.maxHeight.px]=\"altoContainer()\" [id]=\"listboxId()\" role=\"listbox\">\r\n @for (item of filteredItems(); track $index) {\r\n <li #autocompleteItem class=\"text-dark\" role=\"option\" [id]=\"listboxId() + '_opt_' + $index\"\r\n [attr.aria-selected]=\"item[keyCodigo()] == value()\"\r\n [ngClass]=\"{'fw-bold': item[keyCodigo()] == value(), 'selected-item': highlightedIndex() == $index}\"\r\n (mousedown)=\"selectItem(item)\">\r\n @if (joinInfo()) {\r\n {{ item[keyCodigo()] }} - {{ item[keyDescri()] }}\r\n } @else{\r\n {{ item[keyDescri()] }}\r\n }\r\n @if (item[keyCodigo()] == value()) {\r\n <i class=\"ms-2 far fa-check fw-bold text-success cw-20\"></i>\r\n }\r\n </li>\r\n } @empty {\r\n <li class=\"text-muted no-results\">Sin resultados</li>\r\n }\r\n </ul>\r\n </ng-template>\r\n </div>\r\n @if (withCheckTodos()) {\r\n <div class=\"px-2\"> <app-check-box label=\"Todos\" name=\"check_todos\" [value]=\"true\" [(binding)]=\"allDisabled\"\r\n (bindingChange)=\"value.set('');\" /></div>\r\n }\r\n </div>\r\n</div>", styles: [".autocomplete{position:relative;width:100%}ul{width:100%;list-style:none;padding:0;margin:0;overflow:hidden;transition:max-height .3s ease-out,opacity .3s ease-out;box-shadow:0 4px 6px #0000001a;overflow-y:auto;border-radius:0 0 8px 8px;z-index:9999}li{padding:8px;font-size:.7rem;font-weight:400;cursor:pointer;opacity:80%}li:hover{opacity:100%;background:#16161616}.no-results{cursor:default;text-align:center;opacity:60%}.no-results:hover{background:transparent}.dropdown-arrow{position:absolute;right:15px;font-size:11px;color:#6c757d;transition:transform .3s ease-in-out;pointer-events:none;-webkit-user-select:none;user-select:none}.dropdown-arrow.rotate-up{transform:rotate(180deg)}@media (max-width: 442px){.d-flex{flex-direction:column!important;align-items:stretch!important}}.content-1{flex-basis:23%;display:flex;align-items:center}.content-2{flex-grow:1;display:flex;align-items:center}.input-container{position:relative;display:flex;align-items:center;width:70%}.show-input{display:block}@media (max-width: 443px){.show-input{display:none}.input-container{width:100%;padding-right:8px}}.btn-clear{position:absolute;right:15px;background:transparent;border:none;font-size:1.3rem;font-weight:300;line-height:1;cursor:pointer;padding:0}.selected-item{background:#0041ce!important;color:#fff!important}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: 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: OverlayModule }, { kind: "directive", type: i1$2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: CheckBoxComponent, selector: "app-check-box", inputs: ["name", "id", "label", "value", "disabled", "binding", "class", "checked"], outputs: ["bindingChange", "changeCheck"] }], animations: [fadeInOut] });
|
|
1085
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: AutocompleteV2Component, isStandalone: true, selector: "app-autocomplete-v2", inputs: { wlabel: { classPropertyName: "wlabel", publicName: "wlabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isRequired: { classPropertyName: "isRequired", publicName: "isRequired", isSignal: true, isRequired: false, transformFunction: null }, keyCodigo: { classPropertyName: "keyCodigo", publicName: "keyCodigo", isSignal: true, isRequired: false, transformFunction: null }, keyDescri: { classPropertyName: "keyDescri", publicName: "keyDescri", isSignal: true, isRequired: false, transformFunction: null }, withTodos: { classPropertyName: "withTodos", publicName: "withTodos", isSignal: true, isRequired: false, transformFunction: null }, searchIdText: { classPropertyName: "searchIdText", publicName: "searchIdText", isSignal: true, isRequired: false, transformFunction: null }, disabled1: { classPropertyName: "disabled1", publicName: "disabled1", isSignal: true, isRequired: false, transformFunction: null }, disabled2: { classPropertyName: "disabled2", publicName: "disabled2", isSignal: true, isRequired: false, transformFunction: null }, isVertical: { classPropertyName: "isVertical", publicName: "isVertical", isSignal: true, isRequired: false, transformFunction: null }, joinInfo: { classPropertyName: "joinInfo", publicName: "joinInfo", isSignal: true, isRequired: false, transformFunction: null }, activeFocus: { classPropertyName: "activeFocus", publicName: "activeFocus", isSignal: true, isRequired: false, transformFunction: null }, customBorderColor: { classPropertyName: "customBorderColor", publicName: "customBorderColor", isSignal: true, isRequired: false, transformFunction: null }, customBoxShadow: { classPropertyName: "customBoxShadow", publicName: "customBoxShadow", isSignal: true, isRequired: false, transformFunction: null }, customTransition: { classPropertyName: "customTransition", publicName: "customTransition", isSignal: true, isRequired: false, transformFunction: null }, firstItemDefault: { classPropertyName: "firstItemDefault", publicName: "firstItemDefault", isSignal: true, isRequired: false, transformFunction: null }, lista: { classPropertyName: "lista", publicName: "lista", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null }, withCheckTodos: { classPropertyName: "withCheckTodos", publicName: "withCheckTodos", isSignal: true, isRequired: false, transformFunction: null }, allDisabled: { classPropertyName: "allDisabled", publicName: "allDisabled", isSignal: true, isRequired: false, transformFunction: null }, altoContainer: { classPropertyName: "altoContainer", publicName: "altoContainer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchIdText: "searchIdTextChange", disabled1: "disabled1Change", disabled2: "disabled2Change", changeInput: "changeInput", value: "valueChange", searchText: "searchTextChange", allDisabled: "allDisabledChange" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, isSignal: true }, { propertyName: "autocompleteItems", predicate: ["autocompleteItem"], descendants: true }], ngImport: i0, template: "@if (isVertical()) {\r\n<label for=\"{{'id_' + label()}}\" [style.min-width]=\"wlabel() + 'px'\"> {{label()}} @if (isRequired()) {<span\r\n class=\"fw-bold text-danger\">(*)</span>}</label>\r\n}\r\n<div class=\"d-flex align-items-center\">\r\n @if (!isVertical()) {\r\n <label for=\"{{'id_' + label()}}\" [style.min-width]=\"wlabel() + 'px'\">{{label()}} @if (isRequired()) { <span\r\n class=\"fw-bold text-danger\">(*)</span>}</label>\r\n }\r\n\r\n <div class=\"autocomplete d-flex \">\r\n @if(computedType()){\r\n <div class=\"content-1 me-1\">\r\n <input type=\"text\" class=\"form-control show-input\"\r\n [attr.data-active-focus]=\"activeFocus() == false ? 'false' : ''\"\r\n [style.--focus-border-color]=\"customBorderColor()\" [style.--focus-box-shadow]=\"customBoxShadow()\"\r\n [style.--focus-transition]=\"customTransition()\" [disabled]=\"allDisabled() ? true : disabled1()\"\r\n [(ngModel)]=\"value\" (blur)=\"blurKey()\" id=\"{{'id_value_' + label()}}\" name=\"{{'id_value_' + label()}}\" />\r\n </div>\r\n }\r\n\r\n <div class=\"input-container content-2 me-2\">\r\n <input type=\"text\" [autocomplete]=\"false\" [(ngModel)]=\"searchText\" class=\"form-control pe-4\" cdkOverlayOrigin\r\n #autocomplete=\"cdkOverlayOrigin\" #inputRef [attr.data-active-focus]=\"activeFocus() == false ? 'false' : ''\"\r\n [style.--focus-border-color]=\"customBorderColor()\" [style.--focus-box-shadow]=\"customBoxShadow()\"\r\n [style.--focus-transition]=\"customTransition()\" [disabled]=\"allDisabled() ? true : disabled2()\"\r\n id=\"{{'id_' + label()}}\" name=\"{{'id_' + label()}}\" role=\"combobox\" aria-autocomplete=\"list\"\r\n aria-haspopup=\"listbox\" [attr.aria-expanded]=\"showDropdown()\" [attr.aria-controls]=\"listboxId()\"\r\n [attr.aria-activedescendant]=\"highlightedIndex() >= 0 ? (listboxId() + '_opt_' + highlightedIndex()) : null\"\r\n (input)=\"onSearchInput()\" (blur)=\"onBlur()\" (focus)=\"openDropdown()\" (keydown)=\"onKeyDown($event)\" />\r\n <i class=\"dropdown-arrow fa-solid fa-chevron-down\" [class.rotate-up]=\"showDropdown()\"></i>\r\n <!-- @if (searchText().length > 0) {\r\n <button @fadeInOut type=\"button\" class=\"btn-clear text-dark\" [disabled]=\"allDisabled() ? true : disabled2()\"\r\n (mousedown)=\"$event.preventDefault()\" (click)=\"clear(); inputRef.focus()\">\r\n ×\r\n </button>\r\n } @else {\r\n <i class=\"dropdown-arrow fa-solid fa-chevron-down\" [class.rotate-up]=\"showDropdown()\"></i>\r\n } -->\r\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"autocomplete\"\r\n [cdkConnectedOverlayOpen]=\"showDropdown()\" [cdkConnectedOverlayHasBackdrop]=\"true\"\r\n [cdkConnectedOverlayWidth]=\"withInput()\" (backdropClick)=\"onBlur()\"\r\n cdkConnectedOverlayPanelClass=\"autocomplete-overlay\" cdkConnectedOverlayBackdropClass=\"transparent-backdrop\">\r\n\r\n <ul [style.maxHeight.px]=\"altoContainer()\" [id]=\"listboxId()\" role=\"listbox\">\r\n @for (item of filteredItems(); track $index) {\r\n <li #autocompleteItem class=\"text-dark\" role=\"option\" [id]=\"listboxId() + '_opt_' + $index\"\r\n [attr.aria-selected]=\"item[keyCodigo()] == value()\"\r\n [ngClass]=\"{'fw-bold': item[keyCodigo()] == value(), 'selected-item': highlightedIndex() == $index}\"\r\n (mousedown)=\"selectItem(item)\">\r\n @if (joinInfo()) {\r\n {{ item[keyCodigo()] }} - {{ item[keyDescri()] }}\r\n } @else{\r\n {{ item[keyDescri()] }}\r\n }\r\n @if (item[keyCodigo()] == value()) {\r\n <i class=\"ms-2 far fa-check fw-bold text-success cw-20\"></i>\r\n }\r\n </li>\r\n } @empty {\r\n <li class=\"text-muted no-results\">Sin resultados</li>\r\n }\r\n </ul>\r\n </ng-template>\r\n </div>\r\n @if (withCheckTodos()) {\r\n <div class=\"px-2\"> <app-check-box label=\"Todos\" name=\"check_todos\" [value]=\"true\" [(binding)]=\"allDisabled\"\r\n (bindingChange)=\"value.set('');\" /></div>\r\n }\r\n </div>\r\n</div>", styles: [".autocomplete{position:relative;width:100%}ul{width:100%;list-style:none;padding:0;margin:0;overflow:hidden;transition:max-height .3s ease-out,opacity .3s ease-out;box-shadow:0 4px 6px #0000001a;overflow-y:auto;border-radius:0 0 8px 8px;z-index:9999}li{padding:8px;font-size:.7rem;font-weight:400;cursor:pointer;opacity:80%}li:hover{opacity:100%;background:#16161616}.no-results{cursor:default;text-align:center;opacity:60%}.no-results:hover{background:transparent}.dropdown-arrow{position:absolute;right:15px;font-size:11px;color:#6c757d;transition:transform .3s ease-in-out;pointer-events:none;-webkit-user-select:none;user-select:none}.dropdown-arrow.rotate-up{transform:rotate(180deg)}@media (max-width: 442px){.d-flex{flex-direction:column!important;align-items:stretch!important}}.content-1{flex-basis:23%;display:flex;align-items:center}.content-2{flex-grow:1;display:flex;align-items:center}.input-container{position:relative;display:flex;align-items:center;width:70%}.show-input{display:block}@media (max-width: 443px){.show-input{display:none}.input-container{width:100%;padding-right:8px}}.btn-clear{position:absolute;right:15px;background:transparent;border:none;font-size:1.3rem;font-weight:300;line-height:1;cursor:pointer;padding:0}.selected-item{background:#0041ce!important;color:#fff!important}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: 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: OverlayModule }, { kind: "directive", type: i1$2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: CheckBoxComponent, selector: "app-check-box", inputs: ["name", "id", "label", "value", "disabled", "binding", "class", "checked"], outputs: ["bindingChange", "changeCheck"] }], animations: [fadeInOut] });
|
|
1071
1086
|
}
|
|
1072
1087
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: AutocompleteV2Component, decorators: [{
|
|
1073
1088
|
type: Component,
|
|
@@ -4129,13 +4144,13 @@ class TableUltimateComponent {
|
|
|
4129
4144
|
}
|
|
4130
4145
|
getRows = () => this.rowFormat().map(({ idListTsi, format, ...rest }) => rest);
|
|
4131
4146
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TableUltimateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4132
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TableUltimateComponent, isStandalone: true, selector: "app-table-ultimate", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, footerRows: { classPropertyName: "footerRows", publicName: "footerRows", 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 }, withDetails: { classPropertyName: "withDetails", publicName: "withDetails", isSignal: true, isRequired: false, transformFunction: null }, withCheckbox: { classPropertyName: "withCheckbox", publicName: "withCheckbox", isSignal: true, isRequired: false, transformFunction: null }, withTotal: { classPropertyName: "withTotal", publicName: "withTotal", isSignal: true, isRequired: false, transformFunction: null }, withHeight: { classPropertyName: "withHeight", publicName: "withHeight", isSignal: true, isRequired: false, transformFunction: null }, withAttachment: { classPropertyName: "withAttachment", publicName: "withAttachment", isSignal: true, isRequired: false, transformFunction: null }, variante: { classPropertyName: "variante", publicName: "variante", isSignal: true, isRequired: false, transformFunction: null }, rendered: { classPropertyName: "rendered", publicName: "rendered", isSignal: true, isRequired: false, transformFunction: null }, titleTabla: { classPropertyName: "titleTabla", publicName: "titleTabla", isSignal: true, isRequired: false, transformFunction: null }, activeMobileMode: { classPropertyName: "activeMobileMode", publicName: "activeMobileMode", isSignal: true, isRequired: false, transformFunction: null }, selectedRow: { classPropertyName: "selectedRow", publicName: "selectedRow", isSignal: true, isRequired: false, transformFunction: null }, rowClassFn: { classPropertyName: "rowClassFn", publicName: "rowClassFn", isSignal: true, isRequired: false, transformFunction: null }, rowDisabledFn: { classPropertyName: "rowDisabledFn", publicName: "rowDisabledFn", isSignal: true, isRequired: false, transformFunction: null }, selectItems: { classPropertyName: "selectItems", publicName: "selectItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowEvent: "rowEvent", selectedRow: "selectedRowChange", selectItems: "selectItemsChange" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "class.ll-variant--modern": "variante() === \"modern\"" } }, queries: [{ propertyName: "customActions", first: true, predicate: ["customActions"], descendants: true, isSignal: true }, { propertyName: "columnDefs", predicate: TsiColumnDefDirective, isSignal: true }, { propertyName: "contentFilter", first: true, predicate: ["header"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (withFiltro()) {\r\n<div class=\"ll-search-bar\">\r\n\r\n <div class=\"ll-search-bar__left\">\r\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\r\n </div>\r\n\r\n <div class=\"ll-search-bar__right\">\r\n\r\n <div class=\"ll-search-group\">\r\n\r\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\r\n <div class=\"ll-search-input-wrap\">\r\n\r\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\" [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn btn-dark boton-buscar fs-7\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n\r\n <ng-template #content>\r\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white\">\r\n Filtros\r\n </div>\r\n\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\r\n (change)=\"toggleFiltros($event)\" id=\"filter_table_lazy_todos\" />\r\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\"\r\n for=\"filter_table_lazy_todos\">\r\n Todos\r\n </label>\r\n </div>\r\n\r\n @for (col of columns(); track col.caption) {\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'filter_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\r\n for=\"{{ 'filter_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n\r\n</div>\r\n}\r\n\r\n@if (activeMobileMode()) {\r\n@if (isLoadingResponsive()) {\r\n<div class=\"d-flex flex-column justify-content-center align-items-center py-2\">\r\n <div class=\"spinner-border text-secondary mb-2\" role=\"status\"></div>\r\n <span class=\"ms-2 fs-6\">Cargando...</span>\r\n</div>\r\n}\r\n\r\n@if (!isLoadingResponsive()) {\r\n@if (isMobile()) {\r\n<app-card-mobile [data]=\"rowFilter()\" [columns]=\"columns()\" [actions]=\"customActions()\" [identifier]=\"identifier()\"\r\n [titleTabla]=\"titleTabla()\" [altoContainer]=\"altoContainer()\" />\r\n}\r\n@if (!isMobile()) {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n}\r\n}\r\n@else {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n\r\n<ng-template #table>\r\n <!-- Contenedor scrolleable \u2014 solo el BODY hace scroll; header y footer son sticky -->\r\n <div #scrollContainer class=\"ll-scroll-container\"\r\n [style.height]=\"withHeight() ? heightStyle() : ''\"\r\n [style.max-height]=\"heightStyle()\" (scroll)=\"onScroll($event)\">\r\n <table class=\"ll-table\">\r\n\r\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 -->\r\n <thead class=\"ll-thead\">\r\n <tr>\r\n @if (withDetails()) {\r\n <th class=\"cw-25\"></th>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <th class=\"cw-20\">\r\n <label>\r\n <input type=\"checkbox\" name=\"check_box_select_table_main\" id=\"check_box_select_table_main\"\r\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\r\n </label>\r\n </th>\r\n }\r\n\r\n @if (customActions()) {\r\n <th class=\"cw-40\">\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn p-0 text-dark d-flex mx-auto border-0 icon-table\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n <ng-template #content>\r\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white d-flex align-items-baseline justify-content-between\">\r\n <span>Columnas</span>\r\n <span class=\"column-config-hint\">arrastra para ordenar</span>\r\n </div>\r\n\r\n <div cdkDropList class=\"column-config-list\" (cdkDropListDropped)=\"onColumnDrop($event)\">\r\n @for (col of columnasConfigurables(); track col.fieldname) {\r\n <div class=\"column-config-row\" cdkDrag>\r\n <i class=\"fas fa-grip-vertical column-config-grip\" cdkDragHandle></i>\r\n <div class=\"form-check form-switch text-start d-flex align-items-center mb-0 flex-grow-1\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'switch_' + col.caption }}\"\r\n [checked]=\"isColumnVisible(col.fieldname)\"\r\n (change)=\"toggleColumnVisible(col.fieldname, $event)\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\r\n for=\"{{ 'switch_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"column-config-footer\">\r\n <!-- <button type=\"button\" class=\"btn btn-link btn-sm p-0 text-secondary fs-7\"\r\n (click)=\"restablecerConfiguracionColumnas()\">\r\n Restablecer\r\n </button> -->\r\n <button type=\"button\" class=\"btn btn-sm fs-7 column-config-save\"\r\n (click)=\"guardarConfiguracionColumnas()\">\r\n Guardar configuraci\u00F3n\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n </th>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\r\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\r\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\r\n <span class=\"ll-th-content\">\r\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\r\n @if (sortField() === col.fieldname) {\r\n <i class=\"ms-1\"\r\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6':'fas fa-angle-down fs-6'\"></i>\r\n } @else {\r\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\r\n }\r\n </span>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\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 -->\r\n <tbody>\r\n <!-- Spacer superior: ocupa el espacio de las filas NO renderizadas arriba -->\r\n @if (paddingTop() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n\r\n <!-- Filas visibles -->\r\n @for (row of visibleRows(); track row.idListTsi) {\r\n @let idList = row.idListTsi;\r\n <tr class=\"ll-row\" [class.ll-row--selected]=\"isSelected(row, idList)\"\r\n [class.ll-row--drag-over]=\"withAttachment() && dragOverRowId() === idList\"\r\n (click)=\"selectRow(row, idList)\" (dblclick)=\"onDoubleClick(row)\"\r\n (contextmenu)=\"onRightClick($event,row)\"\r\n (dragover)=\"withAttachment() && onDragOver($event, idList)\"\r\n (dragleave)=\"withAttachment() && onDragLeave()\" (drop)=\"withAttachment() && onDrop($event, row)\">\r\n\r\n @if (withDetails()) {\r\n <td class=\"b-table text-center mwp-25\">\r\n <a (click)=\"toggleExpandRow(idList)\" class=\"text-dark cursor-pointer fs-6\">\r\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"expandedRows() != idList\"\r\n [class.fa-chevron-down]=\"expandedRows() == idList\"></i>\r\n </a>\r\n </td>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <td scope=\"col\" class=\"text-center b-table\">\r\n <label>\r\n <input type=\"checkbox\" [name]=\"'check_box_select_table_' + idList\"\r\n [id]=\"'check_box_select_table_' + idList\" animatedCheckbox\r\n [checked]=\"isItemSelected(idList)\" (click)=\"$event.stopPropagation()\"\r\n (change)=\"toogleItem(idList , $event)\" [disabled]=\"isCheckboxDisabled(row)\">\r\n </label>\r\n </td>\r\n }\r\n\r\n @if (customActions()) {\r\n <td class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row }\"></ng-container>\r\n </td>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n @if (columnDefMap().has(col.fieldname)) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else if (col.template) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else {\r\n @switch (col.tipo) {\r\n\r\n @case ('cell-render') {\r\n @let resolverItem = resolveCell(col.fieldname, row);\r\n @if (resolverItem) {\r\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\r\n @if (resolverItem.icon) {\r\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\r\n } @else if (resolverItem.class) {\r\n <span [ngClass]=\"row.situac == 'J' ? 'text-error' : resolverItem.class\">\r\n {{ resolverItem.text }}\r\n </span>\r\n } @else {\r\n {{ resolverItem.text }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @default {\r\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\r\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [attr.title]=\"row[col.fieldname] || null\"\r\n [ngClass]=\"rowClassFn() ? rowClassFn()(row) : getRowClass(row)\" class=\"{{getPosition(col)}}\">\r\n </td>\r\n }\r\n\r\n }\r\n }\r\n }\r\n </tr>\r\n\r\n @if (idList == expandedRows()) {\r\n <tr @fadeInOut>\r\n <td [attr.colspan]=\"columnasRenderizadas().length + (withDetails() ? 1 : 0) + (customActions() ? 1 : 0) + (withCheckbox() ? 1 : 0)\"\r\n class=\"table-blank\">\r\n <div class=\"d-flex flex-column auditoria\">\r\n <span class=\"fw-bold fs-7 text-dark\">Datos de auditor\u00EDa</span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Creaci\u00F3n: {{ row.nomucreac }} el {{ row._format?.fcreac ?? row.fcreac }} a las {{\r\n row.hcreac }}\r\n </span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Actualizaci\u00F3n: {{ row.nomuactua }} el {{ row._format?.factua ?? row.factua }} a las\r\n {{\r\n row.hactua }}\r\n </span>\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n\r\n }\r\n\r\n <!-- Fila vac\u00EDa si no hay datos -->\r\n @if (rowFilter().length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columnasRenderizadas().length\" class=\"ll-empty\">\r\n Sin datos\r\n </td>\r\n </tr>\r\n }\r\n\r\n <!-- Spacer inferior: ocupa el espacio de las filas NO renderizadas abajo -->\r\n @if (paddingBottom() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n </tbody>\r\n\r\n <!-- \u2500\u2500 FOOTER 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 -->\r\n @if (withTotal() && rowFilter().length > 0) {\r\n <tfoot class=\"ll-tfoot\">\r\n\r\n <tr>\r\n <td [attr.colspan]=\"getColspanBeforeTotals()\" class=\"fw-5 fs-6 ps-2 py-2\">Totales:</td>\r\n @for (col of columnasRenderizadas() ; track col.fieldname) {\r\n @if (col.totalizable) {\r\n <td class=\"ll-footer-cell fw-5 text-end fs-6\">\r\n {{ getTotals(col.fieldname)}}\r\n </td>\r\n }\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n</ng-template>", 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);padding:12px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}:host(.ll-variant--modern) .ll-sort-idle{opacity:.4;color:#1e293b}:host(.ll-variant--modern) .icon-table{color:#5e5959!important;font-size:12px!important}:host(.ll-variant--modern) .ll-row{transition:background-color .1s ease}:host(.ll-variant--modern) .ll-row:nth-child(odd){background-color:#fff}:host(.ll-variant--modern) .ll-row:nth-child(2n){background-color:#f0f0f0}:host(.ll-variant--modern) .ll-row:hover:not(.ll-row--selected){background-color:#ebebeb!important}:host(.ll-variant--modern) .ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important;box-shadow:inset 4px 0 #334155}:host(.ll-variant--modern) .ll-row--drag-over{background-color:#5b8dee14!important;outline:2px dashed rgba(91,141,238,.5);outline-offset:-2px}:host(.ll-variant--modern) .ll-row td{border-left:none;border-right:none;border-top:none;border-bottom:1px solid rgba(0,0,0,.1);height:40px}:host(.ll-variant--modern) .ll-row td:hover{background-color:#292a2c09!important;border-bottom:1px solid rgb(133,133,133)}:host(.ll-variant--modern) .ll-tfoot tr td:first-child{border-bottom-left-radius:10px}:host(.ll-variant--modern) .ll-tfoot tr td:last-child{border-bottom-right-radius:10px}:host(.ll-variant--modern) .ll-tfoot .ll-footer-cell{background-color:var(--background-card);color:var(--text-color);border:none;border-top:1px solid rgba(0,0,0,.08);padding:10px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-empty{padding:28px;color:#9ca3af;font-size:13px}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:8px;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:4px;overflow-anchor:none}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3;background-color:var(--background-header-table)}.ll-thead tr th{font-size:11px;font-weight:700;color:var(--text-color);text-align:start;padding:6px 8px;border:var(--border-table-header);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:var(--background-header-table);box-shadow:0 2px 2px -1px #0000001a}.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:2px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.25}.ll-tfoot{position:sticky;bottom:0;z-index:3;background-color:var(--background-card)}.ll-tfoot .ll-footer-cell{font-size:11px;color:var(--text-color);padding:10px 8px;border:var(--border-table-header);background-color:var(--background-card);box-shadow:0 -2px 2px -1px #0000001a}.ll-row{height:30px;cursor:pointer}.ll-row:nth-child(odd){background-color:#00000010}.ll-row:hover{background-color:#00000015}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--drag-over{background-color:#5b8dee1f!important;outline:2px dashed #5b8dee;outline-offset:-2px;cursor:copy}.ll-row--drag-over td{color:#5b8dee!important}.ll-row td{font-size:11px;font-weight:500;color:var(--text-color);vertical-align:middle;padding:0 8px;border:var(--border-table-header);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:16px;color:#6c757d;font-size:12px}@media (max-width: 1600px){.ll-thead tr th,.ll-row td,.ll-tfoot .ll-footer-cell{font-size:9px}}.popover-menu-column{position:absolute;top:100%;left:0;right:auto;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:min(500px,80vh);width:min(400px,100vw - 2rem);max-width:calc(80vw - 2rem);overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.6rem .75rem;border-bottom:1px solid #c4c4c4;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}.column-config-hint{font-size:10px;font-weight:400;text-transform:none;color:#9aa3ac}.column-config-list{display:flex;flex-direction:column;gap:3px;padding:4px 0 2px}.column-config-row{display:flex;align-items:center;gap:8px;padding:4px 6px;background:#fff;border:1px solid transparent;border-radius:6px;transition:background-color .15s ease,border-color .15s ease}.column-config-row:hover{background:#f6f7f8}.column-config-grip{cursor:grab;color:#adb5bd;font-size:13px;flex:none}.column-config-grip:active{cursor:grabbing}.column-config-row.cdk-drag-preview{box-shadow:0 10px 24px -8px #00000059;border:1px solid #e5e5e5;border-radius:6px;background:#fff;transform:rotate(-1.5deg)}.column-config-row.cdk-drag-placeholder{border:1.5px dashed #6c757d;border-radius:6px;background:#f1f3f5;opacity:.7}.column-config-row.cdk-drag-placeholder *{visibility:hidden}.column-config-list.cdk-drop-list-dragging .column-config-row:not(.cdk-drag-placeholder){transition:transform .2s cubic-bezier(0,0,.2,1)}.column-config-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;position:sticky;bottom:0;background:#fff;border-top:1px solid #e5e5e5;margin:6px -.75rem 0;padding:8px .75rem}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.column-config-save{border-radius:6px;border:1px solid rgba(0,0,0,.12);background-color:#fff;color:#272727;padding:4px 12px;box-shadow:0 1px 2px #0000000f;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease}.column-config-save:hover{background-color:#334155;border-color:#0003;color:#fff;box-shadow:0 2px 6px #00000026}.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}.table-blank{background:var(--background-card)}.auditoria{padding-left:35px;padding-top:8px;padding-bottom:10px}.cw-25{min-width:40px}\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"] }, { kind: "component", type: CardMobileComponent, selector: "app-card-mobile", inputs: ["data", "columns", "identifier", "titleTabla", "actions", "altoContainer", "rendered"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }], animations: [fadeInOut, dropdownAnimation] });
|
|
4147
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TableUltimateComponent, isStandalone: true, selector: "app-table-ultimate", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, footerRows: { classPropertyName: "footerRows", publicName: "footerRows", 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 }, withDetails: { classPropertyName: "withDetails", publicName: "withDetails", isSignal: true, isRequired: false, transformFunction: null }, withCheckbox: { classPropertyName: "withCheckbox", publicName: "withCheckbox", isSignal: true, isRequired: false, transformFunction: null }, withTotal: { classPropertyName: "withTotal", publicName: "withTotal", isSignal: true, isRequired: false, transformFunction: null }, withHeight: { classPropertyName: "withHeight", publicName: "withHeight", isSignal: true, isRequired: false, transformFunction: null }, withAttachment: { classPropertyName: "withAttachment", publicName: "withAttachment", isSignal: true, isRequired: false, transformFunction: null }, variante: { classPropertyName: "variante", publicName: "variante", isSignal: true, isRequired: false, transformFunction: null }, rendered: { classPropertyName: "rendered", publicName: "rendered", isSignal: true, isRequired: false, transformFunction: null }, titleTabla: { classPropertyName: "titleTabla", publicName: "titleTabla", isSignal: true, isRequired: false, transformFunction: null }, activeMobileMode: { classPropertyName: "activeMobileMode", publicName: "activeMobileMode", isSignal: true, isRequired: false, transformFunction: null }, selectedRow: { classPropertyName: "selectedRow", publicName: "selectedRow", isSignal: true, isRequired: false, transformFunction: null }, rowClassFn: { classPropertyName: "rowClassFn", publicName: "rowClassFn", isSignal: true, isRequired: false, transformFunction: null }, rowDisabledFn: { classPropertyName: "rowDisabledFn", publicName: "rowDisabledFn", isSignal: true, isRequired: false, transformFunction: null }, selectItems: { classPropertyName: "selectItems", publicName: "selectItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowEvent: "rowEvent", selectedRow: "selectedRowChange", selectItems: "selectItemsChange" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "class.ll-variant--modern": "variante() === \"modern\"" } }, queries: [{ propertyName: "customActions", first: true, predicate: ["customActions"], descendants: true, isSignal: true }, { propertyName: "columnDefs", predicate: TsiColumnDefDirective, isSignal: true }, { propertyName: "contentFilter", first: true, predicate: ["header"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (withFiltro()) {\r\n<div class=\"ll-search-bar\">\r\n\r\n <div class=\"ll-search-bar__left\">\r\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\r\n </div>\r\n\r\n <div class=\"ll-search-bar__right\">\r\n\r\n <div class=\"ll-search-group\">\r\n\r\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\r\n <div class=\"ll-search-input-wrap\">\r\n\r\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\" [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn btn-dark boton-buscar fs-7\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n\r\n <ng-template #content>\r\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white\">\r\n Filtros\r\n </div>\r\n\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\r\n (change)=\"toggleFiltros($event)\" id=\"filter_table_lazy_todos\" />\r\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\"\r\n for=\"filter_table_lazy_todos\">\r\n Todos\r\n </label>\r\n </div>\r\n\r\n @for (col of columns(); track col.caption) {\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'filter_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\r\n for=\"{{ 'filter_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n\r\n</div>\r\n}\r\n\r\n@if (activeMobileMode()) {\r\n@if (isLoadingResponsive()) {\r\n<div class=\"d-flex flex-column justify-content-center align-items-center py-2\">\r\n <div class=\"spinner-border text-secondary mb-2\" role=\"status\"></div>\r\n <span class=\"ms-2 fs-6\">Cargando...</span>\r\n</div>\r\n}\r\n\r\n@if (!isLoadingResponsive()) {\r\n@if (isMobile()) {\r\n<app-card-mobile [data]=\"rowFilter()\" [columns]=\"columns()\" [actions]=\"customActions()\" [identifier]=\"identifier()\"\r\n [titleTabla]=\"titleTabla()\" [altoContainer]=\"altoContainer()\" />\r\n}\r\n@if (!isMobile()) {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n}\r\n}\r\n@else {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n\r\n<ng-template #table>\r\n <!-- Contenedor scrolleable \u2014 solo el BODY hace scroll; header y footer son sticky -->\r\n <div #scrollContainer class=\"ll-scroll-container\"\r\n [style.height]=\"withHeight() ? heightStyle() : ''\"\r\n [style.max-height]=\"heightStyle()\" (scroll)=\"onScroll($event)\">\r\n <table class=\"ll-table\">\r\n\r\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 -->\r\n <thead class=\"ll-thead\">\r\n <tr>\r\n @if (withDetails()) {\r\n <th class=\"cw-25\"></th>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <th class=\"cw-20\">\r\n <label>\r\n <input type=\"checkbox\" name=\"check_box_select_table_main\" id=\"check_box_select_table_main\"\r\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\r\n </label>\r\n </th>\r\n }\r\n\r\n @if (customActions()) {\r\n <th class=\"cw-40\">\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn p-0 text-dark d-flex mx-auto border-0 icon-table\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n <ng-template #content>\r\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white d-flex align-items-baseline justify-content-between\">\r\n <span>Columnas</span>\r\n <span class=\"column-config-hint\">arrastra para ordenar</span>\r\n </div>\r\n\r\n <div cdkDropList class=\"column-config-list\" (cdkDropListDropped)=\"onColumnDrop($event)\">\r\n @for (col of columnasConfigurables(); track col.fieldname) {\r\n <div class=\"column-config-row\" cdkDrag>\r\n <i class=\"fas fa-grip-vertical column-config-grip\" cdkDragHandle></i>\r\n <div class=\"form-check form-switch text-start d-flex align-items-center mb-0 flex-grow-1\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'switch_' + col.caption }}\"\r\n [checked]=\"isColumnVisible(col.fieldname)\"\r\n (change)=\"toggleColumnVisible(col.fieldname, $event)\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\r\n for=\"{{ 'switch_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"column-config-footer\">\r\n <!-- <button type=\"button\" class=\"btn btn-link btn-sm p-0 text-secondary fs-7\"\r\n (click)=\"restablecerConfiguracionColumnas()\">\r\n Restablecer\r\n </button> -->\r\n <button type=\"button\" class=\"btn btn-sm fs-7 column-config-save\"\r\n (click)=\"guardarConfiguracionColumnas()\">\r\n Guardar configuraci\u00F3n\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n </th>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\r\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\r\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\r\n <span class=\"ll-th-content\">\r\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\r\n @if (sortField() === col.fieldname) {\r\n <i class=\"ms-1\"\r\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6':'fas fa-angle-down fs-6'\"></i>\r\n } @else {\r\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\r\n }\r\n </span>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\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 -->\r\n <tbody>\r\n <!-- Spacer superior: ocupa el espacio de las filas NO renderizadas arriba -->\r\n @if (paddingTop() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n\r\n <!-- Filas visibles -->\r\n @for (row of visibleRows(); track row.idListTsi) {\r\n @let idList = row.idListTsi;\r\n <tr class=\"ll-row\" [class.ll-row--selected]=\"isSelected(row, idList)\"\r\n [class.ll-row--drag-over]=\"withAttachment() && dragOverRowId() === idList\"\r\n (click)=\"selectRow(row, idList)\" (dblclick)=\"onDoubleClick(row)\"\r\n (contextmenu)=\"onRightClick($event,row)\"\r\n (dragover)=\"withAttachment() && onDragOver($event, idList)\"\r\n (dragleave)=\"withAttachment() && onDragLeave()\" (drop)=\"withAttachment() && onDrop($event, row)\">\r\n\r\n @if (withDetails()) {\r\n <td class=\"b-table text-center mwp-25\">\r\n <a (click)=\"toggleExpandRow(idList)\" class=\"text-dark cursor-pointer fs-6\">\r\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"expandedRows() != idList\"\r\n [class.fa-chevron-down]=\"expandedRows() == idList\"></i>\r\n </a>\r\n </td>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <td scope=\"col\" class=\"text-center b-table\">\r\n <label>\r\n <input type=\"checkbox\" [name]=\"'check_box_select_table_' + idList\"\r\n [id]=\"'check_box_select_table_' + idList\" animatedCheckbox\r\n [checked]=\"isItemSelected(idList)\" (click)=\"$event.stopPropagation()\"\r\n (change)=\"toogleItem(idList , $event)\" [disabled]=\"isCheckboxDisabled(row)\">\r\n </label>\r\n </td>\r\n }\r\n\r\n @if (customActions()) {\r\n <td class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row }\"></ng-container>\r\n </td>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n @if (columnDefMap().has(col.fieldname)) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else if (col.template) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else {\r\n @switch (col.tipo) {\r\n\r\n @case ('cell-render') {\r\n @let resolverItem = resolveCell(col.fieldname, row);\r\n @if (resolverItem) {\r\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\r\n @if (resolverItem.icon) {\r\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\r\n } @else if (resolverItem.class) {\r\n <span [ngClass]=\"row.situac == 'J' ? 'text-error' : resolverItem.class\">\r\n {{ resolverItem.text }}\r\n </span>\r\n } @else {\r\n {{ resolverItem.text }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @default {\r\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\r\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [attr.title]=\"row[col.fieldname] || null\"\r\n [ngClass]=\"rowClassFn() ? rowClassFn()(row) : getRowClass(row)\" class=\"{{getPosition(col)}}\">\r\n </td>\r\n }\r\n\r\n }\r\n }\r\n }\r\n </tr>\r\n\r\n @if (idList == expandedRows()) {\r\n <tr @fadeInOut>\r\n <td [attr.colspan]=\"columnasRenderizadas().length + (withDetails() ? 1 : 0) + (customActions() ? 1 : 0) + (withCheckbox() ? 1 : 0)\"\r\n class=\"table-blank\">\r\n <div class=\"d-flex flex-column auditoria\">\r\n <span class=\"fw-bold fs-7 text-dark\">Datos de auditor\u00EDa</span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Creaci\u00F3n: {{ row.nomucreac }} el {{ row._format?.fcreac ?? row.fcreac }} a las {{\r\n row.hcreac }}\r\n </span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Actualizaci\u00F3n: {{ row.nomuactua }} el {{ row._format?.factua ?? row.factua }} a las\r\n {{\r\n row.hactua }}\r\n </span>\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n\r\n }\r\n\r\n <!-- Fila vac\u00EDa si no hay datos -->\r\n @if (rowFilter().length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columnasRenderizadas().length\" class=\"ll-empty\">\r\n Sin datos\r\n </td>\r\n </tr>\r\n }\r\n\r\n <!-- Spacer inferior: ocupa el espacio de las filas NO renderizadas abajo -->\r\n @if (paddingBottom() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n </tbody>\r\n\r\n <!-- \u2500\u2500 FOOTER 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 -->\r\n @if (withTotal() && rowFilter().length > 0) {\r\n <tfoot class=\"ll-tfoot\">\r\n\r\n <tr>\r\n <td [attr.colspan]=\"getColspanBeforeTotals()\" class=\"ll-footer-cell fw-5 fs-6 ps-2 py-2\">Totales:</td>\r\n @for (col of columnasRenderizadas() ; track col.fieldname) {\r\n @if (col.totalizable) {\r\n <td class=\"ll-footer-cell fw-5 text-end fs-6\">\r\n {{ getTotals(col.fieldname)}}\r\n </td>\r\n }\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n</ng-template>", 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);padding:12px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}:host(.ll-variant--modern) .ll-sort-idle{opacity:.4;color:#1e293b}:host(.ll-variant--modern) .icon-table{color:#5e5959!important;font-size:12px!important}:host(.ll-variant--modern) .ll-row{transition:background-color .1s ease}:host(.ll-variant--modern) .ll-row:nth-child(odd){background-color:#fff}:host(.ll-variant--modern) .ll-row:nth-child(2n){background-color:#f0f0f0}:host(.ll-variant--modern) .ll-row:hover:not(.ll-row--selected){background-color:#ebebeb!important}:host(.ll-variant--modern) .ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important;box-shadow:inset 4px 0 #334155}:host(.ll-variant--modern) .ll-row--drag-over{background-color:#5b8dee14!important;outline:2px dashed rgba(91,141,238,.5);outline-offset:-2px}:host(.ll-variant--modern) .ll-row td{border-left:none;border-right:none;border-top:none;border-bottom:1px solid rgba(0,0,0,.1);height:40px}:host(.ll-variant--modern) .ll-row td:hover{background-color:#292a2c09!important;border-bottom:1px solid rgb(133,133,133)}:host(.ll-variant--modern) .ll-tfoot tr td:first-child{border-bottom-left-radius:10px}:host(.ll-variant--modern) .ll-tfoot tr td:last-child{border-bottom-right-radius:10px}:host(.ll-variant--modern) .ll-tfoot .ll-footer-cell{background-color:var(--background-card);color:var(--text-color);border:none;border-top:1px solid rgba(0,0,0,.08);padding:10px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-empty{padding:28px;color:#9ca3af;font-size:13px}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:8px;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:4px;overflow-anchor:none}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3;background-color:var(--background-header-table)}.ll-thead tr th{font-size:11px;font-weight:700;color:var(--text-color);text-align:start;padding:6px 8px;border:var(--border-table-header);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:var(--background-header-table);box-shadow:0 2px 2px -1px #0000001a}.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:2px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.25}.ll-tfoot{position:sticky;bottom:0;z-index:3;background-color:var(--background-card)}.ll-tfoot .ll-footer-cell{font-size:11px;color:var(--text-color);padding:10px 8px;border:var(--border-table-header);background-color:var(--background-card);box-shadow:0 -2px 2px -1px #0000001a}.ll-row{height:30px;cursor:pointer}.ll-row:nth-child(odd){background-color:#00000010}.ll-row:hover{background-color:#00000015}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--drag-over{background-color:#5b8dee1f!important;outline:2px dashed #5b8dee;outline-offset:-2px;cursor:copy}.ll-row--drag-over td{color:#5b8dee!important}.ll-row td{font-size:11px;font-weight:500;color:var(--text-color);vertical-align:middle;padding:0 8px;border:var(--border-table-header);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:16px;color:#6c757d;font-size:12px}@media (max-width: 1600px){.ll-thead tr th,.ll-row td,.ll-tfoot .ll-footer-cell{font-size:9px}}.popover-menu-column{position:absolute;top:100%;left:0;right:auto;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:min(500px,80vh);width:min(400px,100vw - 2rem);max-width:calc(80vw - 2rem);overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.6rem .75rem;border-bottom:1px solid #c4c4c4;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}.column-config-hint{font-size:10px;font-weight:400;text-transform:none;color:#9aa3ac}.column-config-list{display:flex;flex-direction:column;gap:3px;padding:4px 0 2px}.column-config-row{display:flex;align-items:center;gap:8px;padding:4px 6px;background:#fff;border:1px solid transparent;border-radius:6px;transition:background-color .15s ease,border-color .15s ease}.column-config-row:hover{background:#f6f7f8}.column-config-grip{cursor:grab;color:#adb5bd;font-size:13px;flex:none}.column-config-grip:active{cursor:grabbing}.column-config-row.cdk-drag-preview{box-shadow:0 10px 24px -8px #00000059;border:1px solid #e5e5e5;border-radius:6px;background:#fff;transform:rotate(-1.5deg)}.column-config-row.cdk-drag-placeholder{border:1.5px dashed #6c757d;border-radius:6px;background:#f1f3f5;opacity:.7}.column-config-row.cdk-drag-placeholder *{visibility:hidden}.column-config-list.cdk-drop-list-dragging .column-config-row:not(.cdk-drag-placeholder){transition:transform .2s cubic-bezier(0,0,.2,1)}.column-config-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;position:sticky;bottom:0;background:#fff;border-top:1px solid #e5e5e5;margin:6px -.75rem 0;padding:8px .75rem}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.column-config-save{border-radius:6px;border:1px solid rgba(0,0,0,.12);background-color:#fff;color:#272727;padding:4px 12px;box-shadow:0 1px 2px #0000000f;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease}.column-config-save:hover{background-color:#334155;border-color:#0003;color:#fff;box-shadow:0 2px 6px #00000026}.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}.table-blank{background:var(--background-card)}.auditoria{padding-left:35px;padding-top:8px;padding-bottom:10px}.cw-25{min-width:40px}\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"] }, { kind: "component", type: CardMobileComponent, selector: "app-card-mobile", inputs: ["data", "columns", "identifier", "titleTabla", "actions", "altoContainer", "rendered"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }], animations: [fadeInOut, dropdownAnimation] });
|
|
4133
4148
|
}
|
|
4134
4149
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TableUltimateComponent, decorators: [{
|
|
4135
4150
|
type: Component,
|
|
4136
4151
|
args: [{ selector: 'app-table-ultimate', imports: [FormsModule, CommonModule, DropdownCdkComponent, AnimatedCheckboxDirective, CardMobileComponent, NgTemplateOutlet, CdkDropList, CdkDrag, CdkDragHandle], animations: [fadeInOut, dropdownAnimation], host: {
|
|
4137
4152
|
'[class.ll-variant--modern]': 'variante() === "modern"'
|
|
4138
|
-
}, template: "@if (withFiltro()) {\r\n<div class=\"ll-search-bar\">\r\n\r\n <div class=\"ll-search-bar__left\">\r\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\r\n </div>\r\n\r\n <div class=\"ll-search-bar__right\">\r\n\r\n <div class=\"ll-search-group\">\r\n\r\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\r\n <div class=\"ll-search-input-wrap\">\r\n\r\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\" [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn btn-dark boton-buscar fs-7\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n\r\n <ng-template #content>\r\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white\">\r\n Filtros\r\n </div>\r\n\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\r\n (change)=\"toggleFiltros($event)\" id=\"filter_table_lazy_todos\" />\r\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\"\r\n for=\"filter_table_lazy_todos\">\r\n Todos\r\n </label>\r\n </div>\r\n\r\n @for (col of columns(); track col.caption) {\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'filter_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\r\n for=\"{{ 'filter_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n\r\n</div>\r\n}\r\n\r\n@if (activeMobileMode()) {\r\n@if (isLoadingResponsive()) {\r\n<div class=\"d-flex flex-column justify-content-center align-items-center py-2\">\r\n <div class=\"spinner-border text-secondary mb-2\" role=\"status\"></div>\r\n <span class=\"ms-2 fs-6\">Cargando...</span>\r\n</div>\r\n}\r\n\r\n@if (!isLoadingResponsive()) {\r\n@if (isMobile()) {\r\n<app-card-mobile [data]=\"rowFilter()\" [columns]=\"columns()\" [actions]=\"customActions()\" [identifier]=\"identifier()\"\r\n [titleTabla]=\"titleTabla()\" [altoContainer]=\"altoContainer()\" />\r\n}\r\n@if (!isMobile()) {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n}\r\n}\r\n@else {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n\r\n<ng-template #table>\r\n <!-- Contenedor scrolleable \u2014 solo el BODY hace scroll; header y footer son sticky -->\r\n <div #scrollContainer class=\"ll-scroll-container\"\r\n [style.height]=\"withHeight() ? heightStyle() : ''\"\r\n [style.max-height]=\"heightStyle()\" (scroll)=\"onScroll($event)\">\r\n <table class=\"ll-table\">\r\n\r\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 -->\r\n <thead class=\"ll-thead\">\r\n <tr>\r\n @if (withDetails()) {\r\n <th class=\"cw-25\"></th>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <th class=\"cw-20\">\r\n <label>\r\n <input type=\"checkbox\" name=\"check_box_select_table_main\" id=\"check_box_select_table_main\"\r\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\r\n </label>\r\n </th>\r\n }\r\n\r\n @if (customActions()) {\r\n <th class=\"cw-40\">\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn p-0 text-dark d-flex mx-auto border-0 icon-table\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n <ng-template #content>\r\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white d-flex align-items-baseline justify-content-between\">\r\n <span>Columnas</span>\r\n <span class=\"column-config-hint\">arrastra para ordenar</span>\r\n </div>\r\n\r\n <div cdkDropList class=\"column-config-list\" (cdkDropListDropped)=\"onColumnDrop($event)\">\r\n @for (col of columnasConfigurables(); track col.fieldname) {\r\n <div class=\"column-config-row\" cdkDrag>\r\n <i class=\"fas fa-grip-vertical column-config-grip\" cdkDragHandle></i>\r\n <div class=\"form-check form-switch text-start d-flex align-items-center mb-0 flex-grow-1\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'switch_' + col.caption }}\"\r\n [checked]=\"isColumnVisible(col.fieldname)\"\r\n (change)=\"toggleColumnVisible(col.fieldname, $event)\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\r\n for=\"{{ 'switch_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"column-config-footer\">\r\n <!-- <button type=\"button\" class=\"btn btn-link btn-sm p-0 text-secondary fs-7\"\r\n (click)=\"restablecerConfiguracionColumnas()\">\r\n Restablecer\r\n </button> -->\r\n <button type=\"button\" class=\"btn btn-sm fs-7 column-config-save\"\r\n (click)=\"guardarConfiguracionColumnas()\">\r\n Guardar configuraci\u00F3n\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n </th>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\r\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\r\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\r\n <span class=\"ll-th-content\">\r\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\r\n @if (sortField() === col.fieldname) {\r\n <i class=\"ms-1\"\r\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6':'fas fa-angle-down fs-6'\"></i>\r\n } @else {\r\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\r\n }\r\n </span>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\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 -->\r\n <tbody>\r\n <!-- Spacer superior: ocupa el espacio de las filas NO renderizadas arriba -->\r\n @if (paddingTop() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n\r\n <!-- Filas visibles -->\r\n @for (row of visibleRows(); track row.idListTsi) {\r\n @let idList = row.idListTsi;\r\n <tr class=\"ll-row\" [class.ll-row--selected]=\"isSelected(row, idList)\"\r\n [class.ll-row--drag-over]=\"withAttachment() && dragOverRowId() === idList\"\r\n (click)=\"selectRow(row, idList)\" (dblclick)=\"onDoubleClick(row)\"\r\n (contextmenu)=\"onRightClick($event,row)\"\r\n (dragover)=\"withAttachment() && onDragOver($event, idList)\"\r\n (dragleave)=\"withAttachment() && onDragLeave()\" (drop)=\"withAttachment() && onDrop($event, row)\">\r\n\r\n @if (withDetails()) {\r\n <td class=\"b-table text-center mwp-25\">\r\n <a (click)=\"toggleExpandRow(idList)\" class=\"text-dark cursor-pointer fs-6\">\r\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"expandedRows() != idList\"\r\n [class.fa-chevron-down]=\"expandedRows() == idList\"></i>\r\n </a>\r\n </td>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <td scope=\"col\" class=\"text-center b-table\">\r\n <label>\r\n <input type=\"checkbox\" [name]=\"'check_box_select_table_' + idList\"\r\n [id]=\"'check_box_select_table_' + idList\" animatedCheckbox\r\n [checked]=\"isItemSelected(idList)\" (click)=\"$event.stopPropagation()\"\r\n (change)=\"toogleItem(idList , $event)\" [disabled]=\"isCheckboxDisabled(row)\">\r\n </label>\r\n </td>\r\n }\r\n\r\n @if (customActions()) {\r\n <td class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row }\"></ng-container>\r\n </td>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n @if (columnDefMap().has(col.fieldname)) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else if (col.template) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else {\r\n @switch (col.tipo) {\r\n\r\n @case ('cell-render') {\r\n @let resolverItem = resolveCell(col.fieldname, row);\r\n @if (resolverItem) {\r\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\r\n @if (resolverItem.icon) {\r\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\r\n } @else if (resolverItem.class) {\r\n <span [ngClass]=\"row.situac == 'J' ? 'text-error' : resolverItem.class\">\r\n {{ resolverItem.text }}\r\n </span>\r\n } @else {\r\n {{ resolverItem.text }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @default {\r\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\r\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [attr.title]=\"row[col.fieldname] || null\"\r\n [ngClass]=\"rowClassFn() ? rowClassFn()(row) : getRowClass(row)\" class=\"{{getPosition(col)}}\">\r\n </td>\r\n }\r\n\r\n }\r\n }\r\n }\r\n </tr>\r\n\r\n @if (idList == expandedRows()) {\r\n <tr @fadeInOut>\r\n <td [attr.colspan]=\"columnasRenderizadas().length + (withDetails() ? 1 : 0) + (customActions() ? 1 : 0) + (withCheckbox() ? 1 : 0)\"\r\n class=\"table-blank\">\r\n <div class=\"d-flex flex-column auditoria\">\r\n <span class=\"fw-bold fs-7 text-dark\">Datos de auditor\u00EDa</span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Creaci\u00F3n: {{ row.nomucreac }} el {{ row._format?.fcreac ?? row.fcreac }} a las {{\r\n row.hcreac }}\r\n </span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Actualizaci\u00F3n: {{ row.nomuactua }} el {{ row._format?.factua ?? row.factua }} a las\r\n {{\r\n row.hactua }}\r\n </span>\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n\r\n }\r\n\r\n <!-- Fila vac\u00EDa si no hay datos -->\r\n @if (rowFilter().length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columnasRenderizadas().length\" class=\"ll-empty\">\r\n Sin datos\r\n </td>\r\n </tr>\r\n }\r\n\r\n <!-- Spacer inferior: ocupa el espacio de las filas NO renderizadas abajo -->\r\n @if (paddingBottom() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n </tbody>\r\n\r\n <!-- \u2500\u2500 FOOTER 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 -->\r\n @if (withTotal() && rowFilter().length > 0) {\r\n <tfoot class=\"ll-tfoot\">\r\n\r\n <tr>\r\n <td [attr.colspan]=\"getColspanBeforeTotals()\" class=\"fw-5 fs-6 ps-2 py-2\">Totales:</td>\r\n @for (col of columnasRenderizadas() ; track col.fieldname) {\r\n @if (col.totalizable) {\r\n <td class=\"ll-footer-cell fw-5 text-end fs-6\">\r\n {{ getTotals(col.fieldname)}}\r\n </td>\r\n }\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n</ng-template>", 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);padding:12px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}:host(.ll-variant--modern) .ll-sort-idle{opacity:.4;color:#1e293b}:host(.ll-variant--modern) .icon-table{color:#5e5959!important;font-size:12px!important}:host(.ll-variant--modern) .ll-row{transition:background-color .1s ease}:host(.ll-variant--modern) .ll-row:nth-child(odd){background-color:#fff}:host(.ll-variant--modern) .ll-row:nth-child(2n){background-color:#f0f0f0}:host(.ll-variant--modern) .ll-row:hover:not(.ll-row--selected){background-color:#ebebeb!important}:host(.ll-variant--modern) .ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important;box-shadow:inset 4px 0 #334155}:host(.ll-variant--modern) .ll-row--drag-over{background-color:#5b8dee14!important;outline:2px dashed rgba(91,141,238,.5);outline-offset:-2px}:host(.ll-variant--modern) .ll-row td{border-left:none;border-right:none;border-top:none;border-bottom:1px solid rgba(0,0,0,.1);height:40px}:host(.ll-variant--modern) .ll-row td:hover{background-color:#292a2c09!important;border-bottom:1px solid rgb(133,133,133)}:host(.ll-variant--modern) .ll-tfoot tr td:first-child{border-bottom-left-radius:10px}:host(.ll-variant--modern) .ll-tfoot tr td:last-child{border-bottom-right-radius:10px}:host(.ll-variant--modern) .ll-tfoot .ll-footer-cell{background-color:var(--background-card);color:var(--text-color);border:none;border-top:1px solid rgba(0,0,0,.08);padding:10px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-empty{padding:28px;color:#9ca3af;font-size:13px}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:8px;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:4px;overflow-anchor:none}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3;background-color:var(--background-header-table)}.ll-thead tr th{font-size:11px;font-weight:700;color:var(--text-color);text-align:start;padding:6px 8px;border:var(--border-table-header);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:var(--background-header-table);box-shadow:0 2px 2px -1px #0000001a}.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:2px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.25}.ll-tfoot{position:sticky;bottom:0;z-index:3;background-color:var(--background-card)}.ll-tfoot .ll-footer-cell{font-size:11px;color:var(--text-color);padding:10px 8px;border:var(--border-table-header);background-color:var(--background-card);box-shadow:0 -2px 2px -1px #0000001a}.ll-row{height:30px;cursor:pointer}.ll-row:nth-child(odd){background-color:#00000010}.ll-row:hover{background-color:#00000015}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--drag-over{background-color:#5b8dee1f!important;outline:2px dashed #5b8dee;outline-offset:-2px;cursor:copy}.ll-row--drag-over td{color:#5b8dee!important}.ll-row td{font-size:11px;font-weight:500;color:var(--text-color);vertical-align:middle;padding:0 8px;border:var(--border-table-header);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:16px;color:#6c757d;font-size:12px}@media (max-width: 1600px){.ll-thead tr th,.ll-row td,.ll-tfoot .ll-footer-cell{font-size:9px}}.popover-menu-column{position:absolute;top:100%;left:0;right:auto;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:min(500px,80vh);width:min(400px,100vw - 2rem);max-width:calc(80vw - 2rem);overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.6rem .75rem;border-bottom:1px solid #c4c4c4;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}.column-config-hint{font-size:10px;font-weight:400;text-transform:none;color:#9aa3ac}.column-config-list{display:flex;flex-direction:column;gap:3px;padding:4px 0 2px}.column-config-row{display:flex;align-items:center;gap:8px;padding:4px 6px;background:#fff;border:1px solid transparent;border-radius:6px;transition:background-color .15s ease,border-color .15s ease}.column-config-row:hover{background:#f6f7f8}.column-config-grip{cursor:grab;color:#adb5bd;font-size:13px;flex:none}.column-config-grip:active{cursor:grabbing}.column-config-row.cdk-drag-preview{box-shadow:0 10px 24px -8px #00000059;border:1px solid #e5e5e5;border-radius:6px;background:#fff;transform:rotate(-1.5deg)}.column-config-row.cdk-drag-placeholder{border:1.5px dashed #6c757d;border-radius:6px;background:#f1f3f5;opacity:.7}.column-config-row.cdk-drag-placeholder *{visibility:hidden}.column-config-list.cdk-drop-list-dragging .column-config-row:not(.cdk-drag-placeholder){transition:transform .2s cubic-bezier(0,0,.2,1)}.column-config-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;position:sticky;bottom:0;background:#fff;border-top:1px solid #e5e5e5;margin:6px -.75rem 0;padding:8px .75rem}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.column-config-save{border-radius:6px;border:1px solid rgba(0,0,0,.12);background-color:#fff;color:#272727;padding:4px 12px;box-shadow:0 1px 2px #0000000f;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease}.column-config-save:hover{background-color:#334155;border-color:#0003;color:#fff;box-shadow:0 2px 6px #00000026}.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}.table-blank{background:var(--background-card)}.auditoria{padding-left:35px;padding-top:8px;padding-bottom:10px}.cw-25{min-width:40px}\n"] }]
|
|
4153
|
+
}, template: "@if (withFiltro()) {\r\n<div class=\"ll-search-bar\">\r\n\r\n <div class=\"ll-search-bar__left\">\r\n <ng-container *ngTemplateOutlet=\"contentFilter();\"></ng-container>\r\n </div>\r\n\r\n <div class=\"ll-search-bar__right\">\r\n\r\n <div class=\"ll-search-group\">\r\n\r\n <label class=\"form-label mb-0 ll-search-label\">Buscar:</label>\r\n <div class=\"ll-search-input-wrap\">\r\n\r\n <input type=\"text\" class=\"form-control cw-250\" placeholder=\"Buscar...\" [value]=\"busqueda()\" (input)=\"textoDigitado($event)\" />\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn btn-dark boton-buscar fs-7\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n\r\n <ng-template #content>\r\n <div class=\"popover-menu-filter bg-white shadow\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white\">\r\n Filtros\r\n </div>\r\n\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input class=\"form-check-input py-0 my-0 cw-25 ch-15\" type=\"checkbox\" [checked]=\"true\"\r\n (change)=\"toggleFiltros($event)\" id=\"filter_table_lazy_todos\" />\r\n <label class=\"form-check-label ps-2 fs-6 mb-0 cursor-pointer\"\r\n for=\"filter_table_lazy_todos\">\r\n Todos\r\n </label>\r\n </div>\r\n\r\n @for (col of columns(); track col.caption) {\r\n <div class=\"form-check form-switch text-start d-flex align-items-center\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'filter_' + col.caption }}\" [(ngModel)]=\"filtrarColumnas()[col.fieldname]\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer mb-0\"\r\n for=\"{{ 'filter_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n\r\n</div>\r\n}\r\n\r\n@if (activeMobileMode()) {\r\n@if (isLoadingResponsive()) {\r\n<div class=\"d-flex flex-column justify-content-center align-items-center py-2\">\r\n <div class=\"spinner-border text-secondary mb-2\" role=\"status\"></div>\r\n <span class=\"ms-2 fs-6\">Cargando...</span>\r\n</div>\r\n}\r\n\r\n@if (!isLoadingResponsive()) {\r\n@if (isMobile()) {\r\n<app-card-mobile [data]=\"rowFilter()\" [columns]=\"columns()\" [actions]=\"customActions()\" [identifier]=\"identifier()\"\r\n [titleTabla]=\"titleTabla()\" [altoContainer]=\"altoContainer()\" />\r\n}\r\n@if (!isMobile()) {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n}\r\n}\r\n@else {\r\n<ng-container *ngTemplateOutlet=\"table\"></ng-container>\r\n}\r\n\r\n<ng-template #table>\r\n <!-- Contenedor scrolleable \u2014 solo el BODY hace scroll; header y footer son sticky -->\r\n <div #scrollContainer class=\"ll-scroll-container\"\r\n [style.height]=\"withHeight() ? heightStyle() : ''\"\r\n [style.max-height]=\"heightStyle()\" (scroll)=\"onScroll($event)\">\r\n <table class=\"ll-table\">\r\n\r\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 -->\r\n <thead class=\"ll-thead\">\r\n <tr>\r\n @if (withDetails()) {\r\n <th class=\"cw-25\"></th>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <th class=\"cw-20\">\r\n <label>\r\n <input type=\"checkbox\" name=\"check_box_select_table_main\" id=\"check_box_select_table_main\"\r\n animatedCheckbox [checked]=\"validaAllCheck()\" (change)=\"allCheck($event)\">\r\n </label>\r\n </th>\r\n }\r\n\r\n @if (customActions()) {\r\n <th class=\"cw-40\">\r\n <app-dropdown-cdk>\r\n <ng-template #trigger>\r\n <button class=\"btn p-0 text-dark d-flex mx-auto border-0 icon-table\">\r\n <i class=\"fas fa-cog\"></i>\r\n </button>\r\n </ng-template>\r\n <ng-template #content>\r\n <div class=\"popover-menu-column bg-white shadow mt-2\" @dropdownAnimation>\r\n <div class=\"popover-title fs-7 bg-white d-flex align-items-baseline justify-content-between\">\r\n <span>Columnas</span>\r\n <span class=\"column-config-hint\">arrastra para ordenar</span>\r\n </div>\r\n\r\n <div cdkDropList class=\"column-config-list\" (cdkDropListDropped)=\"onColumnDrop($event)\">\r\n @for (col of columnasConfigurables(); track col.fieldname) {\r\n <div class=\"column-config-row\" cdkDrag>\r\n <i class=\"fas fa-grip-vertical column-config-grip\" cdkDragHandle></i>\r\n <div class=\"form-check form-switch text-start d-flex align-items-center mb-0 flex-grow-1\">\r\n <input type=\"checkbox\" class=\"form-check-input py-0 my-0 cw-25 ch-15\"\r\n id=\"{{ 'switch_' + col.caption }}\"\r\n [checked]=\"isColumnVisible(col.fieldname)\"\r\n (change)=\"toggleColumnVisible(col.fieldname, $event)\" />\r\n <label class=\"form-check-label ps-2 fs-6 cursor-pointer font-label mb-0\"\r\n for=\"{{ 'switch_' + col.caption }}\">\r\n {{ col.caption }}\r\n </label>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div class=\"column-config-footer\">\r\n <!-- <button type=\"button\" class=\"btn btn-link btn-sm p-0 text-secondary fs-7\"\r\n (click)=\"restablecerConfiguracionColumnas()\">\r\n Restablecer\r\n </button> -->\r\n <button type=\"button\" class=\"btn btn-sm fs-7 column-config-save\"\r\n (click)=\"guardarConfiguracionColumnas()\">\r\n Guardar configuraci\u00F3n\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </app-dropdown-cdk>\r\n </th>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n <th [title]=\"col.caption\" [style.width.px]=\"col.width || null\"\r\n [style.min-width.px]=\"col.width || null\" [style.max-width.px]=\"col.width || null\"\r\n class=\"ll-th-sortable\" (click)=\"toggleSort(col.fieldname)\">\r\n <span class=\"ll-th-content\">\r\n <span class=\"ll-th-caption\">{{ col.caption }}</span>\r\n @if (sortField() === col.fieldname) {\r\n <i class=\"ms-1\"\r\n [ngClass]=\"sortDir() === 'asc' ? 'fas fa-angle-up fs-6':'fas fa-angle-down fs-6'\"></i>\r\n } @else {\r\n <i class=\"fas fa-sort ms-1 ll-sort-idle\"></i>\r\n }\r\n </span>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\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 -->\r\n <tbody>\r\n <!-- Spacer superior: ocupa el espacio de las filas NO renderizadas arriba -->\r\n @if (paddingTop() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingTop()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n\r\n <!-- Filas visibles -->\r\n @for (row of visibleRows(); track row.idListTsi) {\r\n @let idList = row.idListTsi;\r\n <tr class=\"ll-row\" [class.ll-row--selected]=\"isSelected(row, idList)\"\r\n [class.ll-row--drag-over]=\"withAttachment() && dragOverRowId() === idList\"\r\n (click)=\"selectRow(row, idList)\" (dblclick)=\"onDoubleClick(row)\"\r\n (contextmenu)=\"onRightClick($event,row)\"\r\n (dragover)=\"withAttachment() && onDragOver($event, idList)\"\r\n (dragleave)=\"withAttachment() && onDragLeave()\" (drop)=\"withAttachment() && onDrop($event, row)\">\r\n\r\n @if (withDetails()) {\r\n <td class=\"b-table text-center mwp-25\">\r\n <a (click)=\"toggleExpandRow(idList)\" class=\"text-dark cursor-pointer fs-6\">\r\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"expandedRows() != idList\"\r\n [class.fa-chevron-down]=\"expandedRows() == idList\"></i>\r\n </a>\r\n </td>\r\n }\r\n\r\n @if (withCheckbox()) {\r\n <td scope=\"col\" class=\"text-center b-table\">\r\n <label>\r\n <input type=\"checkbox\" [name]=\"'check_box_select_table_' + idList\"\r\n [id]=\"'check_box_select_table_' + idList\" animatedCheckbox\r\n [checked]=\"isItemSelected(idList)\" (click)=\"$event.stopPropagation()\"\r\n (change)=\"toogleItem(idList , $event)\" [disabled]=\"isCheckboxDisabled(row)\">\r\n </label>\r\n </td>\r\n }\r\n\r\n @if (customActions()) {\r\n <td class=\"text-center\">\r\n <ng-container *ngTemplateOutlet=\"customActions(); context: { $implicit: row }\"></ng-container>\r\n </td>\r\n }\r\n\r\n @for (col of columnasRenderizadas(); track col.fieldname) {\r\n @if (columnDefMap().has(col.fieldname)) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"columnDefMap().get(col.fieldname)!; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else if (col.template) {\r\n <td>\r\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row, column: col }\">\r\n </ng-container>\r\n </td>\r\n } @else {\r\n @switch (col.tipo) {\r\n\r\n @case ('cell-render') {\r\n @let resolverItem = resolveCell(col.fieldname, row);\r\n @if (resolverItem) {\r\n <td [title]=\"resolverItem.text\" [class.text-center]=\"resolverItem.icon\">\r\n @if (resolverItem.icon) {\r\n <i class=\"fs-5\" [ngClass]=\"resolverItem.icon\"></i>\r\n } @else if (resolverItem.class) {\r\n <span [ngClass]=\"row.situac == 'J' ? 'text-error' : resolverItem.class\">\r\n {{ resolverItem.text }}\r\n </span>\r\n } @else {\r\n {{ resolverItem.text }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @default {\r\n <td [innerHTML]=\"getHighlight(row._format?.[col.fieldname] ?? row[col.fieldname], col.fieldname)\"\r\n [style.width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [style.max-width]=\"col.width ? col.width + 'px' : 'auto'\"\r\n [attr.title]=\"row[col.fieldname] || null\"\r\n [ngClass]=\"rowClassFn() ? rowClassFn()(row) : getRowClass(row)\" class=\"{{getPosition(col)}}\">\r\n </td>\r\n }\r\n\r\n }\r\n }\r\n }\r\n </tr>\r\n\r\n @if (idList == expandedRows()) {\r\n <tr @fadeInOut>\r\n <td [attr.colspan]=\"columnasRenderizadas().length + (withDetails() ? 1 : 0) + (customActions() ? 1 : 0) + (withCheckbox() ? 1 : 0)\"\r\n class=\"table-blank\">\r\n <div class=\"d-flex flex-column auditoria\">\r\n <span class=\"fw-bold fs-7 text-dark\">Datos de auditor\u00EDa</span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Creaci\u00F3n: {{ row.nomucreac }} el {{ row._format?.fcreac ?? row.fcreac }} a las {{\r\n row.hcreac }}\r\n </span>\r\n <span class=\"fs-6 text-dark fw-bold\">\r\n Actualizaci\u00F3n: {{ row.nomuactua }} el {{ row._format?.factua ?? row.factua }} a las\r\n {{\r\n row.hactua }}\r\n </span>\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n\r\n }\r\n\r\n <!-- Fila vac\u00EDa si no hay datos -->\r\n @if (rowFilter().length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columnasRenderizadas().length\" class=\"ll-empty\">\r\n Sin datos\r\n </td>\r\n </tr>\r\n }\r\n\r\n <!-- Spacer inferior: ocupa el espacio de las filas NO renderizadas abajo -->\r\n @if (paddingBottom() > 0) {\r\n <tr class=\"ll-spacer\" [style.height.px]=\"paddingBottom()\">\r\n <td [attr.colspan]=\"columnasRenderizadas().length\"></td>\r\n </tr>\r\n }\r\n </tbody>\r\n\r\n <!-- \u2500\u2500 FOOTER 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 -->\r\n @if (withTotal() && rowFilter().length > 0) {\r\n <tfoot class=\"ll-tfoot\">\r\n\r\n <tr>\r\n <td [attr.colspan]=\"getColspanBeforeTotals()\" class=\"ll-footer-cell fw-5 fs-6 ps-2 py-2\">Totales:</td>\r\n @for (col of columnasRenderizadas() ; track col.fieldname) {\r\n @if (col.totalizable) {\r\n <td class=\"ll-footer-cell fw-5 text-end fs-6\">\r\n {{ getTotals(col.fieldname)}}\r\n </td>\r\n }\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n</ng-template>", 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);padding:12px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-th-sortable:hover{background-color:#fff!important}:host(.ll-variant--modern) .ll-sort-idle{opacity:.4;color:#1e293b}:host(.ll-variant--modern) .icon-table{color:#5e5959!important;font-size:12px!important}:host(.ll-variant--modern) .ll-row{transition:background-color .1s ease}:host(.ll-variant--modern) .ll-row:nth-child(odd){background-color:#fff}:host(.ll-variant--modern) .ll-row:nth-child(2n){background-color:#f0f0f0}:host(.ll-variant--modern) .ll-row:hover:not(.ll-row--selected){background-color:#ebebeb!important}:host(.ll-variant--modern) .ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important;box-shadow:inset 4px 0 #334155}:host(.ll-variant--modern) .ll-row--drag-over{background-color:#5b8dee14!important;outline:2px dashed rgba(91,141,238,.5);outline-offset:-2px}:host(.ll-variant--modern) .ll-row td{border-left:none;border-right:none;border-top:none;border-bottom:1px solid rgba(0,0,0,.1);height:40px}:host(.ll-variant--modern) .ll-row td:hover{background-color:#292a2c09!important;border-bottom:1px solid rgb(133,133,133)}:host(.ll-variant--modern) .ll-tfoot tr td:first-child{border-bottom-left-radius:10px}:host(.ll-variant--modern) .ll-tfoot tr td:last-child{border-bottom-right-radius:10px}:host(.ll-variant--modern) .ll-tfoot .ll-footer-cell{background-color:var(--background-card);color:var(--text-color);border:none;border-top:1px solid rgba(0,0,0,.08);padding:10px 14px;box-shadow:none}:host(.ll-variant--modern) .ll-empty{padding:28px;color:#9ca3af;font-size:13px}.ll-search-bar{display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:8px;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:4px;overflow-anchor:none}.ll-table{width:100%;border-collapse:collapse;table-layout:auto;white-space:nowrap}.ll-thead{position:sticky;top:0;z-index:3;background-color:var(--background-header-table)}.ll-thead tr th{font-size:11px;font-weight:700;color:var(--text-color);text-align:start;padding:6px 8px;border:var(--border-table-header);max-width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background-color:var(--background-header-table);box-shadow:0 2px 2px -1px #0000001a}.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:2px}.ll-th-caption{overflow:hidden;text-overflow:ellipsis}.ll-sort-idle{opacity:.25}.ll-tfoot{position:sticky;bottom:0;z-index:3;background-color:var(--background-card)}.ll-tfoot .ll-footer-cell{font-size:11px;color:var(--text-color);padding:10px 8px;border:var(--border-table-header);background-color:var(--background-card);box-shadow:0 -2px 2px -1px #0000001a}.ll-row{height:30px;cursor:pointer}.ll-row:nth-child(odd){background-color:#00000010}.ll-row:hover{background-color:#00000015}.ll-row--selected{background:var(--table-active-bg)!important;color:var(--table-active-color)!important}.ll-row--drag-over{background-color:#5b8dee1f!important;outline:2px dashed #5b8dee;outline-offset:-2px;cursor:copy}.ll-row--drag-over td{color:#5b8dee!important}.ll-row td{font-size:11px;font-weight:500;color:var(--text-color);vertical-align:middle;padding:0 8px;border:var(--border-table-header);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ll-spacer td{padding:0;border:none}.ll-empty{text-align:center;padding:16px;color:#6c757d;font-size:12px}@media (max-width: 1600px){.ll-thead tr th,.ll-row td,.ll-tfoot .ll-footer-cell{font-size:9px}}.popover-menu-column{position:absolute;top:100%;left:0;right:auto;border-radius:.375rem;padding:0rem .75rem;display:block;max-height:min(500px,80vh);width:min(400px,100vw - 2rem);max-width:calc(80vw - 2rem);overflow-y:auto}.popover-title{font-weight:700;margin-bottom:.7rem;margin-left:-.75rem;margin-right:-.75rem;padding:.6rem .75rem;border-bottom:1px solid #c4c4c4;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}.column-config-hint{font-size:10px;font-weight:400;text-transform:none;color:#9aa3ac}.column-config-list{display:flex;flex-direction:column;gap:3px;padding:4px 0 2px}.column-config-row{display:flex;align-items:center;gap:8px;padding:4px 6px;background:#fff;border:1px solid transparent;border-radius:6px;transition:background-color .15s ease,border-color .15s ease}.column-config-row:hover{background:#f6f7f8}.column-config-grip{cursor:grab;color:#adb5bd;font-size:13px;flex:none}.column-config-grip:active{cursor:grabbing}.column-config-row.cdk-drag-preview{box-shadow:0 10px 24px -8px #00000059;border:1px solid #e5e5e5;border-radius:6px;background:#fff;transform:rotate(-1.5deg)}.column-config-row.cdk-drag-placeholder{border:1.5px dashed #6c757d;border-radius:6px;background:#f1f3f5;opacity:.7}.column-config-row.cdk-drag-placeholder *{visibility:hidden}.column-config-list.cdk-drop-list-dragging .column-config-row:not(.cdk-drag-placeholder){transition:transform .2s cubic-bezier(0,0,.2,1)}.column-config-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;position:sticky;bottom:0;background:#fff;border-top:1px solid #e5e5e5;margin:6px -.75rem 0;padding:8px .75rem}.popover-menu-column::-webkit-scrollbar-thumb{background-color:#d7d7d7;border-radius:4px;border:2px solid transparent}.column-config-save{border-radius:6px;border:1px solid rgba(0,0,0,.12);background-color:#fff;color:#272727;padding:4px 12px;box-shadow:0 1px 2px #0000000f;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease}.column-config-save:hover{background-color:#334155;border-color:#0003;color:#fff;box-shadow:0 2px 6px #00000026}.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}.table-blank{background:var(--background-card)}.auditoria{padding-left:35px;padding-top:8px;padding-bottom:10px}.cw-25{min-width:40px}\n"] }]
|
|
4139
4154
|
}], propDecorators: { onResize: [{
|
|
4140
4155
|
type: HostListener,
|
|
4141
4156
|
args: ['window:resize', ['$event']]
|
|
@@ -4160,7 +4175,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
4160
4175
|
* @Input withCheckbox - Mostrar checkboxes de selección
|
|
4161
4176
|
* @Input lazyLoad - Activa carga diferida de hijos (emite expandEvent)
|
|
4162
4177
|
* @Input indentSize - Píxeles de indentación por nivel (default: 20)
|
|
4163
|
-
* @Input maxLevels - Límite de niveles expandibles (0 = sin límite)
|
|
4178
|
+
* @Input maxLevels - Límite de niveles expandibles (0 = sin límite). A partir del
|
|
4179
|
+
* último nivel permitido no se muestra el chevron de expandir,
|
|
4180
|
+
* aunque `lazyLoad` esté activo.
|
|
4181
|
+
* @Input hasChildrenKey - Campo del dato origen que indica si el nodo tiene hijos
|
|
4182
|
+
* (ej. 'tieneHijos'). Con `lazyLoad` activo, sin este campo se
|
|
4183
|
+
* asume que toda fila puede tener hijos hasta que se consulten;
|
|
4184
|
+
* definiéndolo, las filas hoja no muestran chevron.
|
|
4164
4185
|
* @Input customLevels - Niveles que renderizan su bloque de datos con `#levelTemplate`
|
|
4165
4186
|
* en vez de la grilla de `columns` (permite que cada nivel tenga
|
|
4166
4187
|
* su propia organización/estructura visual)
|
|
@@ -4193,6 +4214,12 @@ class TableUltimatePivotComponent {
|
|
|
4193
4214
|
lazyLoad = input(false);
|
|
4194
4215
|
indentSize = input(20);
|
|
4195
4216
|
maxLevels = input(0);
|
|
4217
|
+
/** Nombre del campo del dato origen que indica explícitamente si el nodo tiene hijos
|
|
4218
|
+
* (ej. 'tieneHijos'). Útil con `lazyLoad`: sin esto, todo nodo se asume expandible
|
|
4219
|
+
* porque no se conocen sus hijos hasta pedirlos; si el backend ya informa qué filas
|
|
4220
|
+
* son hoja, declarar esta propiedad evita mostrar el chevron (y disparar el lazy load)
|
|
4221
|
+
* en esas filas. Si no se define, se mantiene el comportamiento por defecto. */
|
|
4222
|
+
hasChildrenKey = input(null);
|
|
4196
4223
|
/** Niveles (0-based) cuyo bloque de datos se delega al `#levelTemplate` proyectado,
|
|
4197
4224
|
* en lugar de la grilla estándar de `columns`. Ej: [1, 2].
|
|
4198
4225
|
* Las filas de estos niveles no muestran el chevron de expandir propio: si el nivel
|
|
@@ -4279,17 +4306,21 @@ class TableUltimatePivotComponent {
|
|
|
4279
4306
|
const ck = this.childrenKey();
|
|
4280
4307
|
const maxL = this.maxLevels();
|
|
4281
4308
|
const lazy = this.lazyLoad();
|
|
4309
|
+
const hcKey = this.hasChildrenKey();
|
|
4310
|
+
// Nivel a partir del cual ya no se permite seguir desplegando (0 = sin límite)
|
|
4311
|
+
const withinMaxLevels = maxL === 0 || level < maxL - 1;
|
|
4282
4312
|
for (const node of nodes) {
|
|
4283
4313
|
const id = node.idListTsi;
|
|
4284
4314
|
const children = node[ck];
|
|
4285
|
-
const
|
|
4315
|
+
const hasOwnChildren = Array.isArray(children) && children.length > 0;
|
|
4316
|
+
// Si el dato trae un indicador explícito de "tiene hijos", manda sobre la
|
|
4317
|
+
// suposición de lazyLoad (así una fila hoja no muestra chevron innecesario).
|
|
4318
|
+
const hasChildren = withinMaxLevels && (hcKey && node[hcKey] !== undefined ? !!node[hcKey] : (hasOwnChildren || lazy));
|
|
4286
4319
|
const isExpanded = expanded.has(id);
|
|
4287
4320
|
const isLoading = loading.has(id);
|
|
4288
4321
|
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
|
-
}
|
|
4322
|
+
if (withinMaxLevels && isExpanded && !isLoading && hasOwnChildren) {
|
|
4323
|
+
result.push(...this.flattenVisible(children, level + 1, expanded, loading));
|
|
4293
4324
|
}
|
|
4294
4325
|
}
|
|
4295
4326
|
return result;
|
|
@@ -4588,13 +4619,13 @@ class TableUltimatePivotComponent {
|
|
|
4588
4619
|
return fields.reduce((acc, f) => acc + (obj[f] ?? ''), '');
|
|
4589
4620
|
}
|
|
4590
4621
|
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 }, 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}.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}.ll-row--level-0{background-color:#fff}.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] });
|
|
4622
|
+
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
4623
|
}
|
|
4593
4624
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TableUltimatePivotComponent, decorators: [{
|
|
4594
4625
|
type: Component,
|
|
4595
4626
|
args: [{ selector: 'app-table-ultimate-pivot', standalone: true, imports: [FormsModule, CommonModule, DropdownCdkComponent, AnimatedCheckboxDirective, NgTemplateOutlet], animations: [fadeInOut, dropdownAnimation], host: {
|
|
4596
4627
|
'[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: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}.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}.ll-row--level-0{background-color:#fff}.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"] }]
|
|
4628
|
+
}, 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
4629
|
}] });
|
|
4599
4630
|
|
|
4600
4631
|
class TableAgrupadaComponent {
|