import { Injectable , OnDestroy } from '@angular/core' ; import { TypeService } from '../../framework/services/type.service' ; import { TemplateHelpdataElement } from '../models/template-helpdata-element' ; import { ReplaySubject } from 'rxjs' ; import { takeUntil } from 'rxjs/operators' ; import { CmdbType } from '../../framework/models/cmdb-type' ; @ Injectable ( { providedIn : 'root' } ) export class TemplateHelperService implements OnDestroy { private subscriber : ReplaySubject < void > ; constructor ( private typeService ) { this . subscriber = new ReplaySubject < void > ( ) ; } private async getSectionReferenceType ( typeID ) { return this . typeService . getType ( typeID ) . pipe ( takeUntil ( this . subscriber ) ) . toPromise ( ) ; } public async getObjectTemplateHelperData ( typeId , prefix = '' , iteration = 3 ) { const templateHelperData = [ ] ; templateHelperData . push ( ( { label : 'Public ID' , templatedata : ( prefix ? '{{fields' + prefix + '[\'id\']}}' : '{{id}}' ) } ) as TemplateHelpdataElement ) ; await this . typeService . getType ( typeId ) . subscribe ( async ( cmdbTypeObj ) => { for ( const field of cmdbTypeObj . fields ) { if ( field . type === 'ref' && iteration > 0 ) { const changedPrefix = ( prefix ? prefix + '[\'fields\'][\'' + field . name + '\']' : '[\'' + field . name + '\']' ) ; let subdata ; if ( ! isNaN ( field . ref_types ) && ! Array . isArray ( field . ref_types ) ) { await this . getObjectTemplateHelperData ( field . ref_types , changedPrefix , iteration - 1 ) . then ( data => { subdata = data ; } ) ; } else if ( field . ref_types . length === 1 ) { await this . getObjectTemplateHelperData ( field . ref_types [ 0 ] , changedPrefix , iteration - 1 ) . then ( data => { subdata = data ; } ) ; } else { subdata = [ ] ; await field . ref_types . forEach ( ( type ) => { this . getObjectTemplateHelperData ( type , changedPrefix , iteration - 1 ) . then ( data => { subdata . push ( ( { label : 'ref_type ' + type , subdata : data } ) ) ; } ) ; } ) ; } templateHelperData . push ( ( { label : field . label , subdata } ) as TemplateHelpdataElement ) ; } else if ( field . type === 'ref-section-field' ) { const refSection = cmdbTypeObj . render_meta . sections . find ( s => s . name === field . name . substring ( 0 , field . name . length - 6 ) ) ; const changedPrefix = ( prefix ? prefix + '[\'fields\'][\'' + field . name + '\']' : '[\'' + field . name + '\']' ) ; if ( ! refSection ) { continue ; } await this . getSectionReferenceType ( refSection . reference . type_id ) . then ( ( referenceType ) => { const referenceFields = [ ] ; let referenceFieldNames = [ ] ; if ( refSection . reference . selected_fields && refSection . reference . selected_fields . length > 0 ) { referenceFieldNames = refSection . reference . selected_fields ; } else { const referenceTypeSection = referenceType . render_meta . sections . find ( s => s . name === refSection . reference . section_name ) ; if ( referenceTypeSection ) { referenceFieldNames = referenceTypeSection . fields ; } } for ( const refFieldName of referenceFieldNames ) { const refField = referenceType . fields . find ( f => f . name === refFieldName ) ; if ( refField ) { referenceFields . push ( ( { label : refField . label , templatedata : ( changedPrefix ? '{{fields' + changedPrefix + '[\'fields\'][\'' + refField . name + '\']}}' : '{{fields[\'' + refField . name + '\']}}' ) } ) as TemplateHelpdataElement ) ; } } templateHelperData . push ( ( { label : field . label , subdata : referenceFields } ) as TemplateHelpdataElement ) ; } ) ; } else { templateHelperData . push ( ( { label : field . label , templatedata : ( prefix ? '{{fields' + prefix + '[\'fields\'][\'' + field . name + '\']}}' : '{{fields[\'' + field . name + '\']}}' ) } ) as TemplateHelpdataElement ) ; } } } , ( error ) => { console . error ( error ) ; } ) ; return templateHelperData ; } public ngOnDestroy ( ) { this . subscriber . next ( ) ; this . subscriber . complete ( ) ; } }