import { Component , OnDestroy , OnInit , TemplateRef , ViewChild } from '@angular/core' ; import { ApiCallService } from '../services/api-call.service' ; import { TypeService } from '../framework/services/type.service' ; import { ObjectService } from '../framework/services/object.service' ; import { CmdbCategory } from '../framework/models/cmdb-category' ; import { CategoryService } from '../framework/services/category.service' ; import { GroupService } from '../management/services/group.service' ; import { Group } from '../management/models/group' ; import { UserService } from '../management/services/user.service' ; import { APIGetMultiResponse } from '../services/models/api-response' ; import { RenderResult } from '../framework/models/cmdb-render' ; import { Column } from '../layout/table/table.types' ; import { takeUntil } from 'rxjs/operators' ; import { ReplaySubject } from 'rxjs' ; import { ToastService } from '../layout/toast/toast.service' ; import { SidebarService } from '../layout/services/sidebar.service' ; import { CollectionParameters } from '../services/models/api-parameter' ; import { CmdbType } from '../framework/models/cmdb-type' ; @ Component ( { selector : 'cmdb-dashboard' , templateUrl : './dashboard.component.html' , styleUrls : [ './dashboard.component.scss' ] } ) export class DashboardComponent implements OnInit , OnDestroy { /**
     * Table Template: Dashboard active column.
     */ @ ViewChild ( 'activeTemplate' , { static : true } ) activeTemplate : TemplateRef < any > ; /**
     * Table Template: Dashboard user column.
     */ @ ViewChild ( 'userTemplate' , { static : true } ) userTemplate : TemplateRef < any > ; /**
     * Table Template: Dashboard action column.
     */ @ ViewChild ( 'actionTemplate' , { static : true } ) actionTemplate : TemplateRef < any > ; /**
     * Table Template: Dashboard date column.
     */ @ ViewChild ( 'dateTemplate' , { static : true } ) dateTemplate : TemplateRef < any > ; /**
     * Global unsubscriber for http calls to the rest backend.
     */ private unSubscribe : ReplaySubject < void > = new ReplaySubject ( ) ; public objectCount : number = 0 ; public typeCount : number = 0 ; public userCount : number = 0 ; public readonly maxChartValue : number = 4 ; public labelsObject : string [ ] = [ ] ; public itemsObject : number [ ] = [ ] ; public colorsObject : any [ ] = [ ] ; public optionsObject : { } = { } ; public labelsCategory : string [ ] = [ ] ; public itemsCategory : number [ ] = [ ] ; public colorsCategory : any [ ] = [ ] ; public labelsGroup : string [ ] = [ ] ; public itemsGroup : number [ ] = [ ] ; public colorsGroup : any [ ] = [ ] ; public newestObjects : Array < RenderResult > = [ ] ; public newestTableColumns : Array < Column > = [ ] ; public newestObjectsCount : number = 0 ; public readonly newestInnitPage : number = 1 ; public newestPage : number = this . newestInnitPage ; public newestLoading : boolean = false ; public latestObjects : Array < RenderResult > = [ ] ; public latestTableColumns : Array < Column > = [ ] ; public latestObjectsCount : number = 0 ; public readonly latestInnitPage : number = 1 ; public latestPage : number = this . latestInnitPage ; public latestLoading : boolean = false ; constructor ( private api , private typeService , private objectService , private categoryService , private toastService , private sidebarService , private userService , private groupService ) { } public ngOnInit ( ) { const activeColumn = { display : 'Active' , name : 'active' , data : 'object_information.active' , searchable : false , sortable : false , template : this . activeTemplate , cssClasses : [ 'text-center' ] , style : { width : '6rem' } } as unknown as Column ; const publicColumn = { display : 'Public ID' , name : 'public_id' , data : 'object_information.object_id' , cssClasses : [ 'text-center' ] , style : { width : '6rem' } , searchable : false , sortable : false } as unknown as Column ; const typeColumn = { display : 'Type' , name : 'type' , data : 'type_information.type_label' , cssClasses : [ 'text-center' ] , searchable : false , sortable : false } as unknown as Column ; const authorColumn = { display : 'Author' , name : 'author_id' , data : 'object_information.author_name' , sortable : false , searchable : false , cssClasses : [ 'text-center' ] } as Column ; const editorColumn = { display : 'Last editor' , name : 'editor_id' , data : 'object_information.editor_name' , sortable : false , searchable : false , cssClasses : [ 'text-center' ] , render ( data ) { if ( ! data ) { return '' ; } return data ; } } as Column ; const creationColumn = { display : 'Creation Time' , name : 'creation_time' , data : 'object_information.creation_time' , sortable : false , searchable : false , cssClasses : [ 'text-center' ] , template : this . dateTemplate , } as Column ; const lastModColumn = { display : 'Modification Time' , name : 'last_edit_time' , data : 'object_information.last_edit_time' , sortable : false , searchable : false , cssClasses : [ 'text-center' ] , template : this . dateTemplate , render ( data ) { if ( ! data ) { return 'No modifications so far.' ; } return data ; } } as Column ; const actionColumn = { display : 'Actions' , name : 'actions' , sortable : false , searchable : false , fixed : true , template : this . actionTemplate , cssClasses : [ 'text-center' ] , style : { width : '6em' } } as unknown as Column ; this . newestTableColumns = [ activeColumn , publicColumn , typeColumn , authorColumn , creationColumn , actionColumn ] ; this . latestTableColumns = [ activeColumn , publicColumn , typeColumn , editorColumn , lastModColumn , actionColumn ] ; this . countTypes ( ) ; this . countObjects ( ) ; this . userService . countUsers ( ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( totals ) => { this . userCount = totals ; } ) ; this . loadNewestObjects ( ) ; this . loadLatestObjects ( ) ; this . generateObjectChar ( ) ; this . generateTypeChar ( ) ; this . generateGroupChar ( ) ; } private countObjects ( ) { const apiParameters = { limit : 1 , sort : 'public_id' , order : 1 , page : 1 , filter : [ { $match : { } } ] } ; this . objectService . getObjects ( apiParameters ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( apiResponse ) => { this . objectCount = apiResponse . total ; } ) ; } private countTypes ( ) { const filter = JSON . stringify ( this . typeService . getAclFilter ( ) ) ; const apiParameters = { page : 1 , limit : 1 , sort : 'public_id' , order : 1 , filter } ; this . typeService . getTypes ( apiParameters ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( response ) => { this . typeCount = response . total ; } ) ; } public onNewestPageChange ( event ) { this . newestPage = event ; this . loadNewestObjects ( ) ; } public onLatestPageChange ( event ) { this . latestPage = event ; this . loadLatestObjects ( ) ; } private loadNewestObjects ( ) { this . newestLoading = true ; const apiParameters = { page : this . newestPage , limit : 10 , order : - 1 } ; this . objectService . getNewestObjects ( apiParameters ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( apiResponse ) => { this . newestObjects = apiResponse . results as Array < RenderResult > ; this . newestObjectsCount = apiResponse . total ; } , ( ) => { } , ( ) => { this . newestLoading = false ; } ) ; } private loadLatestObjects ( ) { this . latestLoading = true ; const apiParameters = { page : this . latestPage , limit : 10 , order : - 1 } ; this . objectService . getLatestObjects ( apiParameters ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( apiResponse ) => { this . latestObjects = apiResponse . results as Array < RenderResult > ; this . latestObjectsCount = apiResponse . total ; } , ( ) => { } , ( ) => { this . latestLoading = false ; } ) ; } private generateObjectChar ( ) { this . optionsObject = { responsive : true , legend : { display : false } , scales : { yAxes : [ { ticks : { beginAtZero : true } } ] } , } ; this . objectService . groupObjectsByType ( 'type_id' ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( values => { for ( const obj of values ) { this . labelsObject . push ( obj . label ) ; this . colorsObject . push ( this . getRandomColor ( ) ) ; this . itemsObject . push ( obj . count ) ; } } ) ; } private generateTypeChar ( ) { const params = { filter : undefined , limit : 5 , sort : 'public_id' , order : 1 , page : 1 , view : 'tree' } ; this . categoryService . getCategories ( params ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( apiResponse ) => { const categories = apiResponse . results as Array < CmdbCategory > ; for ( const cate of categories ) { this . itemsCategory . push ( cate . types . length ) ; this . labelsCategory . push ( cate . label ) ; this . colorsCategory . push ( this . getRandomColor ( ) ) ; } } ) ; } private generateGroupChar ( ) { const groupsCallParameters = { filter : [ { $lookup : { from : 'management.users' , localField : 'public_id' , foreignField : 'group_id' , as : 'users' } } ] , limit : 5 , sort : 'public_id' , order : 1 , page : 1 } ; this . groupService . getGroups ( groupsCallParameters ) . subscribe ( ( data ) => { for ( let i = 0 ; i < data . results . length ; i ++ ) { this . userService . countUsers ( { group_id : data . results [ i ] . public_id } ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( nUsers ) => { this . labelsGroup . push ( data . results [ i ] . label ) ; this . colorsGroup . push ( this . getRandomColor ( ) ) ; this . itemsGroup . push ( nUsers ) ; } ) ; if ( i === this . maxChartValue ) { break ; } } } ) ; } getRandomColor ( ) { const color = Math . floor ( 0x1000000 * Math . random ( ) ) . toString ( 16 ) ; return '#' + ( '000000' + color ) . slice ( - 6 ) ; } public onObjectDelete ( value ) { this . objectService . deleteObject ( value . object_information . object_id ) . pipe ( takeUntil ( this . unSubscribe ) ) . subscribe ( ( ) => { this . toastService . success ( `Object ${ value . object_information . object_id } was deleted successfully` ) ; this . sidebarService . updateTypeCounter ( value . type_information . type_id ) . then ( ( ) => { this . loadLatestObjects ( ) ; this . loadNewestObjects ( ) ; } ) ; } , ( error ) => { this . toastService . error ( `Error while deleting object ${ value . object_information . object_id } | Error: ${ error }` ) ; } ) ; } public ngOnDestroy ( ) { this . unSubscribe . next ( ) ; this . unSubscribe . complete ( ) ; } }