Browse Source

feat(theme-basic): implement collapseWithMargin animation to the application layout main navigation

pull/2000/head
mehmet-erim 7 years ago
parent
commit
6fa19229bb
  1. 192
      npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html
  2. 40
      npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.ts

192
npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.html

@ -3,7 +3,7 @@
id="main-navbar"
style="min-height: 4rem;"
>
<div class="container">
<div class="container ">
<a class="navbar-brand" routerLink="/">
<img *ngIf="appInfo.logoUrl; else appName" [src]="appInfo.logoUrl" [alt]="appInfo.name" />
</a>
@ -15,109 +15,117 @@
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="main-navbar-collapse" [ngbCollapse]="isCollapsed">
<ul class="navbar-nav mx-auto">
<ng-container
*ngFor="let route of visibleRoutes$ | async; trackBy: trackByFn"
[ngTemplateOutlet]="route?.children?.length ? dropdownLink : defaultLink"
[ngTemplateOutletContext]="{ $implicit: route }"
>
</ng-container>
<div class="navbar-collapse" id="main-navbar-collapse">
<ng-container *ngTemplateOutlet="!smallScreen ? navigations : null"></ng-container>
<ng-template #defaultLink let-route>
<li class="nav-item" [abpPermission]="route.requiredPolicy">
<a class="nav-link" [routerLink]="[route.url]">{{ route.name | abpLocalization }}</a>
</li>
</ng-template>
<div *ngIf="smallScreen" class="overflow-hidden" [@collapseWithMargin]="isCollapsed ? 'collapsed' : 'expanded'">
<ng-container *ngTemplateOutlet="navigations"></ng-container>
</div>
<ng-template #dropdownLink let-route>
<li
#navbarRootDropdown
ngbDropdown
[abpPermission]="route.requiredPolicy"
[abpVisibility]="routeContainer"
class="nav-item"
display="static"
(click)="$event.preventDefault(); $event.stopPropagation()"
<ng-template #navigations>
<ul class="navbar-nav mx-auto">
<ng-container
*ngFor="let route of visibleRoutes$ | async; trackBy: trackByFn"
[ngTemplateOutlet]="route?.children?.length ? dropdownLink : defaultLink"
[ngTemplateOutletContext]="{ $implicit: route }"
>
<a
ngbDropdownToggle
class="nav-link"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
href="javascript:void(0)"
>
<i *ngIf="route.iconClass" [ngClass]="route.iconClass"></i> {{ route.name | abpLocalization }}
</a>
<div #routeContainer ngbDropdownMenu class="dropdown-menu border-0 shadow-sm">
<ng-template
#forTemplate
ngFor
[ngForOf]="route.children"
[ngForTrackBy]="trackByFn"
[ngForTemplate]="childWrapper"
></ng-template>
</div>
</li>
</ng-template>
</ng-container>
<ng-template #childWrapper let-child>
<ng-template
[ngTemplateOutlet]="child?.children?.length ? dropdownChild : defaultChild"
[ngTemplateOutletContext]="{ $implicit: child }"
></ng-template>
</ng-template>
<ng-template #defaultLink let-route>
<li class="nav-item" [abpPermission]="route.requiredPolicy">
<a class="nav-link" [routerLink]="[route.url]">{{ route.name | abpLocalization }}</a>
</li>
</ng-template>
<ng-template #defaultChild let-child>
<div class="dropdown-submenu" [abpPermission]="child.requiredPolicy">
<a class="dropdown-item" [routerLink]="[child.url]">
<i *ngIf="child.iconClass" [ngClass]="child.iconClass"></i>
{{ child.name | abpLocalization }}</a
<ng-template #dropdownLink let-route>
<li
#navbarRootDropdown
ngbDropdown
[abpPermission]="route.requiredPolicy"
[abpVisibility]="routeContainer"
class="nav-item"
display="static"
(click)="$event.preventDefault(); $event.stopPropagation()"
>
</div>
</ng-template>
<ng-template #dropdownChild let-child>
<div
[abpVisibility]="childrenContainer"
class="dropdown-submenu"
ngbDropdown
[display]="isDropdownChildDynamic ? 'dynamic' : 'static'"
placement="right-top"
[autoClose]="true"
[abpPermission]="child.requiredPolicy"
(openChange)="openChange($event, childrenContainer)"
>
<div ngbDropdownToggle [class.dropdown-toggle]="false">
<a
abpEllipsis="210px"
[abpEllipsisEnabled]="isDropdownChildDynamic"
role="button"
class="btn d-block text-left dropdown-toggle"
ngbDropdownToggle
class="nav-link"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
href="javascript:void(0)"
>
<i *ngIf="child.iconClass" [ngClass]="child.iconClass"></i>
{{ child.name | abpLocalization }}
<i *ngIf="route.iconClass" [ngClass]="route.iconClass"></i> {{ route.name | abpLocalization }}
</a>
<div #routeContainer ngbDropdownMenu class="dropdown-menu border-0 shadow-sm">
<ng-template
#forTemplate
ngFor
[ngForOf]="route.children"
[ngForTrackBy]="trackByFn"
[ngForTemplate]="childWrapper"
></ng-template>
</div>
</li>
</ng-template>
<ng-template #childWrapper let-child>
<ng-template
[ngTemplateOutlet]="child?.children?.length ? dropdownChild : defaultChild"
[ngTemplateOutletContext]="{ $implicit: child }"
></ng-template>
</ng-template>
<ng-template #defaultChild let-child>
<div class="dropdown-submenu" [abpPermission]="child.requiredPolicy">
<a class="dropdown-item" [routerLink]="[child.url]">
<i *ngIf="child.iconClass" [ngClass]="child.iconClass"></i>
{{ child.name | abpLocalization }}</a
>
</div>
<div #childrenContainer ngbDropdownMenu class="dropdown-menu border-0 shadow-sm">
<ng-template
ngFor
[ngForOf]="child.children"
[ngForTrackBy]="trackByFn"
[ngForTemplate]="childWrapper"
></ng-template>
</ng-template>
<ng-template #dropdownChild let-child>
<div
[abpVisibility]="childrenContainer"
class="dropdown-submenu"
ngbDropdown
[display]="isDropdownChildDynamic ? 'dynamic' : 'static'"
placement="right-top"
[autoClose]="true"
[abpPermission]="child.requiredPolicy"
(openChange)="openChange($event, childrenContainer)"
>
<div ngbDropdownToggle [class.dropdown-toggle]="false">
<a
abpEllipsis="210px"
[abpEllipsisEnabled]="isDropdownChildDynamic"
role="button"
class="btn d-block text-left dropdown-toggle"
>
<i *ngIf="child.iconClass" [ngClass]="child.iconClass"></i>
{{ child.name | abpLocalization }}
</a>
</div>
<div #childrenContainer ngbDropdownMenu class="dropdown-menu border-0 shadow-sm">
<ng-template
ngFor
[ngForOf]="child.children"
[ngForTrackBy]="trackByFn"
[ngForTemplate]="childWrapper"
></ng-template>
</div>
</div>
</div>
</ng-template>
</ul>
</ng-template>
</ul>
<ul class="navbar-nav">
<ng-container
*ngFor="let element of rightPartElements; trackBy: trackElementByFn"
[ngTemplateOutlet]="element"
></ng-container>
</ul>
<ul class="navbar-nav">
<ng-container
*ngFor="let element of rightPartElements; trackBy: trackElementByFn"
[ngTemplateOutlet]="element"
></ng-container>
</ul>
</ng-template>
</div>
</div>
</nav>

40
npm/ng-packs/packages/theme-basic/src/lib/components/application-layout/application-layout.component.ts

@ -1,24 +1,25 @@
import {
ABP,
ApplicationConfiguration,
GetAppConfiguration,
Config,
ConfigState,
eLayoutType,
SetLanguage,
GetAppConfiguration,
SessionState,
SetLanguage,
takeUntilDestroy,
Config,
} from '@abp/ng.core';
import { collapseWithMargin, slideFromBottom } from '@abp/ng.theme.shared';
import {
AfterViewInit,
Component,
OnDestroy,
QueryList,
Renderer2,
TemplateRef,
TrackByFunction,
ViewChild,
ViewChildren,
Renderer2,
} from '@angular/core';
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
import { Navigate, RouterState } from '@ngxs/router-plugin';
@ -31,12 +32,11 @@ import snq from 'snq';
import { AddNavigationElement } from '../../actions';
import { Layout } from '../../models/layout';
import { LayoutState } from '../../states';
import { slideFromBottom } from '@abp/ng.theme.shared';
@Component({
selector: 'abp-layout-application',
templateUrl: './application-layout.component.html',
animations: [slideFromBottom],
animations: [slideFromBottom, collapseWithMargin],
})
export class ApplicationLayoutComponent implements AfterViewInit, OnDestroy {
// required for dynamic component
@ -67,6 +67,8 @@ export class ApplicationLayoutComponent implements AfterViewInit, OnDestroy {
isCollapsed = true;
smallScreen: boolean; // do not set true or false
get appInfo(): Config.Application {
return this.store.selectSnapshot(ConfigState.getApplicationInfo);
}
@ -103,16 +105,22 @@ export class ApplicationLayoutComponent implements AfterViewInit, OnDestroy {
constructor(private store: Store, private oauthService: OAuthService, private renderer: Renderer2) {}
private checkWindowWidth() {
setTimeout(() => {
this.navbarRootDropdowns.forEach(item => {
item.close();
});
if (window.innerWidth < 768) {
this.isDropdownChildDynamic = false;
} else {
this.isDropdownChildDynamic = true;
this.navbarRootDropdowns.forEach(item => {
item.close();
});
if (window.innerWidth < 768) {
this.isDropdownChildDynamic = false;
if (this.smallScreen === false) {
this.isCollapsed = false;
setTimeout(() => {
this.isCollapsed = true;
}, 100);
}
}, 0);
this.smallScreen = true;
} else {
this.isDropdownChildDynamic = true;
this.smallScreen = false;
}
}
ngAfterViewInit() {
@ -142,7 +150,7 @@ export class ApplicationLayoutComponent implements AfterViewInit, OnDestroy {
fromEvent(window, 'resize')
.pipe(
takeUntilDestroy(this),
debounceTime(250),
debounceTime(150),
)
.subscribe(() => {
this.checkWindowWidth();

Loading…
Cancel
Save