Initial Project Commit
This commit is contained in:
commit
a6dea9c888
2148 changed files with 173870 additions and 0 deletions
|
@ -0,0 +1,23 @@
|
|||
<div class="d-flex justify-content-center">
|
||||
<div class="col-8">
|
||||
@if (activityDomain) {
|
||||
<div>
|
||||
<h2>
|
||||
@if (_titleI18N) {<span jhiTranslate="{{ _titleI18N }}"></span>}
|
||||
@else if (_title) {<span>{{ _title }}</span>}
|
||||
@else {<span>__ no title __</span>}
|
||||
</h2>
|
||||
|
||||
<hr />
|
||||
|
||||
<jhi-alert-error></jhi-alert-error>
|
||||
|
||||
<jhi-alert></jhi-alert>
|
||||
|
||||
<jhi-activity-progress [activityDomain]="activityDomain"></jhi-activity-progress>
|
||||
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,44 @@
|
|||
// base-layout.component.ts
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { IActivityDomain } from 'app/entities/activity/activity.model';
|
||||
import { ResilientActivityProgressComponent } from 'app/resilient/resilient-activity/progress/resilient-activity-progress.component';
|
||||
|
||||
import SharedModule from 'app/shared/shared.module';
|
||||
|
||||
@Component({
|
||||
standalone: true, // Mark as standalone
|
||||
selector: 'base-detail-layout',
|
||||
templateUrl: './base-detail.component.html',
|
||||
styles: [`
|
||||
.content { padding: 1rem; }
|
||||
`],
|
||||
imports: [
|
||||
SharedModule,
|
||||
ResilientActivityProgressComponent
|
||||
]
|
||||
})
|
||||
export class BaseDetailLayoutComponent {
|
||||
// Use [activityDomain]="entity()" to enable template domain values
|
||||
@Input() activityDomain!: IActivityDomain | null; // The "!" makes this NOT optional. An exception will happen at runtime if not provided
|
||||
|
||||
/*
|
||||
_activityDomain: IActivityDomain | null = null;
|
||||
@Input('activityDomain') set activityDomain(value: IActivityDomain | null) {
|
||||
this._activityDomain = value;
|
||||
}
|
||||
*/
|
||||
|
||||
// Use [title.text]="'My Title'" to provide the text of the title
|
||||
_title: string | undefined;
|
||||
@Input('title.text') set titleText(value: string) {
|
||||
this._title = value;
|
||||
console.log('title.text set to:', value);
|
||||
}
|
||||
|
||||
// Use [title.translate]="app.entity.title" to provide the key for translation
|
||||
_titleI18N: string | undefined;
|
||||
@Input('title.translate') set titleTranslate(value: string) {
|
||||
this._titleI18N = value;
|
||||
console.log('title.translate set to:', value);
|
||||
}
|
||||
}
|
15
src/main/webapp/app/layouts/error/error.component.html
Normal file
15
src/main/webapp/app/layouts/error/error.component.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<span class="hipster img-fluid rounded"></span>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<h1 jhiTranslate="error.title">Página de erro!</h1>
|
||||
|
||||
@if (errorMessage()) {
|
||||
<div class="alert alert-danger">{{ errorMessage() }}</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
45
src/main/webapp/app/layouts/error/error.component.ts
Normal file
45
src/main/webapp/app/layouts/error/error.component.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { Component, inject, signal, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import SharedModule from 'app/shared/shared.module';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'jhi-error',
|
||||
templateUrl: './error.component.html',
|
||||
imports: [SharedModule],
|
||||
})
|
||||
export default class ErrorComponent implements OnInit, OnDestroy {
|
||||
errorMessage = signal<string | undefined>(undefined);
|
||||
errorKey?: string;
|
||||
langChangeSubscription?: Subscription;
|
||||
|
||||
private translateService = inject(TranslateService);
|
||||
private route = inject(ActivatedRoute);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.route.data.subscribe(routeData => {
|
||||
if (routeData.errorMessage) {
|
||||
this.errorKey = routeData.errorMessage;
|
||||
this.getErrorMessageTranslation();
|
||||
this.langChangeSubscription = this.translateService.onLangChange.subscribe(() => this.getErrorMessageTranslation());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.langChangeSubscription) {
|
||||
this.langChangeSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
private getErrorMessageTranslation(): void {
|
||||
this.errorMessage.set('');
|
||||
if (this.errorKey) {
|
||||
this.translateService.get(this.errorKey).subscribe(translatedErrorMessage => {
|
||||
this.errorMessage.set(translatedErrorMessage);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
31
src/main/webapp/app/layouts/error/error.route.ts
Normal file
31
src/main/webapp/app/layouts/error/error.route.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { Routes } from '@angular/router';
|
||||
|
||||
import ErrorComponent from './error.component';
|
||||
|
||||
export const errorRoute: Routes = [
|
||||
{
|
||||
path: 'error',
|
||||
component: ErrorComponent,
|
||||
title: 'error.title',
|
||||
},
|
||||
{
|
||||
path: 'accessdenied',
|
||||
component: ErrorComponent,
|
||||
data: {
|
||||
errorMessage: 'error.http.403',
|
||||
},
|
||||
title: 'error.title',
|
||||
},
|
||||
{
|
||||
path: '404',
|
||||
component: ErrorComponent,
|
||||
data: {
|
||||
errorMessage: 'error.http.404',
|
||||
},
|
||||
title: 'error.title',
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
redirectTo: '/404',
|
||||
},
|
||||
];
|
6
src/main/webapp/app/layouts/footer/footer.component.html
Normal file
6
src/main/webapp/app/layouts/footer/footer.component.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
<span jhiTranslate="copyright">InNOVA-Sistema de Informação em Ambiente e Sustentabilidade da NOVA @2025</span><br>
|
||||
<span jhiTranslate="financed">Co-financiado por Fundo Ambiental</span>
|
||||
</p>
|
||||
</div>
|
10
src/main/webapp/app/layouts/footer/footer.component.ts
Normal file
10
src/main/webapp/app/layouts/footer/footer.component.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { TranslateDirective } from 'app/shared/language';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'jhi-footer',
|
||||
templateUrl: './footer.component.html',
|
||||
imports: [TranslateDirective],
|
||||
})
|
||||
export default class FooterComponent {}
|
|
@ -0,0 +1,6 @@
|
|||
<!-- TOP BANNER -->
|
||||
<section>
|
||||
<div class="container-fluid mb-5 p-0">
|
||||
<img id="home-header" src="content/images/home_banner.jpg" class="img-fluid" alt="Route Zero">
|
||||
</div>
|
||||
</section>
|
|
@ -0,0 +1,8 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'jhi-banner',
|
||||
templateUrl: './banner.component.html',
|
||||
})
|
||||
export class BannerComponent {}
|
12
src/main/webapp/app/layouts/main/main.component.css
Normal file
12
src/main/webapp/app/layouts/main/main.component.css
Normal file
|
@ -0,0 +1,12 @@
|
|||
.main-component-banner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
::ng-deep is needed because .authenticated doesn't belong to main.component, its in the <body> tag
|
||||
ViewEncapsulation prevented this to work. By using ::ng-deep, Angular is forced to evaluate this OUTSIDE
|
||||
ViewEncapsulation
|
||||
*/
|
||||
::ng-deep .authenticated .main-component-banner {
|
||||
display: block;
|
||||
}
|
15
src/main/webapp/app/layouts/main/main.component.html
Normal file
15
src/main/webapp/app/layouts/main/main.component.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<jhi-page-ribbon></jhi-page-ribbon>
|
||||
|
||||
<div>
|
||||
<router-outlet name="navbar"></router-outlet>
|
||||
</div>
|
||||
|
||||
<jhi-banner class="main-component-banner" *ngIf="showBanner"></jhi-banner>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="card jh-card">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
|
||||
<jhi-footer></jhi-footer>
|
||||
</div>
|
230
src/main/webapp/app/layouts/main/main.component.spec.ts
Normal file
230
src/main/webapp/app/layouts/main/main.component.spec.ts
Normal file
|
@ -0,0 +1,230 @@
|
|||
jest.mock('app/core/auth/account.service');
|
||||
|
||||
import { waitForAsync, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
||||
import { Router, TitleStrategy } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
import { of } from 'rxjs';
|
||||
import { TranslateModule, TranslateService, LangChangeEvent } from '@ngx-translate/core';
|
||||
|
||||
import { AccountService } from 'app/core/auth/account.service';
|
||||
|
||||
import { AppPageTitleStrategy } from 'app/app-page-title-strategy';
|
||||
import MainComponent from './main.component';
|
||||
|
||||
describe('MainComponent', () => {
|
||||
let comp: MainComponent;
|
||||
let fixture: ComponentFixture<MainComponent>;
|
||||
let titleService: Title;
|
||||
let translateService: TranslateService;
|
||||
let mockAccountService: AccountService;
|
||||
let ngZone: NgZone;
|
||||
const routerState: any = { snapshot: { root: { data: {} } } };
|
||||
let router: Router;
|
||||
let document: Document;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), MainComponent],
|
||||
providers: [Title, AccountService, { provide: TitleStrategy, useClass: AppPageTitleStrategy }],
|
||||
})
|
||||
.overrideTemplate(MainComponent, '')
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MainComponent);
|
||||
comp = fixture.componentInstance;
|
||||
titleService = TestBed.inject(Title);
|
||||
translateService = TestBed.inject(TranslateService);
|
||||
mockAccountService = TestBed.inject(AccountService);
|
||||
mockAccountService.identity = jest.fn(() => of(null));
|
||||
mockAccountService.getAuthenticationState = jest.fn(() => of(null));
|
||||
ngZone = TestBed.inject(NgZone);
|
||||
router = TestBed.inject(Router);
|
||||
document = TestBed.inject(DOCUMENT);
|
||||
});
|
||||
|
||||
describe('page title', () => {
|
||||
const defaultPageTitle = 'global.title';
|
||||
const parentRoutePageTitle = 'parentTitle';
|
||||
const childRoutePageTitle = 'childTitle';
|
||||
const langChangeEvent: LangChangeEvent = { lang: 'pt-pt', translations: null };
|
||||
|
||||
beforeEach(() => {
|
||||
routerState.snapshot.root = { data: {} };
|
||||
jest.spyOn(translateService, 'get').mockImplementation((key: string | string[]) => of(`${key as string} translated`));
|
||||
translateService.currentLang = 'pt-pt';
|
||||
jest.spyOn(titleService, 'setTitle');
|
||||
comp.ngOnInit();
|
||||
});
|
||||
|
||||
describe('navigation end', () => {
|
||||
it('should set page title to default title if pageTitle is missing on routes', fakeAsync(() => {
|
||||
// WHEN
|
||||
ngZone.run(() => router.navigateByUrl(''));
|
||||
tick();
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(defaultPageTitle + ' translated');
|
||||
}));
|
||||
|
||||
it('should set page title to root route pageTitle if there is no child routes', fakeAsync(() => {
|
||||
// GIVEN
|
||||
router.resetConfig([{ path: '', title: parentRoutePageTitle, component: BlankComponent }]);
|
||||
|
||||
// WHEN
|
||||
ngZone.run(() => router.navigateByUrl(''));
|
||||
tick();
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(parentRoutePageTitle + ' translated');
|
||||
}));
|
||||
|
||||
it('should set page title to child route pageTitle if child routes exist and pageTitle is set for child route', fakeAsync(() => {
|
||||
// GIVEN
|
||||
router.resetConfig([
|
||||
{
|
||||
path: 'home',
|
||||
title: parentRoutePageTitle,
|
||||
children: [{ path: '', title: childRoutePageTitle, component: BlankComponent }],
|
||||
},
|
||||
]);
|
||||
|
||||
// WHEN
|
||||
ngZone.run(() => router.navigateByUrl('home'));
|
||||
tick();
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(childRoutePageTitle + ' translated');
|
||||
}));
|
||||
|
||||
it('should set page title to parent route pageTitle if child routes exists but pageTitle is not set for child route data', fakeAsync(() => {
|
||||
// GIVEN
|
||||
router.resetConfig([
|
||||
{
|
||||
path: 'home',
|
||||
title: parentRoutePageTitle,
|
||||
children: [{ path: '', component: BlankComponent }],
|
||||
},
|
||||
]);
|
||||
|
||||
// WHEN
|
||||
ngZone.run(() => router.navigateByUrl('home'));
|
||||
tick();
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(parentRoutePageTitle + ' translated');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('language change', () => {
|
||||
it('should set page title to default title if pageTitle is missing on routes', () => {
|
||||
// WHEN
|
||||
translateService.onLangChange.emit(langChangeEvent);
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(defaultPageTitle + ' translated');
|
||||
});
|
||||
|
||||
it('should set page title to root route pageTitle if there is no child routes', fakeAsync(() => {
|
||||
// GIVEN
|
||||
routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
|
||||
router.resetConfig([{ path: '', title: parentRoutePageTitle, component: BlankComponent }]);
|
||||
|
||||
// WHEN
|
||||
ngZone.run(() => router.navigateByUrl(''));
|
||||
tick();
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(parentRoutePageTitle + ' translated');
|
||||
|
||||
// GIVEN
|
||||
document.title = 'other title';
|
||||
|
||||
// WHEN
|
||||
translateService.onLangChange.emit(langChangeEvent);
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(parentRoutePageTitle + ' translated');
|
||||
}));
|
||||
|
||||
it('should set page title to child route pageTitle if child routes exist and pageTitle is set for child route', fakeAsync(() => {
|
||||
// GIVEN
|
||||
router.resetConfig([
|
||||
{
|
||||
path: 'home',
|
||||
title: parentRoutePageTitle,
|
||||
children: [{ path: '', title: childRoutePageTitle, component: BlankComponent }],
|
||||
},
|
||||
]);
|
||||
|
||||
// WHEN
|
||||
ngZone.run(() => router.navigateByUrl('home'));
|
||||
tick();
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(childRoutePageTitle + ' translated');
|
||||
|
||||
// GIVEN
|
||||
document.title = 'other title';
|
||||
|
||||
// WHEN
|
||||
translateService.onLangChange.emit(langChangeEvent);
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(childRoutePageTitle + ' translated');
|
||||
}));
|
||||
|
||||
it('should set page title to parent route pageTitle if child routes exists but pageTitle is not set for child route data', fakeAsync(() => {
|
||||
// GIVEN
|
||||
router.resetConfig([
|
||||
{
|
||||
path: 'home',
|
||||
title: parentRoutePageTitle,
|
||||
children: [{ path: '', component: BlankComponent }],
|
||||
},
|
||||
]);
|
||||
|
||||
// WHEN
|
||||
ngZone.run(() => router.navigateByUrl('home'));
|
||||
tick();
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(parentRoutePageTitle + ' translated');
|
||||
|
||||
// GIVEN
|
||||
document.title = 'other title';
|
||||
|
||||
// WHEN
|
||||
translateService.onLangChange.emit(langChangeEvent);
|
||||
|
||||
// THEN
|
||||
expect(document.title).toBe(parentRoutePageTitle + ' translated');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('page language attribute', () => {
|
||||
it('should change page language attribute on language change', () => {
|
||||
// GIVEN
|
||||
comp.ngOnInit();
|
||||
|
||||
// WHEN
|
||||
translateService.onLangChange.emit({ lang: 'lang1', translations: null });
|
||||
|
||||
// THEN
|
||||
expect(document.querySelector('html')?.getAttribute('lang')).toEqual('lang1');
|
||||
|
||||
// WHEN
|
||||
translateService.onLangChange.emit({ lang: 'lang2', translations: null });
|
||||
|
||||
// THEN
|
||||
expect(document.querySelector('html')?.getAttribute('lang')).toEqual('lang2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@Component({ template: '' })
|
||||
export class BlankComponent {}
|
61
src/main/webapp/app/layouts/main/main.component.ts
Normal file
61
src/main/webapp/app/layouts/main/main.component.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { Component, inject, OnInit, RendererFactory2, Renderer2 } from '@angular/core';
|
||||
import { RouterOutlet, Router, NavigationEnd } from '@angular/router';
|
||||
import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
|
||||
import dayjs from 'dayjs/esm';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common'; // Add this!
|
||||
|
||||
import { AccountService } from 'app/core/auth/account.service';
|
||||
import { AppPageTitleStrategy } from 'app/app-page-title-strategy';
|
||||
import FooterComponent from '../footer/footer.component';
|
||||
import PageRibbonComponent from '../profiles/page-ribbon.component';
|
||||
import { BannerComponent } from './banner/banner.component';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'jhi-main',
|
||||
templateUrl: './main.component.html',
|
||||
styleUrl: './main.component.css',
|
||||
providers: [AppPageTitleStrategy],
|
||||
imports: [RouterOutlet, FooterComponent, PageRibbonComponent, CommonModule, BannerComponent],
|
||||
})
|
||||
export default class MainComponent implements OnInit {
|
||||
private renderer: Renderer2;
|
||||
|
||||
private router = inject(Router);
|
||||
private appPageTitleStrategy = inject(AppPageTitleStrategy);
|
||||
private accountService = inject(AccountService);
|
||||
private translateService = inject(TranslateService);
|
||||
private rootRenderer = inject(RendererFactory2);
|
||||
|
||||
showBanner = false;
|
||||
|
||||
constructor() {
|
||||
this.renderer = this.rootRenderer.createRenderer(document.querySelector('html'), null);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// try to log in automatically
|
||||
this.accountService.identity().subscribe();
|
||||
|
||||
this.translateService.onLangChange.subscribe((langChangeEvent: LangChangeEvent) => {
|
||||
this.appPageTitleStrategy.updateTitle(this.router.routerState.snapshot);
|
||||
dayjs.locale(langChangeEvent.lang);
|
||||
this.renderer.setAttribute(document.querySelector('html'), 'lang', langChangeEvent.lang);
|
||||
});
|
||||
|
||||
this.router.events
|
||||
.pipe(filter(event => event instanceof NavigationEnd))
|
||||
.subscribe((event) => {
|
||||
const navEndEvent = event as NavigationEnd; // Explicitly tell TypeScript
|
||||
const isLoggedIn = this.accountService.isAuthenticated();
|
||||
|
||||
// List of routes where the banner should be shown
|
||||
const bannerRoutes = ['/'];
|
||||
|
||||
// Check if current route matches one of the bannerRoutes
|
||||
// For this to work, CSS was needed. See main.component.css
|
||||
this.showBanner = bannerRoutes.some(route => this.router.url === route);
|
||||
});
|
||||
}
|
||||
}
|
30
src/main/webapp/app/layouts/navbar/active-menu.directive.ts
Normal file
30
src/main/webapp/app/layouts/navbar/active-menu.directive.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { Directive, OnInit, ElementRef, Renderer2, inject, input } from '@angular/core';
|
||||
import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
|
||||
|
||||
@Directive({
|
||||
standalone: true,
|
||||
selector: '[jhiActiveMenu]',
|
||||
})
|
||||
export default class ActiveMenuDirective implements OnInit {
|
||||
jhiActiveMenu = input();
|
||||
|
||||
private el = inject(ElementRef);
|
||||
private renderer = inject(Renderer2);
|
||||
private translateService = inject(TranslateService);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
|
||||
this.updateActiveFlag(event.lang);
|
||||
});
|
||||
|
||||
this.updateActiveFlag(this.translateService.currentLang);
|
||||
}
|
||||
|
||||
updateActiveFlag(selectedLanguage: string): void {
|
||||
if (this.jhiActiveMenu() === selectedLanguage) {
|
||||
this.renderer.addClass(this.el.nativeElement, 'active');
|
||||
} else {
|
||||
this.renderer.removeClass(this.el.nativeElement, 'active');
|
||||
}
|
||||
}
|
||||
}
|
7
src/main/webapp/app/layouts/navbar/navbar-item.model.d.ts
vendored
Normal file
7
src/main/webapp/app/layouts/navbar/navbar-item.model.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
type NavbarItem = {
|
||||
name: string;
|
||||
route: string;
|
||||
translationKey: string;
|
||||
};
|
||||
|
||||
export default NavbarItem;
|
622
src/main/webapp/app/layouts/navbar/navbar.component.html
Normal file
622
src/main/webapp/app/layouts/navbar/navbar.component.html
Normal file
|
@ -0,0 +1,622 @@
|
|||
<nav data-cy="navbar" class="navbar navbar-dark navbar-expand-md bg-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand logo" routerLink="/" (click)="collapseNavbar()">
|
||||
<span class="logo-img"></span>
|
||||
<!-- span class="navbar-title" jhiTranslate="global.title">Resilient</span -->
|
||||
<!-- span class="navbar-version">{{ version }}</span -->
|
||||
</a>
|
||||
<a
|
||||
class="navbar-toggler d-lg-none"
|
||||
href="javascript:void(0);"
|
||||
data-toggle="collapse"
|
||||
data-target="#navbarResponsive"
|
||||
aria-controls="navbarResponsive"
|
||||
aria-expanded="false"
|
||||
aria-label="Toggle navigation"
|
||||
(click)="toggleNavbar()"
|
||||
>
|
||||
<fa-icon icon="bars"></fa-icon>
|
||||
</a>
|
||||
<div class="navbar-collapse collapse" id="navbarResponsive" [ngbCollapse]="isNavbarCollapsed()">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
@if (account() !== null) {
|
||||
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
|
||||
<a class="nav-link" routerLink="/" (click)="collapseNavbar()">
|
||||
<span>
|
||||
<fa-icon icon="home"></fa-icon>
|
||||
<span jhiTranslate="global.menu.home">Início</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
<!-- jhipster-needle-add-element-to-menu - JHipster will add new menu items here -->
|
||||
@if (account() !== null) {
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN')
|
||||
||
|
||||
(
|
||||
(hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR') || hasRole('ROLE_USER'))
|
||||
&&
|
||||
hasReadPermission(Resources.OUTPUT_DATA)
|
||||
)"
|
||||
class="nav-item"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a
|
||||
class="nav-link"
|
||||
routerLink="/dashboard/EMISSIONS/1500"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.dashboard.emissions">Emissões</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN')
|
||||
||
|
||||
(
|
||||
(hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR') || hasRole('ROLE_USER'))
|
||||
&&
|
||||
hasReadPermission(Resources.OUTPUT_DATA)
|
||||
)"
|
||||
class="nav-item"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a
|
||||
class="nav-link"
|
||||
routerLink="/dashboard/INDICATORS/1500"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.dashboard.indicators">Indicadores</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN')
|
||||
||
|
||||
(
|
||||
( hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR') || hasRole('ROLE_USER'))
|
||||
&&
|
||||
hasReadPermission(Resources.INPUT_DATA)
|
||||
)"
|
||||
class="nav-item"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a
|
||||
class="nav-link"
|
||||
routerLink="/inventory"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.inventory.main">Dados de Atividade</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN')
|
||||
||
|
||||
(
|
||||
(hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR') || hasRole('ROLE_USER'))
|
||||
&&
|
||||
hasReadPermission(Resources.EMISSION_FACTOR)
|
||||
)"
|
||||
class="nav-item"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a
|
||||
class="nav-link"
|
||||
routerLink="/emission-factor/list"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.emissionFactor.main">Fatores Emissão</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN') || hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR')"
|
||||
ngbDropdown
|
||||
class="nav-item dropdown pointer"
|
||||
display="dynamic"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="entity-menu" data-cy="entity">
|
||||
<span>
|
||||
<fa-icon icon="th-list"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.main">Entidades</span>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="entity-menu">
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || ( hasRole('ROLE_MANAGER') && hasReadPermission(Resources.ORGANIZATION) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/organization"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.organization">Organization</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || ( hasRole('ROLE_MANAGER') && hasReadPermission(Resources.PERIOD) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/period"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.period">Period</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li><div class="dropdown-divider"></div></li>
|
||||
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || (hasRole('ROLE_MANAGER') && hasReadPermission(Resources.UNIT_TYPE) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/unit-type"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.unitType">Unit Type</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || (hasRole('ROLE_MANAGER') && hasReadPermission(Resources.UNIT) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/unit"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.unit">Unit</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || (hasRole('ROLE_MANAGER') && hasReadPermission(Resources.UNIT_CONVERTER) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/unit-converter"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.unitConverter">Unit Converter</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasRole('ROLE_MANAGER')"><div class="dropdown-divider"></div></li>
|
||||
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || (hasRole('ROLE_MANAGER') && hasReadPermission(Resources.VARIABLE_SCOPE) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/variable-scope"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.variableScope">Variable Scope</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || (hasRole('ROLE_MANAGER') && hasReadPermission(Resources.VARIABLE_CATEGORY) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/variable-category"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.variableCategory">Variable Category</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || (hasRole('ROLE_MANAGER') && hasReadPermission(Resources.VARIABLE) )">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/variable"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.variable">Variable</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasRole('ROLE_MANAGER')"><div class="dropdown-divider"></div></li>
|
||||
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN')
|
||||
||
|
||||
(
|
||||
(hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR'))
|
||||
&&
|
||||
hasReadPermission(Resources.INPUT_DATA_UPLOAD)
|
||||
)"
|
||||
>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/input-data-upload"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.inputDataUpload">Input Data Upload</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN')
|
||||
||
|
||||
(
|
||||
( hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR') )
|
||||
&&
|
||||
hasReadPermission(Resources.INPUT_DATA)
|
||||
)"
|
||||
>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/input-data"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.inputData">Input Data</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN')
|
||||
||
|
||||
(
|
||||
(hasRole('ROLE_MANAGER') || hasRole('ROLE_COORDINATOR'))
|
||||
&&
|
||||
hasReadPermission(Resources.OUTPUT_DATA)
|
||||
)"
|
||||
>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/output-data"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.outputData">Output Data</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li
|
||||
*ngIf="hasRole('ROLE_ADMIN') || hasRole('ROLE_MANAGER')"
|
||||
ngbDropdown
|
||||
class="nav-item dropdown pointer"
|
||||
display="dynamic"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="setup-menu" data-cy="entity">
|
||||
<span>
|
||||
<fa-icon icon="th-list"></fa-icon>
|
||||
<span jhiTranslate="global.menu.setup.main">Parametrização</span>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="setup-menu">
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.ORGANIZATION_TYPE)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/organization-type"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.organizationType">Organization Type</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.METADATA_PROPERTY)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/metadata-property"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.metadataProperty">Metadata Property</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.METADATA_VALUE)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/metadata-value"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.metadataValue">Metadata Value</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.VARIABLE_CLASS_TYPE)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/variable-class-type"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.variableClassType">Variable Class Type</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.EMISSION_FACTOR)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/emission-factor"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.emissionFactor">Emission Factors</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.DASHBOARD_COMPONENT)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/dashboard-component"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.dashboardComponent">Dashboard Comp.</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.DOCUMENT)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/document"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.document">Document</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN') || hasReadPermission(Resources.CONTENT_PAGE)">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/content-page"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.contentPage">Content Page</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
<li
|
||||
*jhiHasAnyAuthority="'ROLE_ADMIN'"
|
||||
ngbDropdown
|
||||
class="nav-item dropdown pointer"
|
||||
display="dynamic"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="admin-menu" data-cy="adminMenu">
|
||||
<span>
|
||||
<fa-icon icon="users-cog"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.main">Administração</span>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="admin-menu">
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/authority"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
(click)="collapseNavbar()"
|
||||
>
|
||||
<fa-icon icon="asterisk" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.entities.adminAuthority">Authority</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- jhipster-needle-add-element-to-admin-menu - JHipster will add entities to the admin menu here -->
|
||||
<li>
|
||||
<a class="dropdown-item" routerLink="/admin/user-management" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="users" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.userManagement">Gestão de utilizadores</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" routerLink="/security/security-group" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="users" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.security.securityGroup">Gestão de Permissões</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" routerLink="/admin/metrics" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="tachometer-alt" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.metrics">Métricas</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" routerLink="/admin/health" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="heart" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.health">Estado do Sistema</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" routerLink="/admin/configuration" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="cogs" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.configuration">Configuração</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" routerLink="/admin/logs" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="tasks" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.logs">Logs</span>
|
||||
</a>
|
||||
</li>
|
||||
@if (openAPIEnabled) {
|
||||
<li>
|
||||
<a class="dropdown-item" routerLink="/admin/docs" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="book" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.admin.apidocs">API</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
{{ '' // Disable the language selector}}
|
||||
@if (false && languages && languages.length > 1) {
|
||||
<li ngbDropdown class="nav-item dropdown pointer" display="dynamic">
|
||||
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="languagesnavBarDropdown">
|
||||
<span>
|
||||
<fa-icon icon="flag"></fa-icon>
|
||||
<span jhiTranslate="global.menu.language">Idioma</span>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="languagesnavBarDropdown">
|
||||
@for (language of languages; track $index) {
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
[jhiActiveMenu]="language"
|
||||
href="javascript:void(0);"
|
||||
(click)="changeLanguage(language); collapseNavbar()"
|
||||
>{{ language | findLanguageFromKey }}</a
|
||||
>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
|
||||
@if (account() !== null && documents && documents.length>0) {
|
||||
<li
|
||||
ngbDropdown
|
||||
#myDocumentsDropdown="ngbDropdown"
|
||||
*ngIf="hasRole('ROLE_ADMIN') || hasRole('ROLE_MANAGER') || hasRole('ROLE_USER')"
|
||||
class="nav-item dropdown pointer"
|
||||
display="dynamic"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="documents-menu" data-cy="documentsMenu" title="Documentos de Suporte">
|
||||
<fa-icon class="fa-lg" icon="file-pdf"></fa-icon>
|
||||
<span jhiTranslate="global.menu.documents.main">Ficheiros</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="documents-menu">
|
||||
<li *ngFor="let document of documents">
|
||||
<a
|
||||
(click)="openFile(document!.dataFile ?? '', document!.dataFileContentType); myDocumentsDropdown.close()">
|
||||
<span>{{ document.title }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
|
||||
@if (account() !== null) {
|
||||
<li
|
||||
ngbDropdown
|
||||
class="nav-item dropdown pointer"
|
||||
display="dynamic"
|
||||
routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="account-menu" data-cy="accountMenu">
|
||||
@if (!account()?.imageUrl) {
|
||||
<span>
|
||||
<fa-icon icon="user"></fa-icon>
|
||||
<span jhiTranslate="global.menu.account.main">Conta</span>
|
||||
</span>
|
||||
} @else {
|
||||
<span>
|
||||
<img [src]="account()!.imageUrl" class="profile-image rounded-circle" alt="Avatar" />
|
||||
</span>
|
||||
}
|
||||
</a>
|
||||
<ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="account-menu">
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/account/settings"
|
||||
routerLinkActive="active"
|
||||
(click)="collapseNavbar()"
|
||||
data-cy="settings"
|
||||
>
|
||||
<fa-icon icon="wrench" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.account.settings">Configuração</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
routerLink="/account/password"
|
||||
routerLinkActive="active"
|
||||
(click)="collapseNavbar()"
|
||||
data-cy="passwordItem"
|
||||
>
|
||||
<fa-icon icon="lock" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.account.password">Palavra-passe</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="hasRole('ROLE_ADMIN')">
|
||||
<a class="dropdown-item" routerLink="/account/sessions" routerLinkActive="active" (click)="collapseNavbar()">
|
||||
<fa-icon icon="cloud" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.account.sessions">Sessões</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" (click)="logout()" id="logout" data-cy="logout">
|
||||
<fa-icon icon="sign-out-alt" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.account.logout">Sair</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
} @else {
|
||||
<li>
|
||||
<a class="dropdown-item" (click)="login()" id="login" data-cy="login">
|
||||
<fa-icon icon="user" [fixedWidth]="true"></fa-icon>
|
||||
<span jhiTranslate="global.menu.account.login">Entrar</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
||||
@if (account() !== null) {
|
||||
<jhi-resilient-organizations></jhi-resilient-organizations>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
50
src/main/webapp/app/layouts/navbar/navbar.component.scss
Normal file
50
src/main/webapp/app/layouts/navbar/navbar.component.scss
Normal file
|
@ -0,0 +1,50 @@
|
|||
@import 'bootstrap/scss/functions';
|
||||
@import 'bootstrap/scss/variables';
|
||||
|
||||
/* ==========================================================================
|
||||
Navbar
|
||||
========================================================================== */
|
||||
|
||||
.navbar-version {
|
||||
font-size: 0.65em;
|
||||
color: $navbar-dark-color;
|
||||
}
|
||||
|
||||
.profile-image {
|
||||
height: 1.75em;
|
||||
width: 1.75em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
padding: 0.2rem 1rem;
|
||||
|
||||
a.nav-link {
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Logo styles
|
||||
========================================================================== */
|
||||
.logo-img {
|
||||
height: 45px;
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
background: url('/content/images/logo-nova-group-zero.svg') no-repeat center center;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Fix navbar to top
|
||||
========================================================================== */
|
||||
.navbar {
|
||||
position: fixed; /* Fixes it at the top */
|
||||
top: 0; /* Aligns it to the top */
|
||||
left: 0; /* Ensures it starts from the left */
|
||||
width: 100%; /* Full-width */
|
||||
background-color: #333; /* Example background */
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
z-index: 1000; /* Ensures it stays above other elements */
|
||||
}
|
95
src/main/webapp/app/layouts/navbar/navbar.component.spec.ts
Normal file
95
src/main/webapp/app/layouts/navbar/navbar.component.spec.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
jest.mock('app/login/login.service');
|
||||
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { ProfileInfo } from 'app/layouts/profiles/profile-info.model';
|
||||
import { Account } from 'app/core/auth/account.model';
|
||||
import { AccountService } from 'app/core/auth/account.service';
|
||||
import { ProfileService } from 'app/layouts/profiles/profile.service';
|
||||
import { LoginService } from 'app/login/login.service';
|
||||
|
||||
import NavbarComponent from './navbar.component';
|
||||
|
||||
describe('Navbar Component', () => {
|
||||
let comp: NavbarComponent;
|
||||
let fixture: ComponentFixture<NavbarComponent>;
|
||||
let accountService: AccountService;
|
||||
let profileService: ProfileService;
|
||||
const account: Account = {
|
||||
activated: true,
|
||||
authorities: [],
|
||||
email: '',
|
||||
firstName: 'John',
|
||||
langKey: '',
|
||||
lastName: 'Doe',
|
||||
login: 'john.doe',
|
||||
imageUrl: '',
|
||||
};
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NavbarComponent, HttpClientTestingModule, TranslateModule.forRoot()],
|
||||
providers: [LoginService],
|
||||
})
|
||||
.overrideTemplate(NavbarComponent, '')
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NavbarComponent);
|
||||
comp = fixture.componentInstance;
|
||||
accountService = TestBed.inject(AccountService);
|
||||
profileService = TestBed.inject(ProfileService);
|
||||
});
|
||||
|
||||
it('Should call profileService.getProfileInfo on init', () => {
|
||||
// GIVEN
|
||||
jest.spyOn(profileService, 'getProfileInfo').mockReturnValue(of(new ProfileInfo()));
|
||||
|
||||
// WHEN
|
||||
comp.ngOnInit();
|
||||
|
||||
// THEN
|
||||
expect(profileService.getProfileInfo).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should hold current authenticated user in variable account', () => {
|
||||
// WHEN
|
||||
comp.ngOnInit();
|
||||
|
||||
// THEN
|
||||
expect(comp.account()).toBeNull();
|
||||
|
||||
// WHEN
|
||||
accountService.authenticate(account);
|
||||
|
||||
// THEN
|
||||
expect(comp.account()).toEqual(account);
|
||||
|
||||
// WHEN
|
||||
accountService.authenticate(null);
|
||||
|
||||
// THEN
|
||||
expect(comp.account()).toBeNull();
|
||||
});
|
||||
|
||||
it('Should hold current authenticated user in variable account if user is authenticated before page load', () => {
|
||||
// GIVEN
|
||||
accountService.authenticate(account);
|
||||
|
||||
// WHEN
|
||||
comp.ngOnInit();
|
||||
|
||||
// THEN
|
||||
expect(comp.account()).toEqual(account);
|
||||
|
||||
// WHEN
|
||||
accountService.authenticate(null);
|
||||
|
||||
// THEN
|
||||
expect(comp.account()).toBeNull();
|
||||
});
|
||||
});
|
154
src/main/webapp/app/layouts/navbar/navbar.component.ts
Normal file
154
src/main/webapp/app/layouts/navbar/navbar.component.ts
Normal file
|
@ -0,0 +1,154 @@
|
|||
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:
|
||||
* <button *ngIf="hasCreatePermission(Resources.UNIT_TYPE)"></button>
|
||||
*/
|
||||
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<IDocument[]>) => res.body ?? [])
|
||||
).subscribe({
|
||||
next: (docs: IDocument[]) => {
|
||||
this.documents = docs;
|
||||
},
|
||||
});;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/* ==========================================================================
|
||||
Development Ribbon
|
||||
========================================================================== */
|
||||
.ribbon {
|
||||
background-color: rgba(170, 0, 0, 0.5);
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
white-space: nowrap;
|
||||
width: 15em;
|
||||
z-index: 9999;
|
||||
pointer-events: none;
|
||||
opacity: 0.75;
|
||||
a {
|
||||
color: #fff;
|
||||
display: block;
|
||||
font-weight: 400;
|
||||
margin: 1px 0;
|
||||
padding: 10px 50px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 0 5px #444;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { ProfileInfo } from 'app/layouts/profiles/profile-info.model';
|
||||
import { ProfileService } from 'app/layouts/profiles/profile.service';
|
||||
|
||||
import PageRibbonComponent from './page-ribbon.component';
|
||||
|
||||
describe('Page Ribbon Component', () => {
|
||||
let comp: PageRibbonComponent;
|
||||
let fixture: ComponentFixture<PageRibbonComponent>;
|
||||
let profileService: ProfileService;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule, PageRibbonComponent],
|
||||
})
|
||||
.overrideTemplate(PageRibbonComponent, '')
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PageRibbonComponent);
|
||||
comp = fixture.componentInstance;
|
||||
profileService = TestBed.inject(ProfileService);
|
||||
});
|
||||
|
||||
it('Should call profileService.getProfileInfo on init', () => {
|
||||
// GIVEN
|
||||
jest.spyOn(profileService, 'getProfileInfo').mockReturnValue(of(new ProfileInfo()));
|
||||
|
||||
// WHEN
|
||||
comp.ngOnInit();
|
||||
|
||||
// THEN
|
||||
expect(profileService.getProfileInfo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
import { Component, inject, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import SharedModule from 'app/shared/shared.module';
|
||||
import { ProfileService } from './profile.service';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'jhi-page-ribbon',
|
||||
template: `
|
||||
@if (ribbonEnv$ | async; as ribbonEnv) {
|
||||
<div class="ribbon">
|
||||
<a href="" [jhiTranslate]="'global.ribbon.' + (ribbonEnv ?? '')">{{ { dev: 'Desenvolvimento' }[ribbonEnv ?? ''] }}</a>
|
||||
</div>
|
||||
}
|
||||
`,
|
||||
styleUrl: './page-ribbon.component.scss',
|
||||
imports: [SharedModule],
|
||||
})
|
||||
export default class PageRibbonComponent implements OnInit {
|
||||
ribbonEnv$?: Observable<string | undefined>;
|
||||
|
||||
private profileService = inject(ProfileService);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.ribbonEnv$ = this.profileService.getProfileInfo().pipe(map(profileInfo => profileInfo.ribbonEnv));
|
||||
}
|
||||
}
|
15
src/main/webapp/app/layouts/profiles/profile-info.model.ts
Normal file
15
src/main/webapp/app/layouts/profiles/profile-info.model.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
export interface InfoResponse {
|
||||
'display-ribbon-on-profiles'?: string;
|
||||
git?: any;
|
||||
build?: any;
|
||||
activeProfiles?: string[];
|
||||
}
|
||||
|
||||
export class ProfileInfo {
|
||||
constructor(
|
||||
public activeProfiles?: string[],
|
||||
public ribbonEnv?: string,
|
||||
public inProduction?: boolean,
|
||||
public openAPIEnabled?: boolean,
|
||||
) {}
|
||||
}
|
42
src/main/webapp/app/layouts/profiles/profile.service.ts
Normal file
42
src/main/webapp/app/layouts/profiles/profile.service.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { inject, Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ApplicationConfigService } from 'app/core/config/application-config.service';
|
||||
import { ProfileInfo, InfoResponse } from './profile-info.model';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ProfileService {
|
||||
private http = inject(HttpClient);
|
||||
private applicationConfigService = inject(ApplicationConfigService);
|
||||
|
||||
private infoUrl = this.applicationConfigService.getEndpointFor('management/info');
|
||||
private profileInfo$?: Observable<ProfileInfo>;
|
||||
|
||||
getProfileInfo(): Observable<ProfileInfo> {
|
||||
if (this.profileInfo$) {
|
||||
return this.profileInfo$;
|
||||
}
|
||||
|
||||
this.profileInfo$ = this.http.get<InfoResponse>(this.infoUrl).pipe(
|
||||
map((response: InfoResponse) => {
|
||||
const profileInfo: ProfileInfo = {
|
||||
activeProfiles: response.activeProfiles,
|
||||
inProduction: response.activeProfiles?.includes('prod'),
|
||||
openAPIEnabled: response.activeProfiles?.includes('api-docs'),
|
||||
};
|
||||
if (response.activeProfiles && response['display-ribbon-on-profiles']) {
|
||||
const displayRibbonOnProfiles = response['display-ribbon-on-profiles'].split(',');
|
||||
const ribbonProfiles = displayRibbonOnProfiles.filter(profile => response.activeProfiles?.includes(profile));
|
||||
if (ribbonProfiles.length > 0) {
|
||||
profileInfo.ribbonEnv = ribbonProfiles[0];
|
||||
}
|
||||
}
|
||||
return profileInfo;
|
||||
}),
|
||||
shareReplay(),
|
||||
);
|
||||
return this.profileInfo$;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue