import { DOCUMENT } from '@angular/common' ; import { Component , ContentChildren , ElementRef , Inject , Input , OnDestroy , OnInit , QueryList , Renderer2 , TemplateRef } from '@angular/core' ; import { NavigationCancel , NavigationEnd , NavigationError , RouteConfigLoadEnd , RouteConfigLoadStart , Router , Event } from '@angular/router' ; import { Subject } from 'rxjs' ; import { takeUntil } from 'rxjs/operators' ; import { SettingsService } from '@delon/theme' ; import { updateHostClass } from '@delon/util/browser' ; import type { NzSafeAny } from 'ng-zorro-antd/core/types' ; import { NzMessageService } from 'ng-zorro-antd/message' ; import { LayoutDefaultHeaderItemComponent } from './layout-header-item.component' ; import { LayoutDefaultOptions } from './types' ; @ Component ( { selector : 'layout-default' , exportAs : 'layoutDefault' , template : `
    <div class="alain-default__progress-bar" *ngIf="isFetching"></div>
    <layout-default-header [options]="options" [items]="headerItems"></layout-default-header>
    <div *ngIf="!options.hideAside" class="alain-default__aside">
      <div class="alain-default__aside-inner">
        <ng-container *ngTemplateOutlet="asideUser"></ng-container>
        <ng-container *ngTemplateOutlet="nav"></ng-container>
        <layout-default-nav *ngIf="!nav" class="d-block py-lg"></layout-default-nav>
      </div>
    </div>
    <section class="alain-default__content">
      <ng-container *ngTemplateOutlet="content"></ng-container>
      <ng-content></ng-content>
    </section>
  ` } ) export class LayoutDefaultComponent implements OnInit , OnDestroy { @ ContentChildren ( LayoutDefaultHeaderItemComponent , { descendants : false } ) headerItems ! : QueryList < LayoutDefaultHeaderItemComponent > ; @ Input ( ) options ! : LayoutDefaultOptions ; @ Input ( ) asideUser : TemplateRef < void > | null = null ; @ Input ( ) nav : TemplateRef < void > | null = null ; @ Input ( ) content : TemplateRef < void > | null = null ; @ Input ( ) customError ? : string | null ; private destroy$ = new Subject < void > ( ) ; isFetching = false ; constructor ( router , private msgSrv , private settings , private el , private renderer , @ Inject ( DOCUMENT ) private doc ) { router . events . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( ev => this . processEv ( ev ) ) ; } processEv ( ev ) { if ( ! this . isFetching && ev instanceof RouteConfigLoadStart ) { this . isFetching = true ; } if ( ev instanceof NavigationError || ev instanceof NavigationCancel ) { this . isFetching = false ; const err = this . customError === null ? null : this . customError ?? `Could not load ${ ev . url } route` ; if ( err && ev instanceof NavigationError ) { this . msgSrv . error ( err , { nzDuration : 1000 * 3 } ) ; } return ; } if ( ! ( ev instanceof NavigationEnd || ev instanceof RouteConfigLoadEnd ) ) { return ; } if ( this . isFetching ) { setTimeout ( ( ) => { this . isFetching = false ; } , 100 ) ; } } private setClass ( ) { const { el , doc , renderer , settings } = this ; const layout = settings . layout ; updateHostClass ( el . nativeElement , renderer , { [ 'alain-default' ] : true , [ `alain-default__fixed` ] : layout . fixed , [ `alain-default__collapsed` ] : layout . collapsed , [ `alain-default__hide-aside` ] : this . options ! . hideAside } ) ; doc . body . classList [ layout . colorWeak ? 'add' : 'remove' ] ( 'color-weak' ) ; } ngOnInit ( ) { this . options = { logoExpanded : `./assets/logo-full.svg` , logoCollapsed : `./assets/logo.svg` , logoLink : `/` , hideAside : false , ... this . options } ; const { settings , destroy$ } = this ; settings . notify . pipe ( takeUntil ( destroy$ ) ) . subscribe ( ( ) => this . setClass ( ) ) ; this . setClass ( ) ; } ngOnDestroy ( ) { this . destroy$ . next ( ) ; this . destroy$ . complete ( ) ; } }