layout-tsi 0.0.1 → 0.0.3
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/layout-tsi.mjs
CHANGED
|
@@ -435,6 +435,8 @@ class MenuItemComponent {
|
|
|
435
435
|
return;
|
|
436
436
|
}
|
|
437
437
|
if (this.item()?.submenu?.length > 0) {
|
|
438
|
+
if (this.isCollapsedMode)
|
|
439
|
+
return;
|
|
438
440
|
this.open.set(!this.open());
|
|
439
441
|
this.menuService.setOpenMenu(this.level(), this.open() ? this.getItemId() : null);
|
|
440
442
|
}
|
|
@@ -499,11 +501,11 @@ class MenuItemComponent {
|
|
|
499
501
|
return item.path;
|
|
500
502
|
}
|
|
501
503
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
502
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MenuItemComponent, isStandalone: true, selector: "app-menu-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, isSidebarHovering: { classPropertyName: "isSidebarHovering", publicName: "isSidebarHovering", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, parentModuleName: { classPropertyName: "parentModuleName", publicName: "parentModuleName", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, accesos: { classPropertyName: "accesos", publicName: "accesos", isSignal: true, isRequired: false, transformFunction: null }, rolId: { classPropertyName: "rolId", publicName: "rolId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "component", type: MenuItemComponent, selector: "app-menu-item", inputs: ["item", "isSidebarOpen", "isSidebarHovering", "level", "parentModuleName", "accentColor", "accesos", "rolId"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
504
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: MenuItemComponent, isStandalone: true, selector: "app-menu-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, isSidebarHovering: { classPropertyName: "isSidebarHovering", publicName: "isSidebarHovering", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, parentModuleName: { classPropertyName: "parentModuleName", publicName: "parentModuleName", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, accesos: { classPropertyName: "accesos", publicName: "accesos", isSignal: true, isRequired: false, transformFunction: null }, rolId: { classPropertyName: "rolId", publicName: "rolId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}:host-context(.sidebar.open) .item-sidebar{border-radius:8px 0 0 8px;margin-right:-8px}:host-context(.sidebar.open) .item-sidebar:hover{transform:none}:host-context(.sidebar.open) .item-sidebar.active-route{border-radius:0!important;background:#ffffff24!important}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "component", type: MenuItemComponent, selector: "app-menu-item", inputs: ["item", "isSidebarOpen", "isSidebarHovering", "level", "parentModuleName", "accentColor", "accesos", "rolId"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
503
505
|
}
|
|
504
506
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: MenuItemComponent, decorators: [{
|
|
505
507
|
type: Component,
|
|
506
|
-
args: [{ selector: 'app-menu-item', imports: [NgClass, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"] }]
|
|
508
|
+
args: [{ selector: 'app-menu-item', imports: [NgClass, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if(hasAccess()){\r\n<li (mouseenter)=\"onItemMouseEnter($event)\" (mouseleave)=\"onItemMouseLeave()\"\r\n (mouseover)=\"onItemMouseOver()\">\r\n <div class=\"d-flex align-items-center justify-content-between pt-2 pb-2 px-2 item-sidebar\" (click)=\"toggle()\"\r\n (mousedown)=\"onMiddleClick($event)\" (contextmenu)=\"onRightClick($event)\"\r\n [routerLink]=\"(!item().submenu?.length && item().path && !item().extralink) ? item().path : null\"\r\n [class.active-route]=\"esRutaActiva(item().path)\" [class.cursor-pointer]=\"item().submenu?.length == 0\"\r\n [class.cursor-drow]=\"item().submenu?.length > 0\">\r\n <span>\r\n @if (item().title) {\r\n <i [class]=\"(item().icon ? item().icon : '') + (isSidebarActuallyOpen ? ' me-1' : ' me-1 ms-2')\"></i>\r\n <span class=\"sidebar-text\" [class.sidebar-text--hidden]=\"!isSidebarActuallyOpen\">\r\n {{ item().title }}\r\n </span>\r\n }\r\n </span>\r\n @if (item().submenu?.length > 0) {\r\n <i class=\"fas sidebar-chevron\" [class.sidebar-chevron--hidden]=\"!isSidebarActuallyOpen\" [ngClass]=\"{\r\n 'fa-chevron-down': isOpen(),\r\n 'fa-chevron-right': !isOpen()\r\n }\"></i>\r\n }\r\n </div>\r\n @if (item().submenu?.length && isSidebarActuallyOpen && submenuRendered()) {\r\n <ul class=\"list-unstyled ms-3 submenu\" [class.submenu--closing]=\"!isOpen()\">\r\n @for (child of item().submenu; track $index) {\r\n <app-menu-item [item]=\"child\" [level]=\"level() + 1\" [isSidebarOpen]=\"!isSidebarActuallyOpen\" [parentModuleName]=\"parentModuleName()\" [accentColor]=\"accentColor()\" [accesos]=\"accesos()\" [rolId]=\"rolId()\" />\r\n }\r\n </ul>\r\n }\r\n\r\n @if (flyoutRendered()) {\r\n <div class=\"sidebar-flyout\" [class.sidebar-flyout--closing]=\"!showFlyout()\" [style.top.px]=\"flyoutY()\" [style.max-height]=\"'calc(100dvh - ' + flyoutY() + 'px - 8px)'\"\r\n [style.--flyout-accent]=\"accentColor()\" (mouseenter)=\"onFlyoutMouseEnter()\" (mouseleave)=\"onFlyoutMouseLeave()\">\r\n <div class=\"flyout-header\">\r\n <i [class]=\"(item().icon || '') + ' flyout-header-icon'\"></i>\r\n <span class=\"flyout-header-title\">{{ item().title }}</span>\r\n @if (codAcceso()) {\r\n <span class=\"flyout-header-acceso\">{{ codAcceso().split(': ')[1] }}</span>\r\n }\r\n </div>\r\n @if (item().submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-items\">\r\n @for (child of item().submenu; track $index) {\r\n @if (hasAccess(child)) {\r\n <li class=\"flyout-group\">\r\n <div class=\"flyout-item\" [class.flyout-item-has-children]=\"child.submenu?.length > 0\"\r\n [class.flyout-item-expanded]=\"isFlyoutChildExpanded(child)\" [routerLink]=\"manejarRuta(child)\"\r\n [class.flyout-item-active]=\"!child.submenu?.length && esRutaActiva(child.path)\"\r\n (click)=\"onFlyoutItemClick(child, $event)\" (mousedown)=\"onFlyoutItemMiddleClick($event, child)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, child)\" (mouseenter)=\"showChildTooltip($event, child)\"\r\n (mouseleave)=\"hideChildTooltip()\">\r\n @if (child.icon) {\r\n <i [class]=\"child.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ child.title }}</span>\r\n @if (child.submenu?.length > 0) {\r\n <i class=\"fas flyout-chevron\" [class.fa-chevron-down]=\"isFlyoutChildExpanded(child)\"\r\n [class.fa-chevron-right]=\"!isFlyoutChildExpanded(child)\"></i>\r\n }\r\n </div>\r\n\r\n @if (isFlyoutChildExpanded(child) && child.submenu?.length > 0) {\r\n <ul class=\"list-unstyled flyout-subitems\">\r\n @for (grandchild of child.submenu; track $index) {\r\n @if (hasAccess(grandchild)) {\r\n <li class=\"flyout-subitem\" [routerLink]=\"manejarRuta(grandchild)\" [class.flyout-subitem-active]=\"esRutaActiva(grandchild.path)\"\r\n (click)=\"onFlyoutGrandchildClick(grandchild)\" (mousedown)=\"onFlyoutItemMiddleClick($event, grandchild)\"\r\n (contextmenu)=\"onFlyoutItemRightClick($event, grandchild)\"\r\n (mouseenter)=\"showChildTooltip($event, grandchild)\" (mouseleave)=\"hideChildTooltip()\">\r\n @if (grandchild.icon) {\r\n <i [class]=\"grandchild.icon + ' flyout-item-icon'\"></i>\r\n }\r\n <span class=\"flyout-item-label\">{{ grandchild.title }}</span>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </li>\r\n }\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n</li>\r\n}\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".active-route{color:var(--sidebar-active-text)!important;background:linear-gradient(90deg,#ffffff24,#ffffff0a)!important;border-left:3px solid var(--sidebar-accent, #c50048)!important;border-radius:0 8px 8px 0!important;box-shadow:inset 0 1px #ffffff0f!important}.cursor-drow{cursor:default}.submenu{transform-origin:top;animation:submenuIn .26s cubic-bezier(.4,0,.2,1) both}.submenu--closing{animation:submenuOut .22s cubic-bezier(.4,0,.2,1) both}@keyframes submenuIn{0%{opacity:0;transform:translateY(-8px) scaleY(.94)}to{opacity:1;transform:translateY(0) scaleY(1)}}@keyframes submenuOut{0%{opacity:1;transform:translateY(0) scaleY(1)}to{opacity:0;transform:translateY(-8px) scaleY(.94)}}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid var(--sidebar-accent, #c50048);display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700;color:var(--sidebar-accent, #c50048)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--sidebar-accent, #c50048)}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.sidebar-text{display:inline-block;vertical-align:middle;white-space:normal;word-break:break-word;opacity:1;transform:translate(0);transition:opacity .15s ease .22s,transform .15s ease .22s}.sidebar-text--hidden{opacity:0;transform:translate(-4px);white-space:nowrap;max-width:0;overflow:hidden;transition:opacity .12s ease 0s,transform .12s ease 0s,max-width 0s linear .12s}.sidebar-chevron{opacity:1;transition:opacity .15s ease .22s}.sidebar-chevron--hidden{opacity:0;transition:opacity .12s ease 0s}.item-sidebar{color:var(--sidebar-text-color)!important;transition:all .2s ease;border-radius:8px}.item-sidebar>span:first-child{min-width:0;flex:1}.item-sidebar:hover{color:var(--sidebar-active-text)!important;background:#ffffff17!important;transform:translate(2px)}:host-context(.sidebar.open) .item-sidebar{border-radius:8px 0 0 8px;margin-right:-8px}:host-context(.sidebar.open) .item-sidebar:hover{transform:none}:host-context(.sidebar.open) .item-sidebar.active-route{border-radius:0!important;background:#ffffff24!important}.sidebar-flyout{position:fixed;left:70px;z-index:9999;min-width:220px;max-width:300px;overflow-y:auto;scrollbar-width:none;background:linear-gradient(160deg,var(--sidebar-gradient-start, #1a1a2e) 0%,var(--sidebar-bg, #16213e) 100%);border:1px solid rgba(255,255,255,.1);border-left:3px solid var(--flyout-accent, #c50048);border-radius:0 12px 12px;box-shadow:8px 6px 32px #0000008c,0 0 0 1px #ffffff0a;animation:flyout-slide-in .15s cubic-bezier(.25,.46,.45,.94);pointer-events:auto}.sidebar-flyout--closing{animation:flyout-slide-out .13s ease-in both}@keyframes flyout-slide-out{0%{opacity:1;transform:translate(0)}to{opacity:0;transform:translate(-8px)}}.flyout-header{display:flex;align-items:center;gap:10px;padding:12px 16px 10px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff0a}.flyout-header-icon{color:var(--flyout-accent, #c50048);font-size:14px;min-width:16px;text-align:center}.flyout-header-title{font-size:12px;font-weight:700;color:var(--sidebar-active-text, #fff);letter-spacing:.5px;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1}.flyout-header-acceso{font-size:10px;font-weight:700;font-family:monospace;color:var(--flyout-accent, #c50048);background:#ffffff12;border:1px solid rgba(255,255,255,.1);border-left:2px solid var(--flyout-accent, #c50048);padding:2px 7px;border-radius:4px;white-space:nowrap;flex-shrink:0}.flyout-items{padding:6px;margin:0}.flyout-item{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .7));font-size:13px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden;position:relative}.flyout-item:hover{background:#ffffff1a;color:var(--sidebar-active-text, #fff);transform:translate(3px)}.flyout-item-active{background:linear-gradient(90deg,#ffffff21,#ffffff08)!important;color:var(--sidebar-active-text, #fff)!important}.flyout-item-active:before{content:\"\";position:absolute;left:0;top:15%;height:70%;width:3px;background:var(--flyout-accent, #c50048);border-radius:0 2px 2px 0}.flyout-item-icon{font-size:12px;min-width:14px;text-align:center;color:inherit;opacity:.75}.flyout-item-label{flex:1;overflow:hidden;text-overflow:ellipsis}.flyout-chevron{font-size:10px;opacity:.5;margin-left:auto;flex-shrink:0;transition:transform .2s ease}.flyout-group{display:flex;flex-direction:column}.flyout-item-has-children{cursor:default}.flyout-item-expanded{background:#ffffff12!important;color:var(--sidebar-active-text, #fff)!important}.flyout-subitems{padding:2px 6px 2px 14px;border-left:2px solid rgba(255,255,255,.1);margin:0 6px 4px 20px}.flyout-subitem{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:6px;cursor:pointer;color:var(--sidebar-text-color, rgba(255, 255, 255, .65));font-size:12px;transition:background .15s ease,color .15s ease,transform .15s ease;white-space:nowrap;overflow:hidden}.flyout-subitem:hover{background:#ffffff17;color:var(--sidebar-active-text, #fff);transform:translate(2px)}.flyout-subitem-active{color:var(--sidebar-active-text, #fff)!important;position:relative}.flyout-subitem-active:before{content:\"\";position:absolute;left:-14px;top:20%;height:60%;width:2px;background:var(--flyout-accent, #c50048);border-radius:1px}@keyframes flyout-slide-in{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}\n"] }]
|
|
507
509
|
}], ctorParameters: () => [] });
|
|
508
510
|
|
|
509
511
|
class BottomNavigationComponent {
|
|
@@ -736,11 +738,11 @@ class VerticalHeaderComponent {
|
|
|
736
738
|
this.searchCollapsed.set(collides);
|
|
737
739
|
}
|
|
738
740
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: VerticalHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
739
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: VerticalHeaderComponent, isStandalone: true, selector: "app-vertical-header", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, themes: { classPropertyName: "themes", publicName: "themes", isSignal: true, isRequired: false, transformFunction: null }, showThemeSwitcher: { classPropertyName: "showThemeSwitcher", publicName: "showThemeSwitcher", isSignal: true, isRequired: false, transformFunction: null }, showTabs: { classPropertyName: "showTabs", publicName: "showTabs", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, notificationsCount: { classPropertyName: "notificationsCount", publicName: "notificationsCount", isSignal: true, isRequired: false, transformFunction: null }, notificationsInBottomNav: { classPropertyName: "notificationsInBottomNav", publicName: "notificationsInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, showChatbotToggle: { classPropertyName: "showChatbotToggle", publicName: "showChatbotToggle", isSignal: true, isRequired: false, transformFunction: null }, chatbotVisible: { classPropertyName: "chatbotVisible", publicName: "chatbotVisible", isSignal: true, isRequired: false, transformFunction: null }, chatbotInBottomNav: { classPropertyName: "chatbotInBottomNav", publicName: "chatbotInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, versionApp: { classPropertyName: "versionApp", publicName: "versionApp", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, envClass: { classPropertyName: "envClass", publicName: "envClass", isSignal: true, isRequired: false, transformFunction: null }, produccion: { classPropertyName: "produccion", publicName: "produccion", isSignal: true, isRequired: false, transformFunction: null }, isScrolled: { classPropertyName: "isScrolled", publicName: "isScrolled", isSignal: true, isRequired: false, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, nameProyecto: { classPropertyName: "nameProyecto", publicName: "nameProyecto", isSignal: true, isRequired: false, transformFunction: null }, showPanelControl: { classPropertyName: "showPanelControl", publicName: "showPanelControl", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, empresaName: { classPropertyName: "empresaName", publicName: "empresaName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { notificationsClick: "notificationsClick", chatbotVisibleChange: "chatbotVisibleChange", themeChange: "themeChange", emitirToogle: "emitirToogle", searchComponents: "searchComponents", panelControlClick: "panelControlClick", logout: "logout" }, host: { listeners: { "document:click": "onDocumentClick()" } }, viewQueries: [{ propertyName: "headerContainerRef", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "headerSideStartRef", first: true, predicate: ["headerSideStart"], descendants: true }, { propertyName: "headerSideEndRef", first: true, predicate: ["headerSideEnd"], descendants: true }, { propertyName: "compactSearchWrapperRef", first: true, predicate: ["compactSearchWrapper"], descendants: true }], ngImport: i0, template: "<div #headerContainer class=\"d-flex header-container\" [ngClass]=\"envClass()\">\r\n <div class=\"first-header d-none d-md-flex\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" width=\"40px\" height=\"40px\" style=\"cursor:pointer\"\r\n (click)=\"goToHome()\" title=\"Ir a Home\">\r\n <span class=\"text-white empresa-nombre ps-2\" [title]=\"versionApp()\">{{empresaName()}}</span>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 h-100 justify-content-between align-items-center pe-3 ps-0\">\r\n <div #headerSideStart class=\"d-flex align-items-center header-side\">\r\n <button class=\"btn text-white none-style sidebar-toggle-btn\" (click)=\"emitirToogle.emit()\">\r\n <i class=\"fa-solid fa-table-columns\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n <i class=\"fa-solid fa-chevron-left toggle-arrow\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n </button>\r\n <span class=\"text-white empresa-nombre d-inline d-md-none ps-2\">{{empresaName()}}</span>\r\n <span class=\"text-white fs-5 fw-normal d-none d-md-inline ps-2 text-nowrap\">{{nameProyecto()}}</span>\r\n @if (showTabs() && tabsService.tabs().length) {\r\n <button class=\"tabs-header-btn mx-2 d-none d-md-flex\"\r\n [class.tabs-header-btn--active]=\"tabsService.visible()\" (click)=\"tabsService.toggleVisible()\"\r\n [title]=\"tabsService.visible() ? 'Ocultar acceso r\u00E1pido' : 'Mostrar acceso r\u00E1pido'\">\r\n <i class=\"fas fa-layer-group\"></i>\r\n @if (!tabsService.visible()) {\r\n <span class=\"tabs-header-count\">{{ tabsService.tabs().length }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSearch()) {\r\n <button class=\"global-search-trigger d-none d-md-flex align-items-center\"\r\n [class.global-search-trigger--collapsed]=\"searchCollapsed()\" title=\"B\u00FAsqueda de p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">\r\n <i class=\"fas fa-search global-search-icon\"></i>\r\n <span class=\"global-search-placeholder\">Buscar p\u00E1ginas...</span>\r\n <kbd class=\"global-search-kbd\">F2</kbd>\r\n </button>\r\n }\r\n\r\n <div #headerSideEnd class=\"d-flex align-items-center header-side header-side--end\">\r\n\r\n <!-- Fallback del buscador centrado cuando no entra (colisi\u00F3n) o en mobile\r\n (el buscador centrado se oculta por completo por debajo de md): la\r\n p\u00EDldora de texto \"F2\", igual que antes. -->\r\n <div #compactSearchWrapper class=\"h-100 d-flex align-items-center\">\r\n @if (showSearch() && searchCollapsed()) {\r\n <button class=\"global-search-compact-pill\" title=\"Buscar p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">F2</button>\r\n }\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[extra-actions]\" />\r\n\r\n <!-- Acciones adicionales, definidas por el consumidor: siempre a la izquierda\r\n de los tres fijos (tema, notificaciones, soporte). Solo se ocultan en mobile\r\n las que adem\u00E1s se reflejan en el bottom-nav (showInBottomNav) \u2014 si una acci\u00F3n\r\n no baja al bottom-nav, se queda visible ac\u00E1 para no desaparecer del todo. -->\r\n @for (action of actions(); track action.label) {\r\n @if (!action.hidden) {\r\n @if (action.items?.length) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"openActionKey() === action.label\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"toggleActionMenu($event, action)\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"openActionKey() === action.label\">\r\n @for (opcion of action.items; track opcion.label; let last = $last) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4\"\r\n [ngClass]=\"{'divider-border': !last,'border-top-radius': $index == 0,'border-bottom-radius': last}\"\r\n (click)=\"runAction(opcion)\"\r\n (mouseenter)=\"showTooltip($event, opcion.title ?? '')\" (mouseleave)=\"hideTooltip()\">\r\n <i [class]=\"opcion.icon\" class=\"me-1\"></i> {{ opcion.label }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"h-100 d-flex align-items-center\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.()\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n @if (action.badge) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ action.badge }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showThemeSwitcher()) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"themeMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" (click)=\"toggleThemeMenu($event)\"\r\n [title]=\"'Tema: ' + themeLabel()\">\r\n <i class=\"fas text-white\" [ngClass]=\"themeIcon()\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"themeMenuOpen()\">\r\n @for (item of themes(); track item.id) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 border-bottom-radius divider-border\"\r\n (click)=\"selectTheme(item.id)\">\r\n <i class=\"fas me-1\" [ngClass]=\"item.icon\"></i> {{ item.label }}\r\n @if (currentTheme() === item.id) {\r\n <i class=\"fas fa-check ms-auto text-success\"></i>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Notificaciones y soporte: \u00EDcono/estilo est\u00E1ndar, siempre visibles tambi\u00E9n en mobile -->\r\n @if (showNotifications()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" title=\"Notificaciones\"\r\n (click)=\"notificationsClick.emit()\">\r\n <i class=\"fas fa-bell text-white\"></i>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ notificationsCount() }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (showChatbotToggle()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\"\r\n [title]=\"chatbotVisible() ? 'Ocultar soporte' : 'Mostrar soporte'\"\r\n (click)=\"chatbotVisibleChange.emit(!chatbotVisible())\">\r\n <i class=\"fas fa-robot text-white\"></i>\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"userMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"border-0 bg-none\" (click)=\"toggleUserMenu($event)\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\" alt=\"\">\r\n </button>\r\n </div>\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0\" [class.show]=\"userMenuOpen()\">\r\n <div\r\n class=\"d-flex no-block align-items-center p-3 divider-border bg-gray-user-data border-top-radius\">\r\n <div class=\"d-flex align-items-center\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\">\r\n <div class=\"ms-2\">\r\n <p class=\"fs-7 my-0 py-0 fw-6\">{{userName()}}</p>\r\n @if (userName().startsWith('DESARROLLADOR')) {\r\n <span class=\"fs-7 fw-bold\">Desarrollador</span>\r\n } @else if (userName().startsWith('SOPORTE')) {\r\n <span class=\"fs-7 fw-bold\">Soporte</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (showPanelControl()) {\r\n <button class=\"dropdown-item py-3 fs-7 fw-4\" (click)=\"userMenuOpen.set(false); panelControlClick.emit()\">\r\n Panel de control\r\n </button>\r\n }\r\n <button class=\"dropdown-item py-3 fs-7 fw-4 border-bottom-radius\" (click)=\"userMenuOpen.set(false); logout.emit()\"><i\r\n class=\"fas fa-power-off\"></i> Cerrar sesi\u00F3n</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\"\r\n [style.borderLeftColor]=\"accentColor()\" [style.--tooltip-accent]=\"accentColor()\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\" [style.color]=\"accentColor()\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".header-container{height:50px;display:flex;align-items:center;transition:position .5s ease-in-out,background-color .2s ease;padding:0;margin:0;position:relative;--header-accent: #398bf7;background:var(--header-accent);border-bottom:2px solid transparent}.header-container.dev{--header-accent: rgb(197, 0, 72)}.header-container.prod{--header-accent: #398bf7}.header-container.qa{--header-accent: #20c997}:host-context(.dark-mode) .header-container,:host-context(.sky-blue-mode) .header-container,:host-context(.high-contrast-green-mode) .header-container,:host-context(.purple-mode) .header-container{background:var(--header-bg);border-bottom-color:var(--header-accent)}.first-header{display:flex;align-items:center;gap:6px}.empresa-nombre{max-width:350px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:1.25;max-height:2.5em;max-width:100%}@media(max-width:575px){.empresa-nombre{display:none!important}.first-header{min-width:auto!important;padding:10px!important}}@media(min-width:576px)and (max-width:1180px){.first-header{padding:10px!important}}@media(min-width:1181px){.first-header{min-width:260px;width:260px;padding:15px}}.bg-gray-user-data{background:var(--background-btn-light)}.dropdown-menu{transform-origin:top;background-color:var(--background-card);border-color:var(--border-color-modal);color:var(--text-color)}.dropdown-menu-end{right:0!important;left:auto!important}.dropdown-item{color:var(--text-color)}.dropdown-item:hover,.dropdown-item:focus{background-color:var(--bs-table-hover-bg);color:var(--text-color)}.dropdown-menu.show{animation:dropdownMenuIn .24s cubic-bezier(.2,0,.2,1) both}@keyframes dropdownMenuIn{0%{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}.dropdown-menu{width:300px!important;min-width:300px!important}.circle-icon{min-height:30px;min-width:30px;height:30px;width:30px;border-radius:100%;border:2px solid white}.none-style{background:none;border:none}.sidebar-toggle-btn{display:flex;align-items:center;gap:4px}.sidebar-toggle-btn i{transition:transform .25s cubic-bezier(.4,0,.2,1)}.sidebar-toggle-btn i.flipped{transform:scaleX(-1)}.sidebar-toggle-btn .toggle-arrow{font-size:9px;color:#fff}.z-index{z-index:1001}.option{position:relative;border-radius:50px;width:33px;height:100%;transition:background-color .3s ease}.option:hover,.dropdown.show .option{background-color:var(--bs-table-hover-bg)!important}.custom-dropdown.dropdown-menu{min-width:unset!important;width:auto!important}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid;display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--tooltip-accent, #c50048)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.btn-print{border:1px solid rgba(0,0,0,.5764705882)!important;width:33px;height:30px!important;border-radius:6px}.btn-print:hover{border:1px solid rgba(61,61,61,.5254901961)!important;background-color:#dadadaf8!important}.btn-search{width:40px;height:31px!important;border-radius:6px}.logo-btn{width:25px;height:25px;object-fit:contain}.btn-deudas{background:#fff;border-radius:20px;border:none;white-space:nowrap;flex-shrink:0}.btn-deudas.titilando{animation:bordeTitilante 1s infinite alternate}@keyframes bordeTitilante{0%{box-shadow:0 0 2px red}50%{box-shadow:0 0 5px red,0 0 5px #ff4d4d}to{box-shadow:0 0 2px red}}@media(max-width:1100px){.btn-deudas{width:31px;height:31px!important;border-radius:50px;padding:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.btn-deudas .texto-deudas{display:none}.btn-deudas .logo-btn{width:20px;height:20px;margin:0}}@keyframes icon-rotate-pop{0%{transform:rotate(0) scale(1)}25%{transform:rotate(10deg) scale(1.05)}50%{transform:rotate(-10deg) scale(1.1)}75%{transform:rotate(10deg) scale(1.05)}to{transform:rotate(0) scale(1)}}.button-icon-hover{display:inline-block}.button-tilt-hover:hover .button-icon-hover{animation:icon-rotate-pop 1s ease-in-out infinite}.desktop-only{display:flex}@media(max-width:667px){.desktop-only{display:none!important}}.notification-btn{position:relative;border:none;background:none;padding:0;margin-right:8px;cursor:pointer;width:33px;height:32px;display:flex;align-items:center;justify-content:center}.notification-btn i{color:#fff}.notification-badge{position:absolute;top:-5px;right:-3px;color:#fff;font-size:11px;font-weight:600;border-radius:4px;min-width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0 4px}.header-side{flex:0 1 auto;min-width:0}.header-side--end{justify-content:flex-end}.global-search-trigger{position:absolute;left:50%;transform:translate(-50%);z-index:2;align-self:center;flex-shrink:0;margin:0;gap:8px;height:31px;width:280px;padding:0 6px 0 12px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:12px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.global-search-trigger:hover,.global-search-trigger:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.global-search-trigger .global-search-icon{font-size:12px;color:#ffffffbf}.global-search-trigger .global-search-placeholder{flex-grow:1;text-align:start}.global-search-trigger .global-search-kbd{font-size:10px;font-weight:600;line-height:1;padding:3px 5px;border-radius:4px;background:#fff3;border:1px solid rgba(255,255,255,.35);color:#fff}.global-search-trigger--collapsed{display:none!important}.global-search-compact-pill{display:flex;align-items:center;justify-content:center;height:31px;margin-right:8px;padding:0 9px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:11px;font-weight:700;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.global-search-compact-pill:hover,.global-search-compact-pill:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.tabs-header-btn{display:flex;align-items:center;gap:4px;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);color:#fff9;border-radius:20px;padding:3px 8px;font-size:11px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}.tabs-header-btn:hover{background:#fff3;color:#fff}.tabs-header-btn--active{background:#ffffff2e;color:#fff;border-color:#ffffff4d}.tabs-header-btn i{font-size:12px}.tabs-header-count{font-weight:700;font-size:11px;background:#fff3;border-radius:10px;padding:0 5px;min-width:16px;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
741
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: VerticalHeaderComponent, isStandalone: true, selector: "app-vertical-header", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, themes: { classPropertyName: "themes", publicName: "themes", isSignal: true, isRequired: false, transformFunction: null }, showThemeSwitcher: { classPropertyName: "showThemeSwitcher", publicName: "showThemeSwitcher", isSignal: true, isRequired: false, transformFunction: null }, showTabs: { classPropertyName: "showTabs", publicName: "showTabs", isSignal: true, isRequired: false, transformFunction: null }, showNotifications: { classPropertyName: "showNotifications", publicName: "showNotifications", isSignal: true, isRequired: false, transformFunction: null }, notificationsCount: { classPropertyName: "notificationsCount", publicName: "notificationsCount", isSignal: true, isRequired: false, transformFunction: null }, notificationsInBottomNav: { classPropertyName: "notificationsInBottomNav", publicName: "notificationsInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, showChatbotToggle: { classPropertyName: "showChatbotToggle", publicName: "showChatbotToggle", isSignal: true, isRequired: false, transformFunction: null }, chatbotVisible: { classPropertyName: "chatbotVisible", publicName: "chatbotVisible", isSignal: true, isRequired: false, transformFunction: null }, chatbotInBottomNav: { classPropertyName: "chatbotInBottomNav", publicName: "chatbotInBottomNav", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, versionApp: { classPropertyName: "versionApp", publicName: "versionApp", isSignal: true, isRequired: false, transformFunction: null }, accentColor: { classPropertyName: "accentColor", publicName: "accentColor", isSignal: true, isRequired: false, transformFunction: null }, envClass: { classPropertyName: "envClass", publicName: "envClass", isSignal: true, isRequired: false, transformFunction: null }, produccion: { classPropertyName: "produccion", publicName: "produccion", isSignal: true, isRequired: false, transformFunction: null }, isScrolled: { classPropertyName: "isScrolled", publicName: "isScrolled", isSignal: true, isRequired: false, transformFunction: null }, isSidebarOpen: { classPropertyName: "isSidebarOpen", publicName: "isSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, nameProyecto: { classPropertyName: "nameProyecto", publicName: "nameProyecto", isSignal: true, isRequired: false, transformFunction: null }, showPanelControl: { classPropertyName: "showPanelControl", publicName: "showPanelControl", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, empresaName: { classPropertyName: "empresaName", publicName: "empresaName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { notificationsClick: "notificationsClick", chatbotVisibleChange: "chatbotVisibleChange", themeChange: "themeChange", emitirToogle: "emitirToogle", searchComponents: "searchComponents", panelControlClick: "panelControlClick", logout: "logout" }, host: { listeners: { "document:click": "onDocumentClick()" } }, viewQueries: [{ propertyName: "headerContainerRef", first: true, predicate: ["headerContainer"], descendants: true }, { propertyName: "headerSideStartRef", first: true, predicate: ["headerSideStart"], descendants: true }, { propertyName: "headerSideEndRef", first: true, predicate: ["headerSideEnd"], descendants: true }, { propertyName: "compactSearchWrapperRef", first: true, predicate: ["compactSearchWrapper"], descendants: true }], ngImport: i0, template: "<div #headerContainer class=\"d-flex header-container\" [ngClass]=\"envClass()\">\r\n <div class=\"first-header d-none d-md-flex\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" width=\"40px\" height=\"40px\" style=\"cursor:pointer\"\r\n (click)=\"goToHome()\" title=\"Ir a Home\">\r\n <span class=\"text-white empresa-nombre ps-2\" [title]=\"versionApp()\">{{empresaName()}}</span>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 h-100 justify-content-between align-items-center pe-3 ps-0\">\r\n <div #headerSideStart class=\"d-flex align-items-center header-side\">\r\n <button class=\"btn text-white none-style sidebar-toggle-btn\" (click)=\"emitirToogle.emit()\">\r\n <i class=\"fa-solid fa-table-columns\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n <i class=\"fa-solid fa-chevron-left toggle-arrow\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n </button>\r\n <span class=\"text-white empresa-nombre d-inline d-md-none ps-2\">{{empresaName()}}</span>\r\n <span class=\"text-white fs-5 fw-normal d-none d-md-inline ps-2 text-nowrap\">{{nameProyecto()}}</span>\r\n @if (showTabs() && tabsService.tabs().length) {\r\n <button class=\"tabs-header-btn mx-2 d-none d-md-flex\"\r\n [class.tabs-header-btn--active]=\"tabsService.visible()\" (click)=\"tabsService.toggleVisible()\"\r\n [title]=\"tabsService.visible() ? 'Ocultar acceso r\u00E1pido' : 'Mostrar acceso r\u00E1pido'\">\r\n <i class=\"fas fa-layer-group\"></i>\r\n @if (!tabsService.visible()) {\r\n <span class=\"tabs-header-count\">{{ tabsService.tabs().length }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSearch()) {\r\n <button class=\"global-search-trigger d-none d-md-flex align-items-center\"\r\n [class.global-search-trigger--collapsed]=\"searchCollapsed()\" title=\"B\u00FAsqueda de p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">\r\n <i class=\"fas fa-search global-search-icon\"></i>\r\n <span class=\"global-search-placeholder\">Buscar p\u00E1ginas...</span>\r\n <kbd class=\"global-search-kbd\">F2</kbd>\r\n </button>\r\n }\r\n\r\n <div #headerSideEnd class=\"d-flex align-items-center header-side header-side--end\">\r\n\r\n <!-- Fallback del buscador centrado cuando no entra (colisi\u00F3n) o en mobile\r\n (el buscador centrado se oculta por completo por debajo de md): la\r\n p\u00EDldora de texto \"F2\", igual que antes. -->\r\n <div #compactSearchWrapper class=\"h-100 d-flex align-items-center\">\r\n @if (showSearch() && searchCollapsed()) {\r\n <button class=\"global-search-compact-pill\" title=\"Buscar p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">F2</button>\r\n }\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[extra-actions]\" />\r\n\r\n <!-- Acciones adicionales, definidas por el consumidor: siempre a la izquierda\r\n de los tres fijos (tema, notificaciones, soporte). Solo se ocultan en mobile\r\n las que adem\u00E1s se reflejan en el bottom-nav (showInBottomNav) \u2014 si una acci\u00F3n\r\n no baja al bottom-nav, se queda visible ac\u00E1 para no desaparecer del todo. -->\r\n @for (action of actions(); track action.label) {\r\n @if (!action.hidden) {\r\n @if (action.items?.length) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"openActionKey() === action.label\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"toggleActionMenu($event, action)\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"openActionKey() === action.label\">\r\n @for (opcion of action.items; track opcion.label; let last = $last) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 d-flex align-items-center\"\r\n [ngClass]=\"{'divider-border': !last,'border-top-radius': $index == 0,'border-bottom-radius': last}\"\r\n (click)=\"runAction(opcion)\"\r\n (mouseenter)=\"showTooltip($event, opcion.title ?? '')\" (mouseleave)=\"hideTooltip()\">\r\n <i [class]=\"opcion.icon\" class=\"me-1\"></i> {{ opcion.label }}\r\n @if (opcion.value) {\r\n <span class=\"ms-auto ps-3 fw-6\">{{ opcion.value }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"h-100 d-flex align-items-center\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.()\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n @if (action.badge) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ action.badge }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showThemeSwitcher()) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"themeMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" (click)=\"toggleThemeMenu($event)\"\r\n [title]=\"'Tema: ' + themeLabel()\">\r\n <i class=\"fas text-white\" [ngClass]=\"themeIcon()\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"themeMenuOpen()\">\r\n @for (item of themes(); track item.id) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 border-bottom-radius divider-border\"\r\n (click)=\"selectTheme(item.id)\">\r\n <i class=\"fas me-1\" [ngClass]=\"item.icon\"></i> {{ item.label }}\r\n @if (currentTheme() === item.id) {\r\n <i class=\"fas fa-check ms-auto text-success\"></i>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Notificaciones y soporte: \u00EDcono/estilo est\u00E1ndar, siempre visibles tambi\u00E9n en mobile -->\r\n @if (showNotifications()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" title=\"Notificaciones\"\r\n (click)=\"notificationsClick.emit()\">\r\n <i class=\"fas fa-bell text-white\"></i>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ notificationsCount() }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (showChatbotToggle()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\"\r\n [title]=\"chatbotVisible() ? 'Ocultar soporte' : 'Mostrar soporte'\"\r\n (click)=\"chatbotVisibleChange.emit(!chatbotVisible())\">\r\n <i class=\"fas fa-robot text-white\"></i>\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"userMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"border-0 bg-none\" (click)=\"toggleUserMenu($event)\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\" alt=\"\">\r\n </button>\r\n </div>\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0\" [class.show]=\"userMenuOpen()\">\r\n <div\r\n class=\"d-flex no-block align-items-center p-3 divider-border bg-gray-user-data border-top-radius\">\r\n <div class=\"d-flex align-items-center\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\">\r\n <div class=\"ms-2\">\r\n <p class=\"fs-7 my-0 py-0 fw-6\">{{userName()}}</p>\r\n @if (userName().startsWith('DESARROLLADOR')) {\r\n <span class=\"fs-7 fw-bold\">Desarrollador</span>\r\n } @else if (userName().startsWith('SOPORTE')) {\r\n <span class=\"fs-7 fw-bold\">Soporte</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (showPanelControl()) {\r\n <button class=\"dropdown-item py-3 fs-7 fw-4\" (click)=\"userMenuOpen.set(false); panelControlClick.emit()\">\r\n Panel de control\r\n </button>\r\n }\r\n <button class=\"dropdown-item py-3 fs-7 fw-4 border-bottom-radius\" (click)=\"userMenuOpen.set(false); logout.emit()\"><i\r\n class=\"fas fa-power-off\"></i> Cerrar sesi\u00F3n</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\"\r\n [style.borderLeftColor]=\"accentColor()\" [style.--tooltip-accent]=\"accentColor()\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\" [style.color]=\"accentColor()\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".header-container{height:50px;display:flex;align-items:center;transition:position .5s ease-in-out,background-color .2s ease;padding:0;margin:0;position:relative;--header-accent: #398bf7;background:var(--header-accent);border-bottom:2px solid transparent}.header-container.dev{--header-accent: rgb(197, 0, 72)}.header-container.prod{--header-accent: #398bf7}.header-container.qa{--header-accent: #20c997}:host-context(.dark-mode) .header-container,:host-context(.sky-blue-mode) .header-container,:host-context(.high-contrast-green-mode) .header-container,:host-context(.purple-mode) .header-container{background:var(--header-bg);border-bottom-color:var(--header-accent)}.first-header{display:flex;align-items:center;gap:6px}.empresa-nombre{max-width:350px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:1.25;max-height:2.5em;max-width:100%}@media(max-width:575px){.empresa-nombre{display:none!important}.first-header{min-width:auto!important;padding:10px!important}}@media(min-width:576px)and (max-width:1180px){.first-header{padding:10px!important}}@media(min-width:1181px){.first-header{min-width:260px;width:260px;padding:15px}}.bg-gray-user-data{background:var(--background-btn-light)}.dropdown-menu{transform-origin:top;background-color:var(--background-card);border-color:var(--border-color-modal);color:var(--text-color)}.dropdown-menu-end{right:0!important;left:auto!important}.dropdown-item{color:var(--text-color)}.dropdown-item:hover,.dropdown-item:focus{background-color:var(--bs-table-hover-bg);color:var(--text-color)}.dropdown-menu.show{animation:dropdownMenuIn .24s cubic-bezier(.2,0,.2,1) both}@keyframes dropdownMenuIn{0%{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}.dropdown-menu{width:300px!important;min-width:300px!important}.circle-icon{min-height:30px;min-width:30px;height:30px;width:30px;border-radius:100%;border:2px solid white}.none-style{background:none;border:none}.sidebar-toggle-btn{display:flex;align-items:center;gap:4px}.sidebar-toggle-btn i{transition:transform .25s cubic-bezier(.4,0,.2,1)}.sidebar-toggle-btn i.flipped{transform:scaleX(-1)}.sidebar-toggle-btn .toggle-arrow{font-size:9px;color:#fff}.z-index{z-index:1001}.option{position:relative;border-radius:50px;width:33px;height:100%;transition:background-color .3s ease}.option:hover,.dropdown.show .option{background-color:var(--bs-table-hover-bg)!important}.custom-dropdown.dropdown-menu{min-width:unset!important;width:auto!important}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid;display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--tooltip-accent, #c50048)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.btn-print{border:1px solid rgba(0,0,0,.5764705882)!important;width:33px;height:30px!important;border-radius:6px}.btn-print:hover{border:1px solid rgba(61,61,61,.5254901961)!important;background-color:#dadadaf8!important}.btn-search{width:40px;height:31px!important;border-radius:6px}.logo-btn{width:25px;height:25px;object-fit:contain}.btn-deudas{background:#fff;border-radius:20px;border:none;white-space:nowrap;flex-shrink:0}.btn-deudas.titilando{animation:bordeTitilante 1s infinite alternate}@keyframes bordeTitilante{0%{box-shadow:0 0 2px red}50%{box-shadow:0 0 5px red,0 0 5px #ff4d4d}to{box-shadow:0 0 2px red}}@media(max-width:1100px){.btn-deudas{width:31px;height:31px!important;border-radius:50px;padding:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.btn-deudas .texto-deudas{display:none}.btn-deudas .logo-btn{width:20px;height:20px;margin:0}}@keyframes icon-rotate-pop{0%{transform:rotate(0) scale(1)}25%{transform:rotate(10deg) scale(1.05)}50%{transform:rotate(-10deg) scale(1.1)}75%{transform:rotate(10deg) scale(1.05)}to{transform:rotate(0) scale(1)}}.button-icon-hover{display:inline-block}.button-tilt-hover:hover .button-icon-hover{animation:icon-rotate-pop 1s ease-in-out infinite}.desktop-only{display:flex}@media(max-width:667px){.desktop-only{display:none!important}}.notification-btn{position:relative;border:none;background:none;padding:0;margin-right:8px;cursor:pointer;width:33px;height:32px;display:flex;align-items:center;justify-content:center}.notification-btn i{color:#fff}.notification-badge{position:absolute;top:-5px;right:-3px;color:#fff;font-size:11px;font-weight:600;border-radius:4px;min-width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0 4px}.header-side{flex:0 1 auto;min-width:0}.header-side--end{justify-content:flex-end}.global-search-trigger{position:absolute;left:50%;transform:translate(-50%);z-index:2;align-self:center;flex-shrink:0;margin:0;gap:8px;height:31px;width:280px;padding:0 6px 0 12px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:12px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.global-search-trigger:hover,.global-search-trigger:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.global-search-trigger .global-search-icon{font-size:12px;color:#ffffffbf}.global-search-trigger .global-search-placeholder{flex-grow:1;text-align:start}.global-search-trigger .global-search-kbd{font-size:10px;font-weight:600;line-height:1;padding:3px 5px;border-radius:4px;background:#fff3;border:1px solid rgba(255,255,255,.35);color:#fff}.global-search-trigger--collapsed{display:none!important}.global-search-compact-pill{display:flex;align-items:center;justify-content:center;height:31px;margin-right:8px;padding:0 9px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:11px;font-weight:700;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.global-search-compact-pill:hover,.global-search-compact-pill:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.tabs-header-btn{display:flex;align-items:center;gap:4px;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);color:#fff9;border-radius:20px;padding:3px 8px;font-size:11px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}.tabs-header-btn:hover{background:#fff3;color:#fff}.tabs-header-btn--active{background:#ffffff2e;color:#fff;border-color:#ffffff4d}.tabs-header-btn i{font-size:12px}.tabs-header-count{font-weight:700;font-size:11px;background:#fff3;border-radius:10px;padding:0 5px;min-width:16px;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
740
742
|
}
|
|
741
743
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: VerticalHeaderComponent, decorators: [{
|
|
742
744
|
type: Component,
|
|
743
|
-
args: [{ selector: 'app-vertical-header', imports: [CommonModule], template: "<div #headerContainer class=\"d-flex header-container\" [ngClass]=\"envClass()\">\r\n <div class=\"first-header d-none d-md-flex\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" width=\"40px\" height=\"40px\" style=\"cursor:pointer\"\r\n (click)=\"goToHome()\" title=\"Ir a Home\">\r\n <span class=\"text-white empresa-nombre ps-2\" [title]=\"versionApp()\">{{empresaName()}}</span>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 h-100 justify-content-between align-items-center pe-3 ps-0\">\r\n <div #headerSideStart class=\"d-flex align-items-center header-side\">\r\n <button class=\"btn text-white none-style sidebar-toggle-btn\" (click)=\"emitirToogle.emit()\">\r\n <i class=\"fa-solid fa-table-columns\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n <i class=\"fa-solid fa-chevron-left toggle-arrow\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n </button>\r\n <span class=\"text-white empresa-nombre d-inline d-md-none ps-2\">{{empresaName()}}</span>\r\n <span class=\"text-white fs-5 fw-normal d-none d-md-inline ps-2 text-nowrap\">{{nameProyecto()}}</span>\r\n @if (showTabs() && tabsService.tabs().length) {\r\n <button class=\"tabs-header-btn mx-2 d-none d-md-flex\"\r\n [class.tabs-header-btn--active]=\"tabsService.visible()\" (click)=\"tabsService.toggleVisible()\"\r\n [title]=\"tabsService.visible() ? 'Ocultar acceso r\u00E1pido' : 'Mostrar acceso r\u00E1pido'\">\r\n <i class=\"fas fa-layer-group\"></i>\r\n @if (!tabsService.visible()) {\r\n <span class=\"tabs-header-count\">{{ tabsService.tabs().length }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSearch()) {\r\n <button class=\"global-search-trigger d-none d-md-flex align-items-center\"\r\n [class.global-search-trigger--collapsed]=\"searchCollapsed()\" title=\"B\u00FAsqueda de p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">\r\n <i class=\"fas fa-search global-search-icon\"></i>\r\n <span class=\"global-search-placeholder\">Buscar p\u00E1ginas...</span>\r\n <kbd class=\"global-search-kbd\">F2</kbd>\r\n </button>\r\n }\r\n\r\n <div #headerSideEnd class=\"d-flex align-items-center header-side header-side--end\">\r\n\r\n <!-- Fallback del buscador centrado cuando no entra (colisi\u00F3n) o en mobile\r\n (el buscador centrado se oculta por completo por debajo de md): la\r\n p\u00EDldora de texto \"F2\", igual que antes. -->\r\n <div #compactSearchWrapper class=\"h-100 d-flex align-items-center\">\r\n @if (showSearch() && searchCollapsed()) {\r\n <button class=\"global-search-compact-pill\" title=\"Buscar p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">F2</button>\r\n }\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[extra-actions]\" />\r\n\r\n <!-- Acciones adicionales, definidas por el consumidor: siempre a la izquierda\r\n de los tres fijos (tema, notificaciones, soporte). Solo se ocultan en mobile\r\n las que adem\u00E1s se reflejan en el bottom-nav (showInBottomNav) \u2014 si una acci\u00F3n\r\n no baja al bottom-nav, se queda visible ac\u00E1 para no desaparecer del todo. -->\r\n @for (action of actions(); track action.label) {\r\n @if (!action.hidden) {\r\n @if (action.items?.length) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"openActionKey() === action.label\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"toggleActionMenu($event, action)\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"openActionKey() === action.label\">\r\n @for (opcion of action.items; track opcion.label; let last = $last) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4\"\r\n [ngClass]=\"{'divider-border': !last,'border-top-radius': $index == 0,'border-bottom-radius': last}\"\r\n (click)=\"runAction(opcion)\"\r\n (mouseenter)=\"showTooltip($event, opcion.title ?? '')\" (mouseleave)=\"hideTooltip()\">\r\n <i [class]=\"opcion.icon\" class=\"me-1\"></i> {{ opcion.label }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"h-100 d-flex align-items-center\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.()\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n @if (action.badge) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ action.badge }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showThemeSwitcher()) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"themeMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" (click)=\"toggleThemeMenu($event)\"\r\n [title]=\"'Tema: ' + themeLabel()\">\r\n <i class=\"fas text-white\" [ngClass]=\"themeIcon()\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"themeMenuOpen()\">\r\n @for (item of themes(); track item.id) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 border-bottom-radius divider-border\"\r\n (click)=\"selectTheme(item.id)\">\r\n <i class=\"fas me-1\" [ngClass]=\"item.icon\"></i> {{ item.label }}\r\n @if (currentTheme() === item.id) {\r\n <i class=\"fas fa-check ms-auto text-success\"></i>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Notificaciones y soporte: \u00EDcono/estilo est\u00E1ndar, siempre visibles tambi\u00E9n en mobile -->\r\n @if (showNotifications()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" title=\"Notificaciones\"\r\n (click)=\"notificationsClick.emit()\">\r\n <i class=\"fas fa-bell text-white\"></i>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ notificationsCount() }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (showChatbotToggle()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\"\r\n [title]=\"chatbotVisible() ? 'Ocultar soporte' : 'Mostrar soporte'\"\r\n (click)=\"chatbotVisibleChange.emit(!chatbotVisible())\">\r\n <i class=\"fas fa-robot text-white\"></i>\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"userMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"border-0 bg-none\" (click)=\"toggleUserMenu($event)\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\" alt=\"\">\r\n </button>\r\n </div>\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0\" [class.show]=\"userMenuOpen()\">\r\n <div\r\n class=\"d-flex no-block align-items-center p-3 divider-border bg-gray-user-data border-top-radius\">\r\n <div class=\"d-flex align-items-center\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\">\r\n <div class=\"ms-2\">\r\n <p class=\"fs-7 my-0 py-0 fw-6\">{{userName()}}</p>\r\n @if (userName().startsWith('DESARROLLADOR')) {\r\n <span class=\"fs-7 fw-bold\">Desarrollador</span>\r\n } @else if (userName().startsWith('SOPORTE')) {\r\n <span class=\"fs-7 fw-bold\">Soporte</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (showPanelControl()) {\r\n <button class=\"dropdown-item py-3 fs-7 fw-4\" (click)=\"userMenuOpen.set(false); panelControlClick.emit()\">\r\n Panel de control\r\n </button>\r\n }\r\n <button class=\"dropdown-item py-3 fs-7 fw-4 border-bottom-radius\" (click)=\"userMenuOpen.set(false); logout.emit()\"><i\r\n class=\"fas fa-power-off\"></i> Cerrar sesi\u00F3n</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\"\r\n [style.borderLeftColor]=\"accentColor()\" [style.--tooltip-accent]=\"accentColor()\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\" [style.color]=\"accentColor()\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".header-container{height:50px;display:flex;align-items:center;transition:position .5s ease-in-out,background-color .2s ease;padding:0;margin:0;position:relative;--header-accent: #398bf7;background:var(--header-accent);border-bottom:2px solid transparent}.header-container.dev{--header-accent: rgb(197, 0, 72)}.header-container.prod{--header-accent: #398bf7}.header-container.qa{--header-accent: #20c997}:host-context(.dark-mode) .header-container,:host-context(.sky-blue-mode) .header-container,:host-context(.high-contrast-green-mode) .header-container,:host-context(.purple-mode) .header-container{background:var(--header-bg);border-bottom-color:var(--header-accent)}.first-header{display:flex;align-items:center;gap:6px}.empresa-nombre{max-width:350px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:1.25;max-height:2.5em;max-width:100%}@media(max-width:575px){.empresa-nombre{display:none!important}.first-header{min-width:auto!important;padding:10px!important}}@media(min-width:576px)and (max-width:1180px){.first-header{padding:10px!important}}@media(min-width:1181px){.first-header{min-width:260px;width:260px;padding:15px}}.bg-gray-user-data{background:var(--background-btn-light)}.dropdown-menu{transform-origin:top;background-color:var(--background-card);border-color:var(--border-color-modal);color:var(--text-color)}.dropdown-menu-end{right:0!important;left:auto!important}.dropdown-item{color:var(--text-color)}.dropdown-item:hover,.dropdown-item:focus{background-color:var(--bs-table-hover-bg);color:var(--text-color)}.dropdown-menu.show{animation:dropdownMenuIn .24s cubic-bezier(.2,0,.2,1) both}@keyframes dropdownMenuIn{0%{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}.dropdown-menu{width:300px!important;min-width:300px!important}.circle-icon{min-height:30px;min-width:30px;height:30px;width:30px;border-radius:100%;border:2px solid white}.none-style{background:none;border:none}.sidebar-toggle-btn{display:flex;align-items:center;gap:4px}.sidebar-toggle-btn i{transition:transform .25s cubic-bezier(.4,0,.2,1)}.sidebar-toggle-btn i.flipped{transform:scaleX(-1)}.sidebar-toggle-btn .toggle-arrow{font-size:9px;color:#fff}.z-index{z-index:1001}.option{position:relative;border-radius:50px;width:33px;height:100%;transition:background-color .3s ease}.option:hover,.dropdown.show .option{background-color:var(--bs-table-hover-bg)!important}.custom-dropdown.dropdown-menu{min-width:unset!important;width:auto!important}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid;display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--tooltip-accent, #c50048)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.btn-print{border:1px solid rgba(0,0,0,.5764705882)!important;width:33px;height:30px!important;border-radius:6px}.btn-print:hover{border:1px solid rgba(61,61,61,.5254901961)!important;background-color:#dadadaf8!important}.btn-search{width:40px;height:31px!important;border-radius:6px}.logo-btn{width:25px;height:25px;object-fit:contain}.btn-deudas{background:#fff;border-radius:20px;border:none;white-space:nowrap;flex-shrink:0}.btn-deudas.titilando{animation:bordeTitilante 1s infinite alternate}@keyframes bordeTitilante{0%{box-shadow:0 0 2px red}50%{box-shadow:0 0 5px red,0 0 5px #ff4d4d}to{box-shadow:0 0 2px red}}@media(max-width:1100px){.btn-deudas{width:31px;height:31px!important;border-radius:50px;padding:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.btn-deudas .texto-deudas{display:none}.btn-deudas .logo-btn{width:20px;height:20px;margin:0}}@keyframes icon-rotate-pop{0%{transform:rotate(0) scale(1)}25%{transform:rotate(10deg) scale(1.05)}50%{transform:rotate(-10deg) scale(1.1)}75%{transform:rotate(10deg) scale(1.05)}to{transform:rotate(0) scale(1)}}.button-icon-hover{display:inline-block}.button-tilt-hover:hover .button-icon-hover{animation:icon-rotate-pop 1s ease-in-out infinite}.desktop-only{display:flex}@media(max-width:667px){.desktop-only{display:none!important}}.notification-btn{position:relative;border:none;background:none;padding:0;margin-right:8px;cursor:pointer;width:33px;height:32px;display:flex;align-items:center;justify-content:center}.notification-btn i{color:#fff}.notification-badge{position:absolute;top:-5px;right:-3px;color:#fff;font-size:11px;font-weight:600;border-radius:4px;min-width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0 4px}.header-side{flex:0 1 auto;min-width:0}.header-side--end{justify-content:flex-end}.global-search-trigger{position:absolute;left:50%;transform:translate(-50%);z-index:2;align-self:center;flex-shrink:0;margin:0;gap:8px;height:31px;width:280px;padding:0 6px 0 12px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:12px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.global-search-trigger:hover,.global-search-trigger:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.global-search-trigger .global-search-icon{font-size:12px;color:#ffffffbf}.global-search-trigger .global-search-placeholder{flex-grow:1;text-align:start}.global-search-trigger .global-search-kbd{font-size:10px;font-weight:600;line-height:1;padding:3px 5px;border-radius:4px;background:#fff3;border:1px solid rgba(255,255,255,.35);color:#fff}.global-search-trigger--collapsed{display:none!important}.global-search-compact-pill{display:flex;align-items:center;justify-content:center;height:31px;margin-right:8px;padding:0 9px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:11px;font-weight:700;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.global-search-compact-pill:hover,.global-search-compact-pill:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.tabs-header-btn{display:flex;align-items:center;gap:4px;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);color:#fff9;border-radius:20px;padding:3px 8px;font-size:11px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}.tabs-header-btn:hover{background:#fff3;color:#fff}.tabs-header-btn--active{background:#ffffff2e;color:#fff;border-color:#ffffff4d}.tabs-header-btn i{font-size:12px}.tabs-header-count{font-weight:700;font-size:11px;background:#fff3;border-radius:10px;padding:0 5px;min-width:16px;text-align:center}\n"] }]
|
|
745
|
+
args: [{ selector: 'app-vertical-header', imports: [CommonModule], template: "<div #headerContainer class=\"d-flex header-container\" [ngClass]=\"envClass()\">\r\n <div class=\"first-header d-none d-md-flex\">\r\n <img src=\"assets/images/logo-tsi-tres.png\" width=\"40px\" height=\"40px\" style=\"cursor:pointer\"\r\n (click)=\"goToHome()\" title=\"Ir a Home\">\r\n <span class=\"text-white empresa-nombre ps-2\" [title]=\"versionApp()\">{{empresaName()}}</span>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 h-100 justify-content-between align-items-center pe-3 ps-0\">\r\n <div #headerSideStart class=\"d-flex align-items-center header-side\">\r\n <button class=\"btn text-white none-style sidebar-toggle-btn\" (click)=\"emitirToogle.emit()\">\r\n <i class=\"fa-solid fa-table-columns\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n <i class=\"fa-solid fa-chevron-left toggle-arrow\" [class.flipped]=\"isSidebarOpen()\"></i>\r\n </button>\r\n <span class=\"text-white empresa-nombre d-inline d-md-none ps-2\">{{empresaName()}}</span>\r\n <span class=\"text-white fs-5 fw-normal d-none d-md-inline ps-2 text-nowrap\">{{nameProyecto()}}</span>\r\n @if (showTabs() && tabsService.tabs().length) {\r\n <button class=\"tabs-header-btn mx-2 d-none d-md-flex\"\r\n [class.tabs-header-btn--active]=\"tabsService.visible()\" (click)=\"tabsService.toggleVisible()\"\r\n [title]=\"tabsService.visible() ? 'Ocultar acceso r\u00E1pido' : 'Mostrar acceso r\u00E1pido'\">\r\n <i class=\"fas fa-layer-group\"></i>\r\n @if (!tabsService.visible()) {\r\n <span class=\"tabs-header-count\">{{ tabsService.tabs().length }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSearch()) {\r\n <button class=\"global-search-trigger d-none d-md-flex align-items-center\"\r\n [class.global-search-trigger--collapsed]=\"searchCollapsed()\" title=\"B\u00FAsqueda de p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">\r\n <i class=\"fas fa-search global-search-icon\"></i>\r\n <span class=\"global-search-placeholder\">Buscar p\u00E1ginas...</span>\r\n <kbd class=\"global-search-kbd\">F2</kbd>\r\n </button>\r\n }\r\n\r\n <div #headerSideEnd class=\"d-flex align-items-center header-side header-side--end\">\r\n\r\n <!-- Fallback del buscador centrado cuando no entra (colisi\u00F3n) o en mobile\r\n (el buscador centrado se oculta por completo por debajo de md): la\r\n p\u00EDldora de texto \"F2\", igual que antes. -->\r\n <div #compactSearchWrapper class=\"h-100 d-flex align-items-center\">\r\n @if (showSearch() && searchCollapsed()) {\r\n <button class=\"global-search-compact-pill\" title=\"Buscar p\u00E1ginas (F2)\"\r\n (click)=\"searchComponents.emit()\">F2</button>\r\n }\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <ng-content select=\"[extra-actions]\" />\r\n\r\n <!-- Acciones adicionales, definidas por el consumidor: siempre a la izquierda\r\n de los tres fijos (tema, notificaciones, soporte). Solo se ocultan en mobile\r\n las que adem\u00E1s se reflejan en el bottom-nav (showInBottomNav) \u2014 si una acci\u00F3n\r\n no baja al bottom-nav, se queda visible ac\u00E1 para no desaparecer del todo. -->\r\n @for (action of actions(); track action.label) {\r\n @if (!action.hidden) {\r\n @if (action.items?.length) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"openActionKey() === action.label\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"toggleActionMenu($event, action)\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"openActionKey() === action.label\">\r\n @for (opcion of action.items; track opcion.label; let last = $last) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 d-flex align-items-center\"\r\n [ngClass]=\"{'divider-border': !last,'border-top-radius': $index == 0,'border-bottom-radius': last}\"\r\n (click)=\"runAction(opcion)\"\r\n (mouseenter)=\"showTooltip($event, opcion.title ?? '')\" (mouseleave)=\"hideTooltip()\">\r\n <i [class]=\"opcion.icon\" class=\"me-1\"></i> {{ opcion.label }}\r\n @if (opcion.value) {\r\n <span class=\"ms-auto ps-3 fw-6\">{{ opcion.value }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"h-100 d-flex align-items-center\" [class.desktop-only]=\"action.showInBottomNav\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" [title]=\"action.label\" (click)=\"action.accion?.()\">\r\n <i class=\"fas text-white\" [ngClass]=\"action.icon\"></i>\r\n @if (action.badge) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ action.badge }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showThemeSwitcher()) {\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"themeMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" (click)=\"toggleThemeMenu($event)\"\r\n [title]=\"'Tema: ' + themeLabel()\">\r\n <i class=\"fas text-white\" [ngClass]=\"themeIcon()\"></i>\r\n </button>\r\n </div>\r\n\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0 custom-dropdown\" [class.show]=\"themeMenuOpen()\">\r\n @for (item of themes(); track item.id) {\r\n <button class=\"dropdown-item py-2 fs-7 fw-4 border-bottom-radius divider-border\"\r\n (click)=\"selectTheme(item.id)\">\r\n <i class=\"fas me-1\" [ngClass]=\"item.icon\"></i> {{ item.label }}\r\n @if (currentTheme() === item.id) {\r\n <i class=\"fas fa-check ms-auto text-success\"></i>\r\n }\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Notificaciones y soporte: \u00EDcono/estilo est\u00E1ndar, siempre visibles tambi\u00E9n en mobile -->\r\n @if (showNotifications()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\" title=\"Notificaciones\"\r\n (click)=\"notificationsClick.emit()\">\r\n <i class=\"fas fa-bell text-white\"></i>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"notification-badge\" [ngClass]=\"produccion() ? 'bg-danger' : 'bg-info'\">\r\n {{ notificationsCount() }}\r\n </span>\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n @if (showChatbotToggle()) {\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"notification-btn option p-0 m-0 me-2\"\r\n [title]=\"chatbotVisible() ? 'Ocultar soporte' : 'Mostrar soporte'\"\r\n (click)=\"chatbotVisibleChange.emit(!chatbotVisible())\">\r\n <i class=\"fas fa-robot text-white\"></i>\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"dropdown d-inline-block z-index\" [class.show]=\"userMenuOpen()\">\r\n <div class=\"h-100 d-flex align-items-center\">\r\n <button class=\"border-0 bg-none\" (click)=\"toggleUserMenu($event)\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\" alt=\"\">\r\n </button>\r\n </div>\r\n <div class=\"dropdown-menu dropdown-menu-end mtp-9 mb-0 py-0\" [class.show]=\"userMenuOpen()\">\r\n <div\r\n class=\"d-flex no-block align-items-center p-3 divider-border bg-gray-user-data border-top-radius\">\r\n <div class=\"d-flex align-items-center\">\r\n <img class=\"circle-icon shadow-sm\" src=\"assets/images/admin-avatar.png\">\r\n <div class=\"ms-2\">\r\n <p class=\"fs-7 my-0 py-0 fw-6\">{{userName()}}</p>\r\n @if (userName().startsWith('DESARROLLADOR')) {\r\n <span class=\"fs-7 fw-bold\">Desarrollador</span>\r\n } @else if (userName().startsWith('SOPORTE')) {\r\n <span class=\"fs-7 fw-bold\">Soporte</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (showPanelControl()) {\r\n <button class=\"dropdown-item py-3 fs-7 fw-4\" (click)=\"userMenuOpen.set(false); panelControlClick.emit()\">\r\n Panel de control\r\n </button>\r\n }\r\n <button class=\"dropdown-item py-3 fs-7 fw-4 border-bottom-radius\" (click)=\"userMenuOpen.set(false); logout.emit()\"><i\r\n class=\"fas fa-power-off\"></i> Cerrar sesi\u00F3n</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n@if (tooltip()?.text) {\r\n<div class=\"acceso-tooltip-fixed\" [style.left.px]=\"tooltip()!.x\" [style.top.px]=\"tooltip()!.y\"\r\n [style.borderLeftColor]=\"accentColor()\" [style.--tooltip-accent]=\"accentColor()\">\r\n <span class=\"tooltip-label\">{{ tooltip()!.text.split(': ')[0] }}:</span>\r\n <span class=\"tooltip-value\" [style.color]=\"accentColor()\">{{ tooltip()!.text.split(': ')[1] }}</span>\r\n</div>\r\n}\r\n", styles: [".header-container{height:50px;display:flex;align-items:center;transition:position .5s ease-in-out,background-color .2s ease;padding:0;margin:0;position:relative;--header-accent: #398bf7;background:var(--header-accent);border-bottom:2px solid transparent}.header-container.dev{--header-accent: rgb(197, 0, 72)}.header-container.prod{--header-accent: #398bf7}.header-container.qa{--header-accent: #20c997}:host-context(.dark-mode) .header-container,:host-context(.sky-blue-mode) .header-container,:host-context(.high-contrast-green-mode) .header-container,:host-context(.purple-mode) .header-container{background:var(--header-bg);border-bottom-color:var(--header-accent)}.first-header{display:flex;align-items:center;gap:6px}.empresa-nombre{max-width:350px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:1.25;max-height:2.5em;max-width:100%}@media(max-width:575px){.empresa-nombre{display:none!important}.first-header{min-width:auto!important;padding:10px!important}}@media(min-width:576px)and (max-width:1180px){.first-header{padding:10px!important}}@media(min-width:1181px){.first-header{min-width:260px;width:260px;padding:15px}}.bg-gray-user-data{background:var(--background-btn-light)}.dropdown-menu{transform-origin:top;background-color:var(--background-card);border-color:var(--border-color-modal);color:var(--text-color)}.dropdown-menu-end{right:0!important;left:auto!important}.dropdown-item{color:var(--text-color)}.dropdown-item:hover,.dropdown-item:focus{background-color:var(--bs-table-hover-bg);color:var(--text-color)}.dropdown-menu.show{animation:dropdownMenuIn .24s cubic-bezier(.2,0,.2,1) both}@keyframes dropdownMenuIn{0%{opacity:0;transform:translateY(10px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}.dropdown-menu{width:300px!important;min-width:300px!important}.circle-icon{min-height:30px;min-width:30px;height:30px;width:30px;border-radius:100%;border:2px solid white}.none-style{background:none;border:none}.sidebar-toggle-btn{display:flex;align-items:center;gap:4px}.sidebar-toggle-btn i{transition:transform .25s cubic-bezier(.4,0,.2,1)}.sidebar-toggle-btn i.flipped{transform:scaleX(-1)}.sidebar-toggle-btn .toggle-arrow{font-size:9px;color:#fff}.z-index{z-index:1001}.option{position:relative;border-radius:50px;width:33px;height:100%;transition:background-color .3s ease}.option:hover,.dropdown.show .option{background-color:var(--bs-table-hover-bg)!important}.custom-dropdown.dropdown-menu{min-width:unset!important;width:auto!important}.acceso-tooltip-fixed{position:fixed;z-index:99999;transform:translateY(-50%);pointer-events:none;padding:4px 10px 4px 8px;border-radius:6px;font-family:monospace;white-space:nowrap;background:#0f0f14;border:1px solid rgba(255,255,255,.07);border-left:2px solid;display:flex;align-items:center;gap:5px;animation:tooltipFadeIn .14s cubic-bezier(.25,.46,.45,.94)}.acceso-tooltip-fixed:before{content:\"\";position:absolute;right:100%;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--tooltip-accent, #c50048)}.acceso-tooltip-fixed .tooltip-label{font-size:10px;font-weight:400;color:#fff;letter-spacing:.3px}.acceso-tooltip-fixed .tooltip-value{font-size:11px;font-weight:700}@keyframes tooltipFadeIn{0%{opacity:0;transform:translateY(-50%) translate(-4px)}to{opacity:1;transform:translateY(-50%) translate(0)}}.btn-print{border:1px solid rgba(0,0,0,.5764705882)!important;width:33px;height:30px!important;border-radius:6px}.btn-print:hover{border:1px solid rgba(61,61,61,.5254901961)!important;background-color:#dadadaf8!important}.btn-search{width:40px;height:31px!important;border-radius:6px}.logo-btn{width:25px;height:25px;object-fit:contain}.btn-deudas{background:#fff;border-radius:20px;border:none;white-space:nowrap;flex-shrink:0}.btn-deudas.titilando{animation:bordeTitilante 1s infinite alternate}@keyframes bordeTitilante{0%{box-shadow:0 0 2px red}50%{box-shadow:0 0 5px red,0 0 5px #ff4d4d}to{box-shadow:0 0 2px red}}@media(max-width:1100px){.btn-deudas{width:31px;height:31px!important;border-radius:50px;padding:0;display:flex;align-items:center;justify-content:center;aspect-ratio:1/1}.btn-deudas .texto-deudas{display:none}.btn-deudas .logo-btn{width:20px;height:20px;margin:0}}@keyframes icon-rotate-pop{0%{transform:rotate(0) scale(1)}25%{transform:rotate(10deg) scale(1.05)}50%{transform:rotate(-10deg) scale(1.1)}75%{transform:rotate(10deg) scale(1.05)}to{transform:rotate(0) scale(1)}}.button-icon-hover{display:inline-block}.button-tilt-hover:hover .button-icon-hover{animation:icon-rotate-pop 1s ease-in-out infinite}.desktop-only{display:flex}@media(max-width:667px){.desktop-only{display:none!important}}.notification-btn{position:relative;border:none;background:none;padding:0;margin-right:8px;cursor:pointer;width:33px;height:32px;display:flex;align-items:center;justify-content:center}.notification-btn i{color:#fff}.notification-badge{position:absolute;top:-5px;right:-3px;color:#fff;font-size:11px;font-weight:600;border-radius:4px;min-width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0 4px}.header-side{flex:0 1 auto;min-width:0}.header-side--end{justify-content:flex-end}.global-search-trigger{position:absolute;left:50%;transform:translate(-50%);z-index:2;align-self:center;flex-shrink:0;margin:0;gap:8px;height:31px;width:280px;padding:0 6px 0 12px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:12px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.global-search-trigger:hover,.global-search-trigger:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.global-search-trigger .global-search-icon{font-size:12px;color:#ffffffbf}.global-search-trigger .global-search-placeholder{flex-grow:1;text-align:start}.global-search-trigger .global-search-kbd{font-size:10px;font-weight:600;line-height:1;padding:3px 5px;border-radius:4px;background:#fff3;border:1px solid rgba(255,255,255,.35);color:#fff}.global-search-trigger--collapsed{display:none!important}.global-search-compact-pill{display:flex;align-items:center;justify-content:center;height:31px;margin-right:8px;padding:0 9px;background:#ffffff26;border:1px solid rgba(255,255,255,.3);border-radius:6px;color:#ffffffe6;font-size:11px;font-weight:700;cursor:pointer;transition:background .15s,border-color .15s,color .15s}.global-search-compact-pill:hover,.global-search-compact-pill:focus-visible{background:#ffffff47;border-color:#ffffff80;color:#fff}.tabs-header-btn{display:flex;align-items:center;gap:4px;background:#ffffff1a;border:1px solid rgba(255,255,255,.15);color:#fff9;border-radius:20px;padding:3px 8px;font-size:11px;cursor:pointer;transition:background .15s,color .15s;white-space:nowrap}.tabs-header-btn:hover{background:#fff3;color:#fff}.tabs-header-btn--active{background:#ffffff2e;color:#fff;border-color:#ffffff4d}.tabs-header-btn i{font-size:12px}.tabs-header-count{font-weight:700;font-size:11px;background:#fff3;border-radius:10px;padding:0 5px;min-width:16px;text-align:center}\n"] }]
|
|
744
746
|
}], propDecorators: { headerContainerRef: [{
|
|
745
747
|
type: ViewChild,
|
|
746
748
|
args: ['headerContainer']
|