export class LayoutComponent implements OnInit {
//#region Public Variables
@ViewChild('tabList') tabList!: ElementRef;
@ViewChild(HeaderComponent) headerComponent!: HeaderComponent;
public isSidebarActive: boolean = false;
public sidebar!: boolean;
public tabs: ITab[] = [];
public userId: any;
public showScrollButtons: boolean = false;
public bsModalRef!: BsModalRef;
public screenWidth: any;
public containerWidth: any;
public screenHeight: any;
//#endregion
constructor(
private activedRoute: ActivatedRoute,
private router: Router,
private tabService: TabService,
private changeDetectorRef: ChangeDetectorRef,
private toasterService: ToastrService,
) {
if (this.activedRoute.snapshot.queryParams['sidebar'] === "false") {
this.sidebar = false;
localStorage.setItem('sidebar', 'false')
}
else {
localStorage.setItem('sidebar', 'true')
this.sidebar = true;
}
}
ngOnInit(): void {
this.screenWidth = window.innerWidth;
this.screenHeight = window.innerHeight;
this.setTabContainerWidth();
this.loadTabsFromLocalStorage();
this.userId = localStorage.getItem('userId');
this.getTabList(this.userId);
this.tabService.openTab$.subscribe(tab => {
this.openTab(tab.route, tab.label, tab.isActive);
});
}
public setTabContainerWidth(): void {
const sidebarWidth = this.isSidebarActive ? 74 : 300;
const newWidth = this.screenWidth - sidebarWidth;
this.containerWidth = newWidth;
this.changeDetectorRef.detectChanges();
this.checkScrollButtons();
}
public toggleSidebar(): void {
this.isSidebarActive = !this.isSidebarActive;
this.setTabContainerWidth();
}
public getTabList(userId: number): void {
this.tabService.getTabMenuByUserId(userId)
.subscribe({
next: (response: any) => {
// Iterate over the array of tabs received from the backend
response.forEach((tab: { route: string; label: string; isActive: any; }) => {
// Add each tab to the tabs array
this.openTab(tab.route, tab.label, tab.isActive);
});
},
error: (error: any) => {
showErrorMessage('', 'Error while get lab list!', this.toasterService);
},
complete: () => { }
});
}
public openTab(route: string, label: string, isActive: boolean): void {
const existingTab = this.tabs.find(tab => tab.route === route);
if (!existingTab) {
this.tabs.push({ route, label, isActive, userId: this.userId });
// Restore tab state if it exists
const savedState = this.tabService.getTabState(route);
if (savedState) {
}
} else {
existingTab.label = label;
existingTab.isActive = isActive;
}
if (isActive) {
this.setActiveTab(route);
}
this.changeDetectorRef.detectChanges();
this.checkScrollButtons();
}
public closeTab(index: number): void {
const tab = this.tabs[index];
this.tabService.removeTabState(tab.route); // Remove saved state
this.tabs.splice(index, 1);
this.saveTabsToLocalStorage();
if (this.tabs.length > 0) {
const nextTab = this.tabs[index] || this.tabs[index - 1];
this.router.navigateByUrl(nextTab.route);
this.setActiveTab(nextTab.route);
} else {
this.router.navigateByUrl('/main');
}
this.changeDetectorRef.detectChanges();
this.checkScrollButtons();
}
public loadTabsFromLocalStorage(): void {
const storedTabs = localStorage.getItem('tabs');
if (storedTabs) {
this.tabs = JSON.parse(storedTabs);
}
}
public saveTabsToLocalStorage(): void {
localStorage.setItem('tabs', JSON.stringify(this.tabs));
}
public setActiveTab(route: string): void {
this.tabs.forEach(tab => tab.isActive = false);
const activeTab = this.tabs.find(tab => tab.route === route);
if (activeTab) {
if (activeTab.label == "Search Fuel Jobs") {
const urlWithParams = this.router.createUrlTree([route], {
queryParams: { queryParam: 1 }
});
this.router.navigateByUrl(urlWithParams);
}
else {
this.router.navigateByUrl(route);
}
activeTab.isActive = true;
}
this.saveTabsToLocalStorage();
this.changeDetectorRef.detectChanges();
}
public handleLogout(): void {
this.saveTabList();
}
public saveTabList(): void {
this.tabService.addTabs(this.userId, this.tabs)
.subscribe({
next: () => { },
error: (error: any) => {
showErrorMessage(error.error, "Error While Loading Tabs", this.toasterService);
},
complete: () => { }
});
}
//#region Dom Manipulation
public ngAfterViewInit(): void {
this.checkScrollButtons();
this.headerComponent.logoutEvent.subscribe(() => this.handleLogout());
window.addEventListener('resize', () => {
this.setTabContainerWidth();
});
// Manually trigger change detection
this.changeDetectorRef.detectChanges();
}
@HostListener('window:resize', ['$event'])
public onResize(): void {
this.updateScreenDimensions();
this.setTabContainerWidth();
}
private updateScreenDimensions(): void {
this.screenWidth = window.innerWidth;
this.screenHeight = window.innerHeight;
}
//#endregion
//#region ScrollTabs
public scrollLeft(): void {
const tabListElement = this.tabList.nativeElement;
tabListElement.scrollLeft -= 200;
this.changeDetectorRef.detectChanges();
}
public scrollRight(): void {
const tabListElement = this.tabList.nativeElement;
tabListElement.scrollLeft += 200;
this.changeDetectorRef.detectChanges();
}
public checkScrollButtons(): void {
const tabListElement = this.tabList.nativeElement;
this.showScrollButtons = tabListElement.scrollWidth > tabListElement.clientWidth;
this.changeDetectorRef.detectChanges();
}
public scrollToLastTab(): void {
setTimeout(() => {
const tabListElement = this.tabList.nativeElement;
tabListElement.scrollLeft = tabListElement.scrollWidth;
this.changeDetectorRef.detectChanges();
}, 0);
}
//#endregion
public closeAllTabs(): void {
this.tabs.splice(0, this.tabs.length);
this.saveTabsToLocalStorage();
this.tabService.clearAllTabStates();
this.router.navigateByUrl('/main');
}
}
<div class="content-outer">
<header (toggleSidebarEvent)="toggleSidebar()" class="header-container d-none"></header>
<div class="content-wrapper-outer">
<div [ngStyle]="{ 'width.px': containerWidth }" class="top-list-tab-container">
<button class="scroll-button left" *ngIf="showScrollButtons" (click)="scrollLeft()"><</button>
<div class="tab-list-wrapper top-list-tab" #tabList (scroll)="checkScrollButtons()">
<ul class="nav nav-tabs">
<li class="nav-item" *ngFor="let tab of tabs; let i = index">
<div class="nav-link" [ngClass]="{'active': tab.isActive}" [routerLink]="[tab.route]"
(click)="setActiveTab(tab.route)"> {{ tab.label }}
<button type="button" aria-label="Close" (click)="closeTab(i)">
<svg (click)="closeTab(i)" width="10" height="8" viewBox="0 0 8 8" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M1.55235 0.464466C1.25149 0.163606 0.765349 0.163606 0.464489 0.464466C0.163629 0.765326 0.163629 1.25146 0.464489 1.55232L2.91217 4L0.464489 6.44768C0.163629 6.74854 0.163629 7.23467 0.464489 7.53553C0.765349 7.83639 1.25149 7.83639 1.55235 7.53553L4.00002 5.08786L6.4477 7.53553C6.74856 7.83639 7.2347 7.83639 7.53556 7.53553C7.83642 7.23467 7.83642 6.74854 7.53556 6.44768L5.08788 4L7.53556 1.55232C7.83642 1.25146 7.83642 0.765326 7.53556 0.464466C7.2347 0.163606 6.74856 0.163606 6.4477 0.464466L4.00002 2.91214L1.55235 0.464466Z"
fill="#5D6B9A" />
</svg>
</button>
</div>
</li>
</ul>
</div>
<button class="scroll-button right" *ngIf="showScrollButtons" (click)="scrollRight()">></button>
<button *ngIf="tabs.length!=0" aria-label="Close" class="close-all-tabs" (click)="closeAllTabs()">
<svg (click)="closeAllTabs()" width="10" height="8" viewBox="0 0 8 8" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M1.55235 0.464466C1.25149 0.163606 0.765349 0.163606 0.464489 0.464466C0.163629 0.765326 0.163629 1.25146 0.464489 1.55232L2.91217 4L0.464489 6.44768C0.163629 6.74854 0.163629 7.23467 0.464489 7.53553C0.765349 7.83639 1.25149 7.83639 1.55235 7.53553L4.00002 5.08786L6.4477 7.53553C6.74856 7.83639 7.2347 7.83639 7.53556 7.53553C7.83642 7.23467 7.83642 6.74854 7.53556 6.44768L5.08788 4L7.53556 1.55232C7.83642 1.25146 7.83642 0.765326 7.53556 0.464466C7.2347 0.163606 6.74856 0.163606 6.4477 0.464466L4.00002 2.91214L1.55235 0.464466Z"
fill="#5D6B9A" />
</svg>
<span>Close All Tabs</span>
</button>
</div>
<router-outlet></router-outlet>
</div>
</div>