import { Injectable } from '@angular/core' ; import { CmdbType } from '../models/cmdb-type' ; import { ApiCallService , ApiService , HttpProtocolHelper , resp } from '../../services/api-call.service' ; import { Observable , timer } from 'rxjs' ; import { catchError , map , switchMap } from 'rxjs/operators' ; import { FormControl } from '@angular/forms' ; import { HttpHeaders , HttpParams , HttpResponse } from '@angular/common/http' ; import { APIDeleteSingleResponse , APIGetMultiResponse , APIGetSingleResponse , APIInsertSingleResponse , APIUpdateSingleResponse } from '../../services/models/api-response' ; import { CollectionParameters } from '../../services/models/api-parameter' ; import { ValidatorService } from '../../services/validator.service' ; import { UserService } from '../../management/services/user.service' ; import { AccessControlPermission } from '../../acl/acl.types' ; export const checkTypeExistsValidator = ( typeService , time = 500 ) => { return ( control ) => { return timer ( time ) . pipe ( switchMap ( ( ) => { return typeService . getTypeByName ( control . value ) . pipe ( map ( ( response ) => { if ( response === null ) { return null ; } else { return { typeExists : true } ; } } ) , catchError ( ( ) => { return new Promise ( resolve => { resolve ( null ) ; } ) ; } ) ) ; } ) ) ; } ; } ; @ Injectable ( { providedIn : 'root' } ) export class TypeService < T = CmdbType > implements ApiService { public servicePrefix : string = 'types' ; public options = { headers : new HttpHeaders ( { 'Content-Type' : 'application/json' } ) , params : { } , observe : resp } ; constructor ( private api , private userService ) { } public public getAclFilter ( aclRequirement = AccessControlPermission . READ ) { aclRequirement = Array . isArray ( aclRequirement ) ? aclRequirement : [ aclRequirement ] ; const location = 'acl.groups.includes.' + this . userService . getCurrentUser ( ) . group_id ; return { $or : [ { $or : [ { acl : { $exists : false } } , { 'acl.activated' : false } ] } , { $and : [ { 'acl.activated' : true } , { $and : [ { [ location ] : { $exists : true } } , { [ location ] : { $all : aclRequirement } } ] } , ] } ] } ; } param params param active public getTypes ( params = { filter : undefined , limit : 10 , sort : 'public_id' , order : 1 , page : 1 } , active = false ) { const options = this . options ; let httpParams = new HttpParams ( ) ; if ( params . filter !== undefined ) { const filter = JSON . stringify ( params . filter ) ; httpParams = httpParams . set ( 'filter' , filter ) ; } if ( params . projection !== undefined ) { const projection = JSON . stringify ( params . projection ) ; httpParams = httpParams . set ( 'projection' , projection ) ; } httpParams = httpParams . set ( 'limit' , params . limit . toString ( ) ) ; httpParams = httpParams . set ( 'sort' , params . sort ) ; httpParams = httpParams . set ( 'order' , params . order . toString ( ) ) ; httpParams = httpParams . set ( 'page' , params . page . toString ( ) ) ; httpParams = httpParams . set ( 'active' , JSON . stringify ( active ) ) ; options . params = httpParams ; return this . api . callGet < Array < T > > ( this . servicePrefix + '/' , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body ; } ) ) ; } param publicID public getType ( publicID ) { const options = this . options ; options . params = new HttpParams ( ) ; return this . api . callGet < CmdbType > ( this . servicePrefix + '/' + publicID , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body . result as T ; } ) ) ; } /**
     * Get the complete type list
     */ public getTypeList ( aclRequirement ? ) { const options = this . options ; let params = new HttpParams ( ) ; params = params . set ( 'limit' , '0' ) ; params = params . set ( 'filter' , JSON . stringify ( this . getAclFilter ( aclRequirement ) ) ) ; options . params = params ; return this . api . callGet < Array < T > > ( this . servicePrefix + '/' , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body . results as Array < T > ; } ) ) ; } param name public getTypeByName ( name ) { const options = this . options ; const filter = { name } ; let params = new HttpParams ( ) ; params = params . set ( 'filter' , JSON . stringify ( filter ) ) ; options . params = params ; return this . api . callGet < Array < T > > ( this . servicePrefix + '/' , options ) . pipe ( map ( ( apiResponse ) => { if ( apiResponse . body . count === 0 ) { return null ; } return apiResponse . body . results [ 0 ] as T ; } ) ) ; } param name param aclRequirements public getTypesByNameOrLabel ( name , aclRequirements ? ) { const regex = ValidatorService . validateRegex ( name ) . trim ( ) ; const filter = { $and : [ { $or : [ { name : { $regex : regex , $options : 'ism' } } , { label : { $regex : regex , $options : 'ism' } } ] } , this . getAclFilter ( aclRequirements ) ] } ; const options = HttpProtocolHelper . createHttpProtocolOptions ( this . options , JSON . stringify ( filter ) , 0 ) ; return this . api . callGet < Array < T > > ( this . servicePrefix + '/' , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body . results as Array < T > ; } ) ) ; } /**
     * Insert a new type into the database.
     */ public postType ( type ) { const options = this . options ; options . params = new HttpParams ( ) ; return this . api . callPost < T > ( this . servicePrefix + '/' , type , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body . raw as T ; } ) ) ; } /**
     * Update a existing type in the database.
     */ public putType ( type ) { const options = this . options ; options . params = new HttpParams ( ) ; return this . api . callPut < T > ( this . servicePrefix + '/' + type . public_id , type , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body . result as T ; } ) ) ; } returns public deleteType ( publicID ) { const options = this . options ; options . params = new HttpParams ( ) ; return this . api . callDelete < number > ( this . servicePrefix + '/' + publicID , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body . raw as T ; } ) ) ; } param aclRequirements param active public getUncategorizedTypes ( aclRequirements ? , active = true ) { const pipeline = [ { $match : this . getAclFilter ( aclRequirements ) } , { $lookup : { from : 'framework.categories' , localField : 'public_id' , foreignField : 'types' , as : 'categories' } } , { $match : { categories : { $size : 0 } } } , { $project : { categories : 0 } } ] ; const options = HttpProtocolHelper . createHttpProtocolOptions ( this . options , JSON . stringify ( pipeline ) , 0 ) ; options . params = options . params . set ( 'active' , JSON . stringify ( active ) ) ; return this . api . callGet < T [ ] > ( this . servicePrefix + '/' , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body as APIGetMultiResponse < T > ; } ) ) ; } param categoryID param aclRequirements public getTypeListByCategory ( categoryID , aclRequirements ? ) { const pipeline = [ { $lookup : { from : 'framework.categories' , let : { type_id : { $toInt : '$public_id' } } , pipeline : [ { $match : { public_id : categoryID } } , { $match : { $expr : { $in : [ '$$type_id' , '$types' ] } } } ] , as : 'category' } } , { $match : { $and : [ { category : { $gt : { $size : 0 } } } , this . getAclFilter ( aclRequirements ) ] } } , { $project : { category : 0 } } ] ; const options = HttpProtocolHelper . createHttpProtocolOptions ( this . options , JSON . stringify ( pipeline ) , 0 ) ; options . params = options . params . set ( 'active' , false . toString ( ) ) ; return this . api . callGet < Array < T > > ( this . servicePrefix + '/' , options ) . pipe ( map ( ( apiResponse ) => { return apiResponse . body . results as Array < T > ; } ) ) ; } /**
     * Get the total number of types in the system.
     */ public countTypes ( ) { const options = this . options ; options . params = new HttpParams ( ) ; return this . api . callHead < T [ ] > ( this . servicePrefix + '/' , options ) . pipe ( map ( ( apiResponse ) => { return + apiResponse . headers . get ( 'X-Total-Count' ) ; } ) ) ; } }