import { Component , OnInit , ElementRef , ChangeDetectionStrategy , Input , EventEmitter , Output , ChangeDetectorRef , NgZone , OnChanges , OnDestroy , SimpleChanges , ContentChildren , QueryList , AfterViewInit , ViewChild , ContentChild , TemplateRef } from '@angular/core' ; import { startWith , takeUntil , take , finalize } from 'rxjs/operators' ; import { Subject , Observable } from 'rxjs' ; import { GanttUpper , GANTT_UPPER_TOKEN } from './gantt-upper' ; import { GanttLinkDragEvent , GanttLineClickEvent , GanttItemInternal , GanttItem } from './class' ; import { NgxGanttTableColumnComponent } from './table/gantt-column.component' ; import { sideWidth } from './gantt.styles' ; import { coerceCssPixelValue } from '@angular/cdk/coercion' ; import { NgxGanttTableComponent } from './table/gantt-table.component' ; export const defaultColumnWidth = 100 ; export const minColumnWidth = 80 ; @ Component ( { selector : 'ngx-gantt' , templateUrl : './gantt.component.html' , changeDetection : ChangeDetectionStrategy . OnPush , providers : [ { provide : GANTT_UPPER_TOKEN , useExisting : NgxGanttComponent } ] } ) export class NgxGanttComponent extends GanttUpper implements OnInit , AfterViewInit , OnChanges , OnDestroy { @ Input ( ) maxLevel = 2 ; @ Input ( ) async : boolean ; @ Input ( ) childrenResolve : ( GanttItem ) => Observable < GanttItem [ ] > ; @ Input ( ) linkable : boolean ; @ Output ( ) linkDragStarted = new EventEmitter < GanttLinkDragEvent > ( ) ; @ Output ( ) linkDragEnded = new EventEmitter < GanttLinkDragEvent > ( ) ; @ Output ( ) lineClick = new EventEmitter < GanttLineClickEvent > ( ) ; @ ContentChild ( NgxGanttTableComponent ) table : NgxGanttTableComponent ; @ ContentChildren ( NgxGanttTableColumnComponent , { descendants : true } ) columns : QueryList < NgxGanttTableColumnComponent > ; @ ContentChild ( 'tableEmpty' , { static : true } ) tableEmptyTemplate : TemplateRef < any > ; private ngUnsubscribe$ = new Subject ( ) ; public sideTableWidth = sideWidth ; constructor ( elementRef , cdr , ngZone ) { super ( elementRef , cdr , ngZone ) ; } ngOnInit ( ) { super . onInit ( ) ; this . ngZone . onStable . pipe ( take ( 1 ) ) . subscribe ( ( ) => { this . dragContainer . linkDragStarted . pipe ( takeUntil ( this . ngUnsubscribe$ ) ) . subscribe ( ( event ) => { this . linkDragStarted . emit ( event ) ; } ) ; this . dragContainer . linkDragEnded . pipe ( takeUntil ( this . ngUnsubscribe$ ) ) . subscribe ( ( event ) => { this . linkDragEnded . emit ( event ) ; } ) ; } ) ; } ngAfterViewInit ( ) { this . columns . changes . pipe ( startWith ( true ) , takeUntil ( this . ngUnsubscribe$ ) ) . subscribe ( ( ) => { this . columns . forEach ( ( column ) => { if ( ! column . columnWidth ) { column . columnWidth = coerceCssPixelValue ( defaultColumnWidth ) ; } } ) ; this . cdr . detectChanges ( ) ; } ) ; } ngOnChanges ( changes ) { super . onChanges ( changes ) ; } expandChildren ( item ) { if ( ! item . expanded ) { item . setExpand ( true ) ; if ( this . async && this . childrenResolve && item . children . length === 0 ) { item . loading = true ; this . childrenResolve ( item . origin ) . pipe ( take ( 1 ) , finalize ( ( ) => { item . loading = false ; this . expandChange . emit ( ) ; this . cdr . detectChanges ( ) ; } ) ) . subscribe ( ( items ) => { item . addChildren ( items ) ; this . computeItemsRefs ( ... item . children ) ; } ) ; } else { this . computeItemsRefs ( ... item . children ) ; this . expandChange . emit ( ) ; } } else { item . setExpand ( false ) ; this . expandChange . emit ( ) ; } } ngOnDestroy ( ) { super . onDestroy ( ) ; } }