import { Direction , Directionality } from '@angular/cdk/bidi' ; import { DOCUMENT } from '@angular/common' ; import { ChangeDetectionStrategy , ChangeDetectorRef , Component , ElementRef , Inject , Input , OnDestroy , OnInit , Optional , ViewEncapsulation } from '@angular/core' ; import { interval , Subject } from 'rxjs' ; import { takeUntil } from 'rxjs/operators' ; import { AlainConfigService } from '@delon/util/config' ; import { InputNumber } from '@delon/util/decorator' ; import type { NzSafeAny } from 'ng-zorro-antd/core/types' ; @ Component ( { selector : 'error-collect, [error-collect]' , exportAs : 'errorCollect' , template : `
    <i nz-icon nzType="exclamation-circle"></i>
    <span class="error-collect__count">{{ count }}</span>
  ` , host : { '[class.error-collect]' : 'true' , '[class.error-collect-rtl]' : `dir === 'rtl'` , '[class.d-none]' : '_hiden' , '(click)' : '_click()' } , preserveWhitespaces : false , changeDetection : ChangeDetectionStrategy . OnPush , encapsulation : ViewEncapsulation . None } ) export class ErrorCollectComponent implements OnInit , OnDestroy { private formEl : HTMLFormElement | null = null ; private destroy$ = new Subject < void > ( ) ; _hiden = true ; count = 0 ; dir : Direction = 'ltr' ; @ Input ( ) @ InputNumber ( ) freq ! : number ; @ Input ( ) @ InputNumber ( ) offsetTop ! : number ; constructor ( private el , private cdr , @ Inject ( DOCUMENT ) private doc , configSrv , @ Optional ( ) private directionality ) { configSrv . attach ( this , 'errorCollect' , { freq : 500 , offsetTop : 65 + 64 + 8 * 2 } ) ; } private get errEls ( ) : NodeListOf < HTMLElement > { return this . formEl ! . querySelectorAll ( '.ant-form-item-has-error' ) ; } private update ( ) { const count = this . errEls . length ; if ( count === this . count ) return ; this . count = count ; this . _hiden = count === 0 ; this . cdr . markForCheck ( ) ; } _click ( ) { if ( this . count === 0 ) return false ; const els = this . errEls ; const formItemEl = this . findParent ( els [ 0 ] , '[nz-form-control]' ) || els [ 0 ] ; formItemEl . scrollIntoView ( true ) ; this . doc . documentElement . scrollTop -= this . offsetTop ; return true ; } private install ( ) { this . dir = this . directionality . value ; this . directionality . change ?. pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( ( direction ) => { this . dir = direction ; } ) ; interval ( this . freq ) . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( ( ) => this . update ( ) ) ; this . update ( ) ; } private findParent ( el , selector ) { let retEl = null ; while ( el ) { if ( el . querySelector ( selector ) ) { retEl = el as HTMLFormElement ; break ; } el = el . parentElement as HTMLFormElement ; } return retEl ; } ngOnInit ( ) { this . formEl = this . findParent ( this . el . nativeElement , 'form' ) ; if ( this . formEl === null ) throw new Error ( 'No found form element' ) ; this . install ( ) ; } ngOnDestroy ( ) { this . destroy$ . next ( ) ; this . destroy$ . complete ( ) ; } }