Skip to content

Instantly share code, notes, and snippets.

@muhammedaltug
Created November 18, 2020 08:39
Show Gist options
  • Select an option

  • Save muhammedaltug/01ef37807ee229be4d28fe2de679e547 to your computer and use it in GitHub Desktop.

Select an option

Save muhammedaltug/01ef37807ee229be4d28fe2de679e547 to your computer and use it in GitHub Desktop.
Abp App Pro Template Layout Customization In v3.2
import {Component} from '@angular/core';
import {ReplaceableComponentsService} from '@abp/ng.core';
import {ApplicationLayoutComponent} from "./application-layout/application-layout.component";
import {eThemeLeptonComponents} from "@volo/abp.ng.theme.lepton";
@Component({
selector: 'app-root',
template: `
<abp-loader-bar></abp-loader-bar>
<abp-dynamic-layout></abp-dynamic-layout>
`,
})
export class AppComponent {
constructor(replaceableComponentsService: ReplaceableComponentsService) {
replaceableComponentsService.add({
component: ApplicationLayoutComponent,
key: eThemeLeptonComponents.ApplicationLayout
});
}
}
<header>
<abp-logo #navbarBrand *abpReplaceableTemplate="{ componentKey: logoComponentKey }"></abp-logo>
<nav class="navbar navbar-expand-xl navbar-dark d-lg-none nav-mobile">
<button
class="navbar-toggler border-0"
type="button"
data-toggle="collapse"
data-target="#navbarToolbar"
aria-controls="navbarText"
aria-label="Toggle navigation"
[attr.aria-expanded]="isNavbarExpanded"
(click)="isNavbarExpanded = !isNavbarExpanded"
>
<i class="fa fa-user"></i>
</button>
<button
class="navbar-toggler border-0"
[class.collapsed]="!isMenuExpanded"
type="button"
data-toggle="collapse"
data-target="#navbarSidebar"
aria-controls="navbarText"
aria-label="Toggle navigation"
[attr.aria-expanded]="isMenuExpanded"
(click)="isMenuExpanded = !isMenuExpanded"
>
<i class="fa fa-align-justify"></i>
</button>
</nav>
<abp-nav-items
*abpReplaceableTemplate="{
componentKey: navItemsComponentKey,
inputs: { isNavbarExpanded: { value: isNavbarExpanded }, smallScreen: { value: smallScreen } }
}"
[isNavbarExpanded]="isNavbarExpanded"
[smallScreen]="smallScreen"
></abp-nav-items>
<div
#navbarSidebar
class="lp-sidebar navbar-collapse d-lg-block collapse"
id="navbarSidebar"
[class.show]="smallScreen"
[class.abp-collapsed-height]="smallScreen"
[class.abp-mh-100]="smallScreen && isMenuExpanded ? true : false"
>
<div class="lp-sidebar-header" [class.w-75]="!mouseOnSidebar">
<div class="lp-toggle-sidebar" (click)="onClickMenuIcon(isSidebarCollapsed)">
<i
class="fa fa-align-{{ isSidebarCollapsed ? 'left' : 'justify' }} material-icons lp-{{
isSidebarCollapsed ? 'open' : 'close'
}}-icon"
></i>
</div>
</div>
<abp-routes
*abpReplaceableTemplate="{
componentKey: routesComponentKey,
outputs: { clickedToLink: onClickLink },
inputs: {
isMenuPlacementTop: { value: isMenuPlacementTop },
smallScreen: { value: smallScreen }
}
}"
(clickedToLink)="onClickLink()"
[isMenuPlacementTop]="isMenuPlacementTop"
[smallScreen]="smallScreen"
></abp-routes>
</div>
</header>
<div class="lp-content h-100">
<router-outlet></router-outlet>
</div>
<footer class="lp-footer">
<div class="d-flex">
<div class="mr-auto">
<span>2019 - {{ currentYear }} © {{ appInfo.name }}</span
><br />
</div>
</div>
</footer>
import { Config, ConfigState, eLayoutType, SubscriptionService } from '@abp/ng.core';
import {
AfterViewInit,
Component,
ElementRef,
Renderer2,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import { Store } from '@ngxs/store';
import { fromEvent } from 'rxjs';
import { debounceTime, filter } from 'rxjs/operators';
import { SetMenuStatus, SetMenuPlacement, eThemeLeptonComponents, Layout, LayoutState} from '@volo/abp.ng.theme.lepton';
@Component({
selector: 'app-application-layout',
templateUrl: './application-layout.component.html',
encapsulation: ViewEncapsulation.None,
styleUrls: ['application-layout.component.scss'],
providers: [SubscriptionService],
})
export class ApplicationLayoutComponent implements AfterViewInit {
// required for dynamic component
static type = eLayoutType.application;
@ViewChild('navbarSidebar', { read: ElementRef })
navbarSidebarRef: ElementRef<any>;
@ViewChild('navbarBrand', { read: ElementRef })
navbarBrandRef: ElementRef<any>;
isSidebarCollapsed: boolean;
isMenuPlacementTop: boolean;
isMenuSwitched: boolean;
mouseOnSidebar = false;
isMenuExpanded: boolean;
isNavbarExpanded: boolean;
smallScreen = false;
currentYear = new Date().getFullYear();
logoComponentKey = eThemeLeptonComponents.Logo;
routesComponentKey = eThemeLeptonComponents.Routes;
navItemsComponentKey = eThemeLeptonComponents.NavItems;
get appInfo(): Config.Application {
return this.store.selectSnapshot(ConfigState.getApplicationInfo);
}
constructor(
private store: Store,
private renderer: Renderer2,
private subscription: SubscriptionService,
) {}
private listenMouseMove() {
const mousemove$ = fromEvent(document, 'mousemove').pipe(
debounceTime(50),
filter(() => this.isSidebarCollapsed),
);
this.subscription.addOne(mousemove$, (event: MouseEvent) => {
if (
(this.navbarSidebarRef.nativeElement as HTMLElement).contains(event.target as any) ||
(this.navbarBrandRef.nativeElement as HTMLElement).contains(event.target as any)
) {
this.mouseOnSidebar = true;
if (document.body.classList.contains('lp-closed')) {
this.renderer.addClass(document.body, 'lp-extended');
}
} else {
this.mouseOnSidebar = false;
this.renderer.removeClass(document.body, 'lp-extended');
}
});
}
private listenState() {
this.subscription.addOne(this.store.select(LayoutState), ({ menuStatus, menuPlacement }) => {
setTimeout(() => {
this.isSidebarCollapsed = menuStatus === Layout.MenuStatus.OpenOnHover;
this.isMenuPlacementTop = menuPlacement === Layout.MenuPlacement.Top;
}, 0);
});
}
ngAfterViewInit() {
this.listenMouseMove();
this.listenState();
this.listenResize();
}
listenResize() {
const setSmallScreen = () => {
setTimeout(() => {
if (window.innerWidth < 992) {
this.smallScreen = true;
if (this.isMenuPlacementTop) {
this.store.dispatch(new SetMenuPlacement(Layout.MenuPlacement.Left));
this.isMenuSwitched = true;
}
} else {
this.smallScreen = false;
if (this.isMenuSwitched) {
this.store.dispatch(new SetMenuPlacement(Layout.MenuPlacement.Top));
this.isMenuSwitched = false;
}
}
}, 0);
};
setSmallScreen();
const resize$ = fromEvent(window, 'resize').pipe(debounceTime(150));
this.subscription.addOne(resize$, () => setSmallScreen());
}
onClickMenuIcon(value: boolean) {
if (value) {
this.store.dispatch(new SetMenuStatus(Layout.MenuStatus.AlwaysOpened));
} else {
this.store.dispatch(new SetMenuStatus(Layout.MenuStatus.OpenOnHover));
}
}
onClickLink() {
if (this.smallScreen) {
this.isMenuExpanded = false;
this.isNavbarExpanded = false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment