import { Component , OnDestroy , OnInit , TemplateRef , ViewChild } from '@angular/core' ; import { TypeService } from '../services/type.service' ; import { BehaviorSubject , ReplaySubject } from 'rxjs' ; import { APIGetMultiResponse } from '../../services/models/api-response' ; import { CmdbType } from '../models/cmdb-type' ; import { FileSaverService } from 'ngx-filesaver' ; import { DatePipe } from '@angular/common' ; import { FileService } from '../../export/export.service' ; import { Column , Sort , SortDirection , TableState , TableStatePayload } from '../../layout/table/table.types' ; import { CollectionParameters } from '../../services/models/api-parameter' ; import { takeUntil } from 'rxjs/operators' ; import { PermissionService } from '../../auth/services/permission.service' ; import { ActivatedRoute , Data , Router } from '@angular/router' ; import { UserSetting } from '../../management/user-settings/models/user-setting' ; import { convertResourceURL , UserSettingsService } from '../../management/user-settings/services/user-settings.service' ; import { UserSettingsDBService } from '../../management/user-settings/services/user-settings-db.service' ; @ Component ( { selector : 'cmdb-type' , templateUrl : './type.component.html' , styleUrls : [ './type.component.scss' ] } ) export class TypeComponent implements OnInit , OnDestroy { /**
     * HTML ID of the table.
     * Used for user settings and table-states
     */ public readonly id : string = 'type-list-table' ; /**
     * Global un-subscriber for http calls to the rest backend.
     */ private subscriber : ReplaySubject < void > = new ReplaySubject < void > ( ) ; /**
     * Info message.
     */ public readonly INFO_MESSAGE : string = '' + 'DATAGERRY is an asset management tool (or CMDB), where you can define the data model for your own.\n' + '\n' + 'In DATAGERRY objects are stored. An object can be for example a router, server, location or maintenance contract and\n' + ' consists of multiple fields (e.g. management IP, hostname, … of a router). Each field has a specific data type.\n' + ' A datatype could be for example text, checkbox, date, dropdown or many more. The blueprint for an object is defined\n' + ' in an object type.' ; /**
     * Current category collection
     */ public types : Array < CmdbType > = [ ] ; public typesAPIResponse : APIGetMultiResponse < CmdbType > ; public totalTypes : number = 0 ; /**
     * Type selection.
     */ public selectedTypes : Array < CmdbType > = [ ] ; public selectedTypeIDs : Array < number > = [ ] ; /**
     * Table Template: active column.
     */ @ ViewChild ( 'activeTemplate' , { static : true } ) activeTemplate : TemplateRef < any > ; /**
     * Table Template: Type name column.
     */ @ ViewChild ( 'typeNameTemplate' , { static : true } ) typeNameTemplate : TemplateRef < any > ; /**
     * Table Template: Type actions column.
     */ @ ViewChild ( 'actionsTemplate' , { static : true } ) actionsTemplate : TemplateRef < any > ; /**
     * Table Template: Type clean column.
     */ @ ViewChild ( 'cleanTemplate' , { static : true } ) cleanTemplate : TemplateRef < any > ; /**
     * Table Template: Type date column.
     */ @ ViewChild ( 'dateTemplate' , { static : true } ) dateTemplate : TemplateRef < any > ; /**
     * Table Template: user column.
     */ @ ViewChild ( 'userTemplate' , { static : true } ) userTemplate : TemplateRef < any > ; /**
     * Table columns definition.
     */ public columns : Array < Column > ; /**
     * Table selection enabled.
     */ public selectEnabled : boolean = false ; /**
     * Begin with first page.
     */ public readonly initPage : number = 1 ; public page : number = this . initPage ; private private readonly initLimit : number = 10 ; public limit : number = this . initLimit ; /**
     * Filter query from the table search input.
     */ public filter : string ; /**
     * Default sort filter.
     */ public sort : Sort = { name : 'public_id' , order : SortDirection . DESCENDING } as Sort ; /**
     * Loading indicator.
     */ public loading : boolean = false ; public tableStateSubject : BehaviorSubject < TableState > = new BehaviorSubject < TableState > ( undefined ) ; public tableStates : Array < TableState > = [ ] ; public get tableState ( ) : TableState { return this . tableStateSubject . getValue ( ) as TableState ; } constructor ( private typeService , private fileService , private route , private permissionService , private fileSaverService , private datePipe , private router , private userSettingsService , private indexDB ) { this . route . data . pipe ( takeUntil ( this . subscriber ) ) . subscribe ( ( data ) => { if ( data . userSetting ) { const userSettingPayloads = ( data . userSetting as UserSetting < TableStatePayload > ) . payloads . find ( payloads => payloads . id === this . id ) ; this . tableStates = userSettingPayloads . tableStates ; this . tableStateSubject . next ( userSettingPayloads . currentState ) ; } else { this . tableStates = [ ] ; this . tableStateSubject . next ( undefined ) ; const statePayload = new TableStatePayload ( this . id , [ ] ) ; const resource = convertResourceURL ( this . router . url . toString ( ) ) ; const userSetting = this . userSettingsService . createUserSetting < TableStatePayload > ( resource , [ statePayload ] ) ; this . indexDB . addSetting ( userSetting ) ; } } ) ; } /**
     * Starts the component and init the table
     */ public ngOnInit ( ) { this . columns = [ { display : 'Active' , name : 'active' , data : 'active' , searchable : false , sortable : true , template : this . activeTemplate , cssClasses : [ 'text-center' ] , style : { width : '6rem' } } , { display : 'Public ID' , name : 'public_id' , data : 'public_id' , searchable : true , sortable : true } , { display : 'Type' , name : 'name' , data : 'name' , searchable : true , sortable : true , template : this . typeNameTemplate , } , { display : 'Author' , name : 'author_id' , data : 'author_id' , searchable : true , sortable : true , template : this . userTemplate } , { display : 'Creation Time' , name : 'creation_time' , data : 'creation_time' , sortable : true , searchable : false , template : this . dateTemplate , } , { display : 'Last editor' , name : 'editor_id' , data : 'editor_id' , sortable : true , searchable : true , template : this . userTemplate } , { display : 'Modification Time' , name : 'last_edit_time' , data : 'last_edit_time' , sortable : true , searchable : false , template : this . dateTemplate , } , { display : 'Actions' , name : 'actions' , searchable : false , sortable : false , fixed : true , template : this . actionsTemplate , cssClasses : [ 'text-center' ] , cellClasses : [ 'actions-buttons' ] } , ] as Array < Column > ; const cleanRight = 'base.framework.type.clean' ; if ( this . permissionService . hasRight ( cleanRight ) || this . permissionService . hasExtendedRight ( cleanRight ) ) { this . columns . push ( { display : 'Clean' , name : 'clean' , searchable : false , sortable : false , fixed : true , template : this . cleanTemplate , cssClasses : [ 'text-center' ] , cellClasses : [ 'text-center' ] } as Column ) ; } const exportRight = 'base.export.type.*' ; if ( this . permissionService . hasRight ( exportRight ) || this . permissionService . hasExtendedRight ( exportRight ) ) { this . selectEnabled = true ; } this . initTable ( ) ; this . loadTypesFromAPI ( ) ; } private private initTable ( ) { if ( this . tableState ) { this . sort = this . tableState . sort ; this . page = this . tableState . page ; this . limit = this . tableState . pageSize ; } } private private loadTypesFromAPI ( ) { this . loading = true ; let query ; if ( this . filter ) { query = [ ] ; const or = [ ] ; const searchableColumns = this . columns . filter ( c => c . searchable ) ; for ( const column of searchableColumns ) { const regex = { } ; regex [ column . name ] = { $regex : String ( this . filter ) , $options : 'ismx' } ; or . push ( regex ) ; } query . push ( { $addFields : { public_id : { $toString : '$public_id' } } } ) ; or . push ( { public_id : { $elemMatch : { value : { $regex : String ( this . filter ) , $options : 'ismx' } } } } ) ; query . push ( { $match : { $or : or } } ) ; } const params = { filter : query , limit : this . limit , sort : this . sort . name , order : this . sort . order , page : this . page } ; this . typeService . getTypes ( params ) . pipe ( takeUntil ( this . subscriber ) ) . subscribe ( ( apiResponse ) => { this . typesAPIResponse = apiResponse ; this . types = apiResponse . results as Array < CmdbType > ; this . totalTypes = apiResponse . total ; this . loading = false ; } ) ; } /**
     * Destroy subscriptions after closed.
     */ public ngOnDestroy ( ) { this . subscriber . next ( ) ; this . subscriber . complete ( ) ; } param sort public onSortChange ( sort ) { this . sort = sort ; this . loadTypesFromAPI ( ) ; } onStateReset ( ) { this . limit = this . initLimit ; this . page = this . initPage ; this . sort = { name : 'public_id' , order : SortDirection . DESCENDING } as Sort ; } param selectedItems public onSelectedChange ( selectedItems ) { this . selectedTypes = selectedItems ; this . selectedTypeIDs = selectedItems . map ( t => t . public_id ) ; } param page public onPageChange ( page ) { this . page = page ; this . loadTypesFromAPI ( ) ; } param limit public onPageSizeChange ( limit ) { this . limit = limit ; this . loadTypesFromAPI ( ) ; } param search public onSearchChange ( search ) { if ( search ) { this . filter = search ; } else { this . filter = undefined ; } this . loadTypesFromAPI ( ) ; } param state public onStateSelect ( state ) { this . tableStateSubject . next ( state ) ; this . page = this . tableState . page ; this . limit = this . tableState . pageSize ; this . sort = this . tableState . sort ; for ( const col of this . columns ) { col . hidden = ! this . tableState . visibleColumns . includes ( col . name ) ; } this . loadTypesFromAPI ( ) ; } param data param exportType public downLoadFile ( data , exportType ) { const timestamp = this . datePipe . transform ( new Date ( ) , 'MM_dd_yyyy_hh_mm_ss' ) ; this . fileSaverService . save ( data . body , timestamp + '.' + exportType ) ; } /**
     * Call the export routes with the selected types
     */ public exportingFiles ( ) { if ( this . selectedTypeIDs . length === 0 || this . selectedTypeIDs . length === this . totalTypes ) { this . fileService . getTypeFile ( ) . subscribe ( res => this . downLoadFile ( res , 'json' ) ) ; } else { this . fileService . callExportTypeRoute ( '/export/type/' + this . selectedTypeIDs . toString ( ) ) . subscribe ( res => this . downLoadFile ( res , 'json' ) ) ; } } /**
     * Quick-hack to open the selection box.
     */ public showAlert ( ) { $ ( '#infobox' ) . show ( ) ; } }