import { Component , OnInit , Input , Output , EventEmitter , SimpleChanges , OnChanges } from '@angular/core' ; import { ITask , IOrganizationSprint , IOrganizationProject , IOrganization } from '@gauzy/contracts' ; import { Observable } from 'rxjs' ; import { map , tap , filter , take } from 'rxjs/operators' ; import { CdkDragDrop , moveItemInArray , transferArrayItem } from '@angular/cdk/drag-drop' ; import { NbDialogService } from '@nebular/theme' ; import { TranslateService } from '@ngx-translate/core' ; import { UntilDestroy , untilDestroyed } from '@ngneat/until-destroy' ; import { GauzyEditableGridComponent } from '../../../../../../@shared/components/editable-grid/gauzy-editable-grid.component' ; import { SprintStoreService , Store , TasksStoreService } from './../../../../../../@core/services' ; @ UntilDestroy ( { checkProperties : true } ) @ Component ( { selector : 'ga-tasks-sprint-view' , templateUrl : './tasks-sprint-view.component.html' , styleUrls : [ './tasks-sprint-view.component.scss' ] } ) export class TasksSprintViewComponent extends GauzyEditableGridComponent < ITask > implements OnInit , OnChanges { sprints : IOrganizationSprint [ ] = [ ] ; backlogTasks : ITask [ ] = [ ] ; @ Input ( ) tasks : ITask [ ] = [ ] ; @ Input ( ) project : IOrganizationProject ; @ Output ( ) createTaskEvent : EventEmitter < any > = new EventEmitter ( ) ; @ Output ( ) editTaskEvent : EventEmitter < any > = new EventEmitter ( ) ; @ Output ( ) deleteTaskEvent : EventEmitter < any > = new EventEmitter ( ) ; sprints$ : Observable < IOrganizationSprint [ ] > = this . store$ . sprints$ . pipe ( map ( ( sprints ) : IOrganizationSprint [ ] => sprints . filter ( ( sprint ) => sprint . projectId === this . project . id ) ) , tap ( ( sprints ) => { this . sprintIds = [ ... sprints . map ( ( sprint ) => sprint . id ) , 'backlog' ] ; } ) ) ; sprintIds : string [ ] = [ ] ; sprintActions : { title : string ; } [ ] = [ ] ; constructor ( private readonly store$ , translateService , dialogService , private readonly taskStore , private readonly storeService ) { super ( translateService , dialogService ) ; } ngOnInit ( ) { this . backlogTasks = this . tasks ; this . sprintActions = [ { title : this . getTranslation ( 'TASKS_PAGE.EDIT_SPRINT' ) } , { title : this . getTranslation ( 'TASKS_PAGE.DELETE_SPRINT' ) } ] ; } initOrganization ( project ) { this . storeService . selectedOrganization$ . pipe ( filter ( ( organization ) => ! ! organization ) , tap ( ( organization ) => { const { tenantId } = this . storeService . user ; const { id : organizationId } = organization ; this . store$ . fetchSprints ( { organizationId , projectId : project . id , tenantId } ) ; } ) , untilDestroyed ( this ) ) . subscribe ( ) ; } reduceTasks ( tasks ) { this . sprints$ . pipe ( untilDestroyed ( this ) ) . subscribe ( ( availableSprints ) => { const sprints = availableSprints . reduce ( ( acc , sprint ) => { acc [ sprint . id ] = { ... sprint , tasks : sprint . tasks || [ ] } ; return acc ; } , { } ) ; this . sprints = Object . values ( sprints ) ; const backlog = [ ] ; tasks . forEach ( ( task ) => { if ( ! task . organizationSprint ) { backlog . push ( task ) ; } } ) ; this . backlogTasks = backlog ; } ) ; } ngOnChanges ( changes ) { if ( changes . tasks ) { this . reduceTasks ( changes . tasks . currentValue ) ; } if ( changes . project ) { this . initOrganization ( changes . project . currentValue ) ; } } createTask ( ) { this . createTaskEvent . emit ( ) ; } editTask ( selectedItem ) { this . editTaskEvent . emit ( this . selectedItem || selectedItem ) ; } deleteTask ( selectedItem ) { this . deleteTaskEvent . emit ( selectedItem ) ; } drop ( event ) { if ( event . previousContainer === event . container ) { moveItemInArray ( event . container . data , event . previousIndex , event . currentIndex ) ; } else { this . taskStore . editTask ( { id : event . item . data . id , title : event . item . data . title , organizationSprint : this . sprints . find ( ( sprint ) => sprint . id === event . container . id ) || null } ) . pipe ( untilDestroyed ( this ) ) . subscribe ( ) ; transferArrayItem ( event . previousContainer . data , event . container . data , event . previousIndex , event . currentIndex ) ; } } taskAction ( evt ) { switch ( evt . action ) { case 'EDIT_TASK' : this . editTask ( evt . task ) ; break ; case 'DELETE_TASK' : this . deleteTask ( evt . task ) ; break ; } } changeTaskStatus ( { id , status , title } ) { this . taskStore . editTask ( { id , status , title } ) . pipe ( untilDestroyed ( this ) ) . subscribe ( ) ; } completeSprint ( sprint , evt ) { this . preventExpand ( evt ) ; this . store$ . updateSprint ( { ... sprint , isActive : false } ) . pipe ( take ( 1 ) , untilDestroyed ( this ) ) . subscribe ( ) ; } trackByFn ( task ) { return task . id ? task . id : null ; } private preventExpand ( evt ) { evt . stopPropagation ( ) ; evt . preventDefault ( ) ; } }