import { Directive , EventEmitter , Input , OnChanges , OnInit , Output , SimpleChange , SimpleChanges , TemplateRef } from '@angular/core' ; import { SafeAny } from 'ngx-tethys/types' ; import { FunctionProp , isTemplateRef , TinyDate } from 'ngx-tethys/util' ; import { DateCell , DateBodyRow } from '../date/types' ; @ Directive ( ) export abstract class CalendarTable implements OnInit , OnChanges { isTemplateRef = isTemplateRef ; headRow : DateCell [ ] = [ ] ; bodyRows : DateBodyRow [ ] = [ ] ; MAX_ROW = 6 ; MAX_COL = 7 ; @ Input ( ) prefixCls : string = 'thy-calendar' ; @ Input ( ) value : TinyDate ; @ Input ( ) activeDate : TinyDate = new TinyDate ( ) ; @ Input ( ) showWeek : boolean = false ; @ Input ( ) selectedValue : TinyDate [ ] = [ ] ; @ Input ( ) hoverValue : TinyDate [ ] = [ ] ; @ Input ( ) disabledDate ? : ( d : Date ) => boolean ; @ Input ( ) cellRender ? : FunctionProp < TemplateRef < Date > | string > ; @ Input ( ) fullCellRender ? : FunctionProp < TemplateRef < Date > | string > ; @ Output ( ) readonly valueChange = new EventEmitter < TinyDate > ( ) ; @ Output ( ) readonly cellHover = new EventEmitter < TinyDate > ( ) ; constructor ( ) { } protected render ( ) { if ( this . activeDate ) { this . headRow = this . makeHeadRow ( ) ; this . bodyRows = this . makeBodyRows ( ) ; } } trackByBodyRow ( _index , item ) { return item . trackByIndex ; } trackByBodyColumn ( _index , item ) { return item . trackByIndex ; } hasRangeValue ( ) { return this . selectedValue ?. length > 0 || this . hoverValue ?. length > 0 ; } abstract makeHeadRow ( ) ; abstract makeBodyRows ( ) ; ngOnInit ( ) { this . render ( ) ; } ngOnChanges ( changes ) { if ( changes . activeDate && ! changes . activeDate . currentValue ) { this . activeDate = new TinyDate ( ) ; } if ( changes . disabledDate || changes . locale || changes . showWeek || this . isDateRealChange ( changes . activeDate ) || this . isDateRealChange ( changes . value ) || this . isDateRealChange ( changes . selectedValue ) || this . isDateRealChange ( changes . hoverValue ) ) { this . render ( ) ; } } private isDateRealChange ( change ) { if ( change ) { const previousValue = change . previousValue ; const currentValue = change . currentValue ; if ( Array . isArray ( currentValue ) ) { return ( ! Array . isArray ( previousValue ) || currentValue . length !== previousValue . length || currentValue . some ( ( value , index ) => { const previousCandyDate = previousValue [ index ] ; return previousCandyDate instanceof TinyDate ? previousCandyDate . isSameDay ( value ) : previousCandyDate !== value ; } ) ) ; } else { return ! this . isSameDate ( previousValue as TinyDate , currentValue ) ; } } return false ; } private isSameDate ( left , right ) { return ( ! left && ! right ) || ( left && right && right . isSameDay ( left ) ) ; } }