graphdb-workbench
Version:
The web application for GraphDB APIs
1 lines • 8.65 kB
JavaScript
import{Fragment,h,Host}from"@stencil/core";import{NavbarToggledEvent}from"./navbar-toggled-event";import{NavbarService}from"./navbar-service";import{NavbarModel}from"./navbar-model";import{TranslationService}from"../../services/translation.service";import{EventName,EventService,getCurrentRoute,isHomePage,navigateTo,ProductInfoContextService,navigate,ServiceProvider,SubscriptionList}from"../../../../../api/dist/ontotext-workbench-api";const labelKeys={EXPAND:"menu.buttons.expand",COLLAPSE:"menu.buttons.collapse",LOGO_LINK:"menu.logo.link.title"};export class OntoNavbar{constructor(){this.productInfoContextService=ServiceProvider.get(ProductInfoContextService),this.subscriptions=new SubscriptionList,this.resizeHandler=()=>this.adjustAllSubmenus(this.hostElement),this.SUBMENU_VERTICAL_MARGIN=8,this.MIN_SUBMENU_HEIGHT=100,this.labels={[labelKeys.EXPAND]:TranslationService.translate(labelKeys.EXPAND),[labelKeys.COLLAPSE]:TranslationService.translate(labelKeys.COLLAPSE),[labelKeys.LOGO_LINK]:TranslationService.translate(labelKeys.LOGO_LINK)},this.isCollapsedByUser=!1,this.isCollapsed=!1}navbarCollapsedChange(e){this.isCollapsed=!e,this.isCollapsed&&!this.isCollapsedByUser?this.expandNavbar():this.collapseNavbar(),this.navbarToggled.emit(new NavbarToggledEvent(this.isCollapsed))}menuItemsChanged(e){this.init(e)}init(e){const t=NavbarService.map(e||[],this.productInfo);t.initSelected(getCurrentRoute()),this.menuModel=t}select(e,t){e.preventDefault(),this.clearAllOpenedSubmenuStyles(),t.hasSubmenus()||navigate(t.href),t.children.length?t.open?(this.menuModel.closeAll(),this.menuModel.hasSelectedSubmenu(t)&&this.menuModel.selectItem(t)):(this.menuModel.closeOpened(),this.menuModel.open(t),this.menuModel.hasSelectedSubmenu(t)&&this.menuModel.deselectItem(t)):this.menuModel.closeOtherParents(t),this.isCollapsed&&this.menuModel.isParentOpened(t)&&this.menuModel.closeOpened(),this.refreshNavbar(),this.adjustAllSubmenus(this.hostElement)}subscribeToNavigationEnd(){this.subscriptions.add(ServiceProvider.get(EventService).subscribe(EventName.NAVIGATION_END,()=>{this.selectItemByUrl()}))}selectItemByUrl(){this.menuModel&&(this.menuModel.deselectAll(),this.menuModel.closeAll(),isHomePage()||this.menuModel.initSelected(getCurrentRoute()),this.refreshNavbar(),this.adjustAllSubmenus(this.hostElement))}toggleNavbar(){this.isCollapsed?(this.isCollapsedByUser=!1,this.menuModel.expandSelected(),this.menuModel.unhighlightSelected(),this.expandNavbar(),this.clearAllOpenedSubmenuStyles()):(this.isCollapsedByUser=!0,this.menuModel.highlightSelected(),this.menuModel.closeOpened(),this.collapseNavbar(),this.clearAllOpenedSubmenuStyles()),this.refreshNavbar(),this.adjustAllSubmenus(this.hostElement),this.navbarToggled.emit(new NavbarToggledEvent(this.isCollapsed))}collapseNavbar(){this.hostElement.querySelector(".navbar-component").classList.add("collapsed"),this.isCollapsed=!0}expandNavbar(){this.isCollapsedByUser||(this.hostElement.querySelector(".navbar-component").classList.remove("collapsed"),this.isCollapsed=!1)}refreshNavbar(){var e;(null===(e=this.menuModel)||void 0===e?void 0:e.items)&&(this.menuModel=new NavbarModel(this.menuModel.items))}onLanguageChanged(){this.refreshNavbar()}onTranslate(e){this.subscriptions.add(TranslationService.onTranslate(e,[],t=>{this.labels[e]=t,this.onLanguageChanged()}))}toggleNavbarHandler(){return()=>this.toggleNavbar()}adjustSubmenuMaxHeight(e,t=this.SUBMENU_VERTICAL_MARGIN){if(!e||"function"!=typeof e.getBoundingClientRect)return;const s=e.closest(".menu-element");if(!s)return;const l=e.getBoundingClientRect(),n=s.getBoundingClientRect(),a=window.innerHeight,o=n.top-t+n.height,i=a-n.bottom+n.height-t;let r,h=!1;i>=l.height?r=i:o>=l.height?(r=o,h=!0):i>o?(r=i,h=!1):(r=o,h=!0),h?(e.style.bottom="0",e.style.top="auto"):(e.style.top="0",e.style.bottom="auto"),e.style.maxHeight=`${Math.max(this.MIN_SUBMENU_HEIGHT,r)}px`,e.style.overflowY="auto"}adjustAllSubmenus(e,t=this.SUBMENU_VERTICAL_MARGIN){requestAnimationFrame(()=>{e&&"function"==typeof e.querySelectorAll&&this.getAllOpenedSubmenus(e).forEach(e=>this.adjustSubmenuMaxHeight(e,t))})}getAllOpenedSubmenus(e){return Array.from(e.querySelectorAll(".navbar-component.collapsed .menu-element.open .sub-menu"))}getAllSubmenus(e){return Array.from(e.querySelectorAll(".navbar-component .menu-element .sub-menu"))}clearAllOpenedSubmenuStyles(){this.getAllSubmenus(this.hostElement).forEach(e=>{e.style.maxHeight="",e.style.overflowY="",e.style.top="",e.style.bottom=""})}componentWillLoad(){this.init(this.menuItems)}connectedCallback(){this.subscribeToNavigationEnd(),this.subscribeToProductInfoChanges(),this.onTranslate(labelKeys.EXPAND),this.onTranslate(labelKeys.COLLAPSE),this.onTranslate(labelKeys.LOGO_LINK),window.addEventListener("resize",this.resizeHandler)}disconnectedCallback(){this.subscriptions.unsubscribeAll(),window.removeEventListener("resize",this.resizeHandler)}handleSelectMenuItem(e){return t=>{this.select(t,e)}}render(){if(this.menuModel)return h(Host,null,h("ul",{class:"navbar-component"},h("li",{class:"brand"},h("span",{class:"toggle-menu",title:this.isCollapsed?this.labels[labelKeys.EXPAND]:this.labels[labelKeys.COLLAPSE],onClick:this.toggleNavbarHandler()},h("em",{class:this.isCollapsed?"icon-caret-right":"icon-caret-left"})),h("a",{class:"menu-element-root home-page",onClick:navigateTo("./")},h("svg",{class:"big-logo"},h("desc",null,this.labels[labelKeys.LOGO_LINK]),h("use",{href:"assets/graphdb-logo.svg#Layer_1"})),h("svg",{class:"small-logo"},h("desc",null,this.labels[labelKeys.LOGO_LINK]),h("use",{href:"assets/graphdb-logo-sq.svg#Layer_1"})))),this.menuModel.items.map(e=>h("li",{key:e.labelKey,class:{"menu-element":!0,open:e.open},"data-test":e.testSelector,"guide-selector":e.guideSelector},e.children.length>0&&h(Fragment,null,h("div",{class:{"menu-element-root":!0,active:e.selected},onClick:this.handleSelectMenuItem(e)},h("span",{class:`menu-item-icon ${e.icon}`})," ",h("translate-label",{class:"menu-item",labelKey:e.labelKey})),h("ul",{class:"sub-menu"},h("li",{key:e.labelKey,class:"submenu-title"},h("translate-label",{labelKey:e.labelKey})),e.children.map(e=>h("li",{key:e.labelKey,class:{"sub-menu-item":!0,active:e.selected},"data-test":e.testSelector,"guide-selector":e.guideSelector},e.documentationHref?h("a",{class:"sub-menu-link external-link",href:e.href,target:"_blank",rel:"noopener noreferrer"},h("translate-label",{class:"menu-item",labelKey:e.labelKey}),e.icon&&h("span",{class:`text-muted ${e.icon}`})):h("a",{class:"sub-menu-link",href:e.href,onClick:this.handleSelectMenuItem(e)},h("translate-label",{class:"menu-item",labelKey:e.labelKey}),e.icon&&h("span",{class:`text-muted ${e.icon}`})))))),0===e.children.length&&h("a",{class:{"menu-element-root":!0,active:e.selected},href:e.href,onClick:this.handleSelectMenuItem(e)},h("span",{class:`menu-item-icon ${e.icon}`})," ",h("translate-label",{class:"menu-item",labelKey:e.labelKey}))))))}subscribeToProductInfoChanges(){this.subscriptions.add(this.productInfoContextService.onProductInfoChanged(e=>this.productInfo=e))}static get is(){return"onto-navbar"}static get originalStyleUrls(){return{$:["onto-navbar.scss"]}}static get styleUrls(){return{$:["onto-navbar.css"]}}static get properties(){return{navbarCollapsed:{type:"boolean",attribute:"navbar-collapsed",mutable:!1,complexType:{original:"boolean",resolved:"boolean",references:{}},required:!1,optional:!1,docs:{tags:[],text:"Configuration whether the navbar should be collapsed."},getter:!1,setter:!1,reflect:!1},menuItems:{type:"unknown",attribute:"menu-items",mutable:!1,complexType:{original:"ExternalMenuModel",resolved:"ExternalMenuItemsModel[]",references:{ExternalMenuModel:{location:"import",path:"./external-menu-model",id:"src/components/onto-navbar/external-menu-model.ts::ExternalMenuModel"}}},required:!1,optional:!1,docs:{tags:[],text:"Configuration for the menu items model. This is the external model that is used to build the internal model."},getter:!1,setter:!1}}}static get states(){return{menuModel:{},isCollapsed:{}}}static get events(){return[{method:"navbarToggled",name:"navbarToggled",bubbles:!0,cancelable:!0,composed:!0,docs:{tags:[],text:"Event fired when the navbar is toggled."},complexType:{original:"NavbarToggledEvent",resolved:"NavbarToggledEvent",references:{NavbarToggledEvent:{location:"import",path:"./navbar-toggled-event",id:"src/components/onto-navbar/navbar-toggled-event.ts::NavbarToggledEvent"}}}}]}static get elementRef(){return"hostElement"}static get watchers(){return[{propName:"navbarCollapsed",methodName:"navbarCollapsedChange"},{propName:"menuItems",methodName:"menuItemsChanged"}]}}