import { Component, inject, signal, OnInit, OnDestroy, Renderer2 } from '@angular/core'; import { Router, RouterModule } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { Subscription, map } from 'rxjs'; import { StateStorageService } from 'app/core/auth/state-storage.service'; import SharedModule from 'app/shared/shared.module'; import HasAnyAuthorityDirective from 'app/shared/auth/has-any-authority.directive'; import { VERSION } from 'app/app.constants'; import { LANGUAGES } from 'app/config/language.constants'; import { AccountService } from 'app/core/auth/account.service'; import { LoginService } from 'app/login/login.service'; import { ProfileService } from 'app/layouts/profiles/profile.service'; import { EntityNavbarItems } from 'app/entities/entity-navbar-items'; import ActiveMenuDirective from './active-menu.directive'; import NavbarItem from './navbar-item.model'; import {ResilientOrganizationsComponent} from 'app/resilient/resilient-environment/organizations/resilient-organizations.component' import { DocumentService } from 'app/entities/document/service/document.service'; import { IDocument } from 'app/entities/document/document.model'; import { HttpResponse } from '@angular/common/http'; import { DataUtils } from 'app/core/util/data-util.service'; import { Resources } from 'app/security/resources.model'; import { SecurityPermission } from 'app/security/security-permission.model'; import { SecurityAction } from 'app/security/security-action.model'; @Component({ standalone: true, selector: 'jhi-navbar', templateUrl: './navbar.component.html', styleUrl: './navbar.component.scss', imports: [RouterModule, SharedModule, HasAnyAuthorityDirective, ActiveMenuDirective, ResilientOrganizationsComponent], }) export default class NavbarComponent implements OnInit, OnDestroy { private authSubscription?: Subscription; inProduction?: boolean; isNavbarCollapsed = signal(true); languages = LANGUAGES; openAPIEnabled?: boolean; version = ''; entitiesNavbarItems: NavbarItem[] = []; documents?: IDocument[]; private loginService = inject(LoginService); private translateService = inject(TranslateService); private stateStorageService = inject(StateStorageService); private profileService = inject(ProfileService); private router = inject(Router); private accountService = inject(AccountService); private documentService = inject(DocumentService); protected dataUtils = inject(DataUtils); account = this.accountService.trackCurrentAccount(); /** * This makes the enum accessible in the template * Use it, mainly, in html templates for security. * Example: * */ Resources = Resources; constructor(private renderer: Renderer2) { if (VERSION) { this.version = VERSION.toLowerCase().startsWith('v') ? VERSION : `v${VERSION}`; } } ngOnInit(): void { this.entitiesNavbarItems = EntityNavbarItems; this.profileService.getProfileInfo().subscribe(profileInfo => { this.inProduction = profileInfo.inProduction; this.openAPIEnabled = profileInfo.openAPIEnabled; }); this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => { if (account) { this.renderer.addClass(document.body, 'authenticated'); if (!this.documents || this.documents.length==0) { // Only when user is authenticated. And if documents[] NOT already loaded. // NOTE: Before, I was doing it always, for unauthenticated users it failed (security) and redirected him to login page. THIS is not intended, // the user must be hable to access public anonymous HOME page. this.loadDocuments(); } } else { this.renderer.removeClass(document.body, 'authenticated'); } }); // add 'navbar-present' class this.renderer.addClass(document.body, 'navbar-present'); } ngOnDestroy(): void { this.authSubscription?.unsubscribe(); // Remove class this.renderer.removeClass(document.body, 'navbar-present'); } changeLanguage(languageKey: string): void { this.stateStorageService.storeLocale(languageKey); this.translateService.use(languageKey); } collapseNavbar(): void { this.isNavbarCollapsed.set(true); } login(): void { this.router.navigate(['/login']); } logout(): void { this.collapseNavbar(); this.loginService.logout(); this.router.navigate(['']); } toggleNavbar(): void { this.isNavbarCollapsed.update(isNavbarCollapsed => !isNavbarCollapsed); } hasRole(role: string): boolean { return this.accountService.hasAnyAuthority([role]); } hasReadPermission(evalResource: Resources): boolean { const allowPermissions = [SecurityPermission.ALL, SecurityPermission.HIERARCHY]; return allowPermissions.includes(this.accountService.getPermission(evalResource, SecurityAction.READ)); } openFile(base64String: string, contentType: string | null | undefined): void { this.dataUtils.openFile(base64String, contentType); } protected loadDocuments(): void { const queryObject: any = { eagerload: true, }; // Load documents this.documentService .query(queryObject) .pipe( map((res: HttpResponse) => res.body ?? []) ).subscribe({ next: (docs: IDocument[]) => { this.documents = docs; }, });; } }