285 lines
7.9 KiB
TypeScript
285 lines
7.9 KiB
TypeScript
import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout';
|
|
import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
import { Subscription } from 'rxjs';
|
|
import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav';
|
|
import { CoreService } from 'src/app/services/core.service';
|
|
import { AppSettings } from 'src/app/config';
|
|
import { filter } from 'rxjs/operators';
|
|
import { NavigationEnd, Router } from '@angular/router';
|
|
import { navItems } from './vertical/sidebar/sidebar-data';
|
|
import { NavService } from '../../services/nav.service';
|
|
import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component';
|
|
import { RouterModule } from '@angular/router';
|
|
import { MaterialModule } from 'src/app/material.module';
|
|
import { CommonModule } from '@angular/common';
|
|
import { SidebarComponent } from './vertical/sidebar/sidebar.component';
|
|
import { NgScrollbarModule } from 'ngx-scrollbar';
|
|
import { TablerIconsModule } from 'angular-tabler-icons';
|
|
import { HeaderComponent } from './vertical/header/header.component';
|
|
import { AppHorizontalHeaderComponent } from './horizontal/header/header.component';
|
|
import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component';
|
|
import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component';
|
|
import { CustomizerComponent } from './shared/customizer/customizer.component';
|
|
|
|
const MOBILE_VIEW = 'screen and (max-width: 768px)';
|
|
const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)';
|
|
const MONITOR_VIEW = 'screen and (min-width: 1024px)';
|
|
const BELOWMONITOR = 'screen and (max-width: 1023px)';
|
|
|
|
// for mobile app sidebar
|
|
interface apps {
|
|
id: number;
|
|
img: string;
|
|
title: string;
|
|
subtitle: string;
|
|
link: string;
|
|
}
|
|
|
|
interface quicklinks {
|
|
id: number;
|
|
title: string;
|
|
link: string;
|
|
}
|
|
|
|
@Component({
|
|
selector: 'app-full',
|
|
imports: [
|
|
RouterModule,
|
|
AppNavItemComponent,
|
|
MaterialModule,
|
|
CommonModule,
|
|
SidebarComponent,
|
|
NgScrollbarModule,
|
|
TablerIconsModule,
|
|
HeaderComponent,
|
|
AppHorizontalHeaderComponent,
|
|
AppHorizontalSidebarComponent,
|
|
AppBreadcrumbComponent,
|
|
CustomizerComponent,
|
|
],
|
|
templateUrl: './full.component.html',
|
|
|
|
encapsulation: ViewEncapsulation.None
|
|
})
|
|
export class FullComponent implements OnInit {
|
|
navItems = navItems;
|
|
|
|
|
|
|
|
@ViewChild('leftsidenav')
|
|
public sidenav: MatSidenav;
|
|
resView = false;
|
|
@ViewChild('content', { static: true }) content!: MatSidenavContent;
|
|
//get options from service
|
|
options = this.settings.getOptions();
|
|
private layoutChangesSubscription = Subscription.EMPTY;
|
|
private isMobileScreen = false;
|
|
private isContentWidthFixed = true;
|
|
private isCollapsedWidthFixed = false;
|
|
private htmlElement!: HTMLHtmlElement;
|
|
|
|
get isOver(): boolean {
|
|
return this.isMobileScreen;
|
|
}
|
|
|
|
get isTablet(): boolean {
|
|
return this.resView;
|
|
}
|
|
|
|
// for mobile app sidebar
|
|
apps: apps[] = [
|
|
{
|
|
id: 1,
|
|
img: '/assets/images/svgs/icon-dd-chat.svg',
|
|
title: 'Chat Application',
|
|
subtitle: 'Messages & Emails',
|
|
link: '/apps/chat',
|
|
},
|
|
{
|
|
id: 2,
|
|
img: '/assets/images/svgs/icon-dd-cart.svg',
|
|
title: 'Todo App',
|
|
subtitle: 'Completed task',
|
|
link: '/apps/todo',
|
|
},
|
|
{
|
|
id: 3,
|
|
img: '/assets/images/svgs/icon-dd-invoice.svg',
|
|
title: 'Invoice App',
|
|
subtitle: 'Get latest invoice',
|
|
link: '/apps/invoice',
|
|
},
|
|
{
|
|
id: 4,
|
|
img: '/assets/images/svgs/icon-dd-date.svg',
|
|
title: 'Calendar App',
|
|
subtitle: 'Get Dates',
|
|
link: '/apps/calendar',
|
|
},
|
|
{
|
|
id: 5,
|
|
img: '/assets/images/svgs/icon-dd-mobile.svg',
|
|
title: 'Contact Application',
|
|
subtitle: '2 Unsaved Contacts',
|
|
link: '/apps/contacts',
|
|
},
|
|
{
|
|
id: 6,
|
|
img: '/assets/images/svgs/icon-dd-lifebuoy.svg',
|
|
title: 'Tickets App',
|
|
subtitle: 'Create new ticket',
|
|
link: '/apps/tickets',
|
|
},
|
|
{
|
|
id: 7,
|
|
img: '/assets/images/svgs/icon-dd-message-box.svg',
|
|
title: 'Email App',
|
|
subtitle: 'Get new emails',
|
|
link: '/apps/email/inbox',
|
|
},
|
|
{
|
|
id: 8,
|
|
img: '/assets/images/svgs/icon-dd-application.svg',
|
|
title: 'Courses',
|
|
subtitle: 'Create new course',
|
|
link: '/apps/courses',
|
|
},
|
|
];
|
|
|
|
quicklinks: quicklinks[] = [
|
|
{
|
|
id: 1,
|
|
title: 'Pricing Page',
|
|
link: '/theme-pages/pricing',
|
|
},
|
|
{
|
|
id: 2,
|
|
title: 'Authentication Design',
|
|
link: '/authentication/login',
|
|
},
|
|
{
|
|
id: 3,
|
|
title: 'Register Now',
|
|
link: '/authentication/side-register',
|
|
},
|
|
{
|
|
id: 4,
|
|
title: '404 Error Page',
|
|
link: '/authentication/error',
|
|
},
|
|
{
|
|
id: 5,
|
|
title: 'Notes App',
|
|
link: '/apps/notes',
|
|
},
|
|
{
|
|
id: 6,
|
|
title: 'Employee App',
|
|
link: '/apps/employee',
|
|
},
|
|
{
|
|
id: 7,
|
|
title: 'Todo Application',
|
|
link: '/apps/todo',
|
|
},
|
|
{
|
|
id: 8,
|
|
title: 'Treeview',
|
|
link: '/theme-pages/treeview',
|
|
},
|
|
];
|
|
|
|
constructor(
|
|
private settings: CoreService,
|
|
private mediaMatcher: MediaMatcher,
|
|
private router: Router,
|
|
private breakpointObserver: BreakpointObserver,
|
|
private navService: NavService, private cdr: ChangeDetectorRef
|
|
) {
|
|
this.htmlElement = document.querySelector('html')!;
|
|
this.layoutChangesSubscription = this.breakpointObserver
|
|
.observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR])
|
|
.subscribe((state) => {
|
|
// SidenavOpened must be reset true when layout changes
|
|
this.options.sidenavOpened = true;
|
|
this.isMobileScreen = state.breakpoints[BELOWMONITOR];
|
|
if (this.options.sidenavCollapsed == false) {
|
|
this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW];
|
|
}
|
|
this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW];
|
|
this.resView = state.breakpoints[BELOWMONITOR];
|
|
});
|
|
|
|
// Initialize project theme with options
|
|
this.receiveOptions(this.options);
|
|
|
|
// This is for scroll to top
|
|
this.router.events
|
|
.pipe(filter((event) => event instanceof NavigationEnd))
|
|
.subscribe((e) => {
|
|
this.content.scrollTo({ top: 0 });
|
|
});
|
|
}
|
|
|
|
isFilterNavOpen = false;
|
|
|
|
toggleFilterNav() {
|
|
this.isFilterNavOpen = !this.isFilterNavOpen;
|
|
console.log('Sidebar open:', this.isFilterNavOpen);
|
|
this.cdr.detectChanges(); // Ensures Angular updates the view
|
|
}
|
|
|
|
ngOnInit(): void {}
|
|
|
|
ngOnDestroy() {
|
|
this.layoutChangesSubscription.unsubscribe();
|
|
}
|
|
|
|
toggleCollapsed() {
|
|
this.isContentWidthFixed = false;
|
|
this.options.sidenavCollapsed = !this.options.sidenavCollapsed;
|
|
this.resetCollapsedState();
|
|
}
|
|
|
|
resetCollapsedState(timer = 400) {
|
|
setTimeout(() => this.settings.setOptions(this.options), timer);
|
|
}
|
|
|
|
onSidenavClosedStart() {
|
|
this.isContentWidthFixed = false;
|
|
}
|
|
|
|
onSidenavOpenedChange(isOpened: boolean) {
|
|
this.isCollapsedWidthFixed = !this.isOver;
|
|
this.options.sidenavOpened = isOpened;
|
|
this.settings.setOptions(this.options);
|
|
}
|
|
|
|
receiveOptions(options: AppSettings): void {
|
|
this.toggleDarkTheme(options);
|
|
this.toggleColorsTheme(options);
|
|
}
|
|
|
|
toggleDarkTheme(options: AppSettings) {
|
|
if (options.theme === 'dark') {
|
|
this.htmlElement.classList.add('dark-theme');
|
|
this.htmlElement.classList.remove('light-theme');
|
|
} else {
|
|
this.htmlElement.classList.remove('dark-theme');
|
|
this.htmlElement.classList.add('light-theme');
|
|
}
|
|
}
|
|
|
|
toggleColorsTheme(options: AppSettings) {
|
|
// Remove any existing theme class dynamically
|
|
this.htmlElement.classList.forEach((className) => {
|
|
if (className.endsWith('_theme')) {
|
|
this.htmlElement.classList.remove(className);
|
|
}
|
|
});
|
|
|
|
// Add the selected theme class
|
|
this.htmlElement.classList.add(options.activeTheme);
|
|
}
|
|
}
|