import { ApplicationRef, Injectable, NgZone } from '@angular/core'; import { FormArray, FormGroup } from '@angular/forms'; import { isNumeric } from 'rxjs/internal/util/isNumeric'; import { Rule } from '../../../../core/model/dataset-profile-definition/rule'; import { VisibilityRule } from './models/visibility-rule'; import { VisibilityRulesContext } from './models/visibility-rules-context'; @Injectable() export class VisibilityRulesService { private visibilityRuleContext: VisibilityRulesContext; private elementVisibilityMap = new Map(); constructor( public applicationReference: ApplicationRef, public ngZone: NgZone ) { } public checkElementVisibility(id: string): boolean { if (this.visibilityRuleContext.rules.filter(item => item.targetControlId === id).length === 0) { return true; } return this.elementVisibilityMap.has(id) ? this.elementVisibilityMap.get(id) : false; } public buildVisibilityRules(item: Array) { this.visibilityRuleContext = new VisibilityRulesContext(); this.visibilityRuleContext.buildVisibilityRuleContext(item || []); } public updateValueAndVisibility(id: string, value: any) { const visibilityRules = this.visibilityRuleContext.rules.filter(item => item.sourceVisibilityRules.filter(source => source.sourceControlId === id).length > 0); visibilityRules.forEach(item => this.evaluateVisibility(item, value)); } private evaluateVisibility(visibilityRule: VisibilityRule, value: any) { for (let i = 0; i < visibilityRule.sourceVisibilityRules.length; i++) { if (value != null && (this.parseValue(value) !== this.parseValue(visibilityRule.sourceVisibilityRules[i].sourceControlValue))) { this.elementVisibilityMap.set(visibilityRule.targetControlId, false); this.updateValueAndVisibility(visibilityRule.targetControlId, null); // this.clearValues(targetPathKey); return; } } this.elementVisibilityMap.set(visibilityRule.targetControlId, true); this.updateValueAndVisibility(visibilityRule.targetControlId, null); } parseValue(value: any) { if (typeof value === 'string') { if (isNumeric(value)) { return value; } else if (value === 'true') { return true; } else if (value === 'false') { return false; } else { return this.translate(value); } } else { return value; } } search(path, obj, target) { for (const k in obj) { if (obj.hasOwnProperty(k)) { if (obj[k] === target) { return path + '.' + k; } else if (typeof obj[k] === 'object') { const result = this.search(path + '.' + k, obj[k], target); if (result) { return result; } } } } return false; } scanIfChildsOfCompositeFieldHasVisibleItems(compositeFieldParent: FormGroup): boolean { let isVisible = false; ((compositeFieldParent.get('fields'))).controls.forEach(element => { if (this.checkElementVisibility(element.get('id').value)) { isVisible = true; } }); return isVisible; } private translate(item: any) { try { return JSON.parse(item).value; } catch (error) { return item; } } }