import { Component , OnDestroy } from '@angular/core' ; import { CdkDragDrop , moveItemInArray , } from '@angular/cdk/drag-drop' ; import { ApiResponse , Board , Column , User , Notification } from '../../shared/models' ; import { AuthService , ModalService , NotificationsService , StringsService } from '../../shared/services' ; import { SettingsService } from '../settings.service' ; import { BoardAdminService } from './board-admin.service' ; import { BoardData } from './board-data.model' ; class SelectableUser extends User { public selected : boolean ; } @ Component ( { selector : 'tb-board-admin' , templateUrl : './board-admin.component.html' , providers : [ BoardAdminService ] } ) export class BoardAdminComponent implements OnDestroy { private subs : any [ ] ; public displayBoards : Board [ ] ; public users : SelectableUser [ ] ; public boards : Board [ ] ; public activeUser : User ; public modalProps : BoardData ; public boardToRemove : Board ; public strings : any ; public hasBAUsers = false ; public loading = true ; public saving = false ; public userFilter : string ; public statusFilter : string ; public sortFilter : string ; public noBoardsMessage : string ; public MODAL_ID : string ; public MODAL_CONFIRM_ID : string ; constructor ( public auth , public modal , public settings , public boardService , private notes , public stringsService ) { this . MODAL_ID = 'board-addedit-form' ; this . MODAL_CONFIRM_ID = 'board-remove-confirm' ; this . users = [ ] ; this . boards = [ ] ; this . displayBoards = [ ] ; this . subs = [ ] ; this . modalProps = new BoardData ( ) ; this . activeUser = new User ( ) ; this . userFilter = '-1' ; this . statusFilter = '-1' ; this . sortFilter = 'name-asc' ; let sub = auth . userChanged . subscribe ( ( user ) => { this . updateActiveUser ( user ) ; } ) ; this . subs . push ( sub ) ; sub = settings . usersChanged . subscribe ( ( users ) => { this . updateUsersList ( users ) ; } ) ; this . subs . push ( sub ) ; sub = settings . boardsChanged . subscribe ( ( boards ) => { this . updateBoardsList ( boards ) ; } ) ; this . subs . push ( sub ) ; sub = stringsService . stringsChanged . subscribe ( newStrings => { this . strings = newStrings ; this . updateActiveUser ( this . activeUser ) ; } ) ; this . subs . push ( sub ) ; } ngOnDestroy ( ) { this . subs . forEach ( sub => sub . unsubscribe ( ) ) ; } dropColumns ( event ) { moveItemInArray ( event . container . data , event . previousIndex , event . currentIndex ) ; this . modalProps . columns . forEach ( ( item , index ) => { item . position = index ; } ) ; } addEditBoard ( ) { if ( ! this . modal . isOpen ( this . MODAL_ID ) ) { return ; } const isAdd = this . modalProps . title === 'Add' ; this . saving = true ; this . setBoardUsers ( ) ; if ( ! this . validateBoard ( ) ) { this . saving = false ; return ; } if ( isAdd ) { this . boardService . addBoard ( this . modalProps ) . subscribe ( ( response ) => { this . handleResponse ( response ) ; } ) ; return ; } this . boardService . editBoard ( this . modalProps ) . subscribe ( ( response ) => { this . handleResponse ( response ) ; } ) ; } removeBoard ( ) { this . saving = true ; this . boardService . removeBoard ( this . boardToRemove . id ) . subscribe ( ( response ) => { this . handleResponse ( response ) ; this . settings . getActions ( ) . subscribe ( ( res ) => { this . settings . updateActions ( res . data [ 1 ] ) ; } ) ; } ) ; } toggleBoardStatus ( board ) { const boardData = new BoardData ( '' , board . id , board . name , ! board . is_active , board . columns , board . categories , board . issue_trackers , board . users ) ; this . boardService . editBoard ( boardData ) . subscribe ( ( response ) => { this . handleResponse ( response ) ; } ) ; } filterBoards ( ) { const userBoards = this . filterBoardsByUser ( ) ; const statusBoards = this . filterBoardsByStatus ( ) ; this . displayBoards = [ ] ; this . boards . forEach ( ( board ) => { let foundInUserBoards = false ; let foundInStatusBoards = false ; userBoards . forEach ( ( userBoard ) => { if ( userBoard . id === board . id ) { foundInUserBoards = true ; } } ) ; statusBoards . forEach ( ( statusBoard ) => { if ( statusBoard . id === board . id ) { foundInStatusBoards = true ; } } ) ; if ( foundInUserBoards && foundInStatusBoards ) { this . displayBoards . push ( board ) ; } } ) ; this . sortBoards ( ) ; } cancelEnterKey ( event ) { if ( event . stopPropagation ) { event . stopPropagation ( ) ; } } private sortBoards ( ) { switch ( this . sortFilter ) { case 'name-asc' : this . displayBoards . sort ( ( a , b ) => { return a . name . localeCompare ( b . name ) ; } ) ; break ; case 'name-desc' : this . displayBoards . sort ( ( a , b ) => { return b . name . localeCompare ( a . name ) ; } ) ; break ; case 'id-desc' : this . displayBoards . sort ( ( a , b ) => { return b . id - a . id ; } ) ; break ; case 'id-asc' : this . displayBoards . sort ( ( a , b ) => { return a . id - b . id ; } ) ; break ; } } private filterBoardsByUser ( ) { if ( + this . userFilter === - 1 ) { return this . deepCopy ( this . boards ) ; } const filteredBoards = [ ] ; this . boards . forEach ( ( board ) => { let userFound = false ; board . users . forEach ( user => { if ( + user . id === + this . userFilter ) { userFound = true ; } } ) ; if ( userFound ) { filteredBoards . push ( board ) ; } } ) ; return filteredBoards ; } private filterBoardsByStatus ( ) { if ( + this . statusFilter === - 1 ) { return this . deepCopy ( this . boards ) ; } const filteredBoards = [ ] ; this . boards . forEach ( ( board ) => { if ( ( board . is_active && + this . statusFilter === 1 ) || ( ! board . is_active && + this . statusFilter === 0 ) ) { filteredBoards . push ( board ) ; } } ) ; return filteredBoards ; } private validateBoard ( ) { if ( this . modalProps . name === '' ) { this . notes . add ( new Notification ( 'error' , this . strings . settings_boardNameError ) ) ; return false ; } if ( this . modalProps . columns . length === 0 ) { this . notes . add ( new Notification ( 'error' , this . strings . settings_columnError ) ) ; return false ; } return true ; } private handleResponse ( response ) { response . alerts . forEach ( note => this . notes . add ( note ) ) ; if ( response . status === 'success' ) { this . modal . close ( this . MODAL_ID ) ; this . modal . close ( this . MODAL_CONFIRM_ID ) ; const boards = [ ] ; response . data [ 1 ] . forEach ( ( board ) => { boards . push ( new Board ( + board . id , board . name , board . is_active === '1' , board . ownColumn , board . ownCategory , board . ownAutoAction , board . ownIssuetracker , board . sharedUser ) ) ; } ) ; this . settings . updateBoards ( boards ) ; this . saving = false ; } } private setBoardUsers ( ) { this . modalProps . users = [ ] ; this . users . forEach ( user => { if ( user . selected ) { this . modalProps . users . push ( user ) ; } } ) ; } private updateActiveUser ( activeUser ) { if ( ! activeUser ) { return ; } this . activeUser = new User ( + activeUser . default_board_id , activeUser . email , + activeUser . id , activeUser . last_login , + activeUser . security_level , + activeUser . user_option_id , activeUser . username , activeUser . board_access ) ; if ( ! this . strings ) { return ; } this . noBoardsMessage = this . strings . settings_noBoards ; if ( + activeUser . security_level === 1 ) { this . noBoardsMessage = this . strings . settings_noBoardsAdmin ; } } private updateUsersList ( users ) { this . users = [ ] ; this . hasBAUsers = false ; users . forEach ( user => { if ( user . security_level > 1 ) { this . users . push ( user ) ; if ( user . security_level === 2 ) { this . hasBAUsers = true ; } } } ) ; } private updateBoardsList ( boards ) { this . boards = boards ; this . boards . forEach ( board => { board . columns . sort ( ( a , b ) => { return + a . position - + b . position ; } ) ; } ) ; this . filterBoards ( ) ; this . loading = false ; } public getPropertyValue ( obj , prop , i ) { return this . modalProps [ obj ] [ i ] [ prop ] ; } public onPropertyEdit ( obj , prop , i , value ) { this . modalProps [ obj ] [ i ] [ prop ] = value ; } public getColor ( category ) { if ( category . default_task_color ) { return category . default_task_color ; } return category . defaultColor ; } public setCategoryColor ( color , index ) { this . modalProps . categories [ index ] . default_task_color = color ; } private deepCopy ( source ) { let output ; let value ; output = Array . isArray ( source ) ? [ ] : { } ; for ( const key in source ) { if ( source . hasOwnProperty ( key ) ) { value = source [ key ] ; output [ key ] = ( typeof value === 'object' ) ? this . deepCopy ( value ) : value ; } } return output ; } public showModal ( title , board ? ) { const isAdd = ( title === 'Add' ) ; this . modalProps = new BoardData ( title ) ; if ( isAdd ) { this . users . forEach ( ( user ) => { user . selected = false ; } ) ; } else { this . modalProps . id = board . id ; this . modalProps . name = board . name ; this . modalProps . columns = this . deepCopy ( board . columns ) ; this . modalProps . categories = this . deepCopy ( board . categories ) ; this . modalProps . issue_trackers = this . deepCopy ( board . issue_trackers ) ; this . users . forEach ( ( user ) => { const filtered = board . users . filter ( u => + u . id === user . id ) ; user . selected = filtered . length > 0 ; } ) ; } this . modal . open ( this . MODAL_ID ) ; } public showConfirmModal ( board ) { this . boardToRemove = board ; this . modal . open ( this . MODAL_CONFIRM_ID ) ; } }