import { VisibilityRule } from './models/VisibilityRule'; import { VisibilityRulesContext } from './models/VisibilityRulesContext'; import { FormGroup } from '@angular/forms'; import { Injectable, ApplicationRef, NgZone } from '@angular/core'; import { Rule } from '../../models/Rule'; import { DatasetProfileDefinitionModel } from '../../models/DatasetProfileDefinitionModel'; import { JsonSerializer } from '../JsonSerializer'; @Injectable() export class VisibilityRulesService { public formGroup: FormGroup; public visibilityRuleContext: VisibilityRulesContext; public fieldsPathMemory: any = {}; private elementVisibilityMap = new Map(); private initialModel: DatasetProfileDefinitionModel; private currentModel: DatasetProfileDefinitionModel; constructor(public applicationReference: ApplicationRef, public ngZone: NgZone) { } public setModel(model: DatasetProfileDefinitionModel) { this.initialModel = JsonSerializer.fromJSONObject(model, DatasetProfileDefinitionModel); this.currentModel = model this.visibilityRuleContext.rules.forEach(item => this.evaluateVisibility(item)) } public getFormGroup(id: string): FormGroup { let pathKeyArray = this.search("pages", this.initialModel.pages, id).split(".") pathKeyArray.pop(); let pathKey = pathKeyArray.join("."); if (!this.fieldsPathMemory[id] && pathKey) this.fieldsPathMemory[id] = pathKey; return (this.formGroup.get(pathKey)); } public checkElementVisibility(id: string): boolean { if (!this.elementVisibilityMap.has(id) || this.elementVisibilityMap.get(id)) return true; else return false; } public buildVisibilityRules(item: Array) { this.visibilityRuleContext = new VisibilityRulesContext(); this.visibilityRuleContext.buildVisibilityRuleContext(item); } public updateValueAndVisibility(id: string) { let visibilityRules = this.visibilityRuleContext.rules.filter(item => item.sourceVisibilityRules.filter(source => source.sourceControlId === id).length > 0); visibilityRules.forEach(item => this.evaluateVisibility(item)) } private evaluateVisibility(visibilityRule: VisibilityRule) { for (let i = 0; i < visibilityRule.sourceVisibilityRules.length; i++) { let pathKey = this.fieldsPathMemory[visibilityRule.sourceVisibilityRules[i].sourceControlId]; if (this.formGroup.get(pathKey + '.value') && ((this.formGroup.get(pathKey + '.value').value == null || this.formGroup.get(pathKey + '.value').value == undefined) || "" + this.formGroup.get(pathKey + '.value').value != "" + visibilityRule.sourceVisibilityRules[i].sourceControlValue)) { if (this.formGroup.get(pathKey).parent.get("id")) { if (!this.checkElementVisibility(this.formGroup.get(pathKey).parent.get("id").value)) { let targetPathKey = this.fieldsPathMemory[visibilityRule.targetControlId] this.getObject(this.currentModel, "id", visibilityRule.targetControlId, this.currentModel, true) this.elementVisibilityMap.set(visibilityRule.targetControlId, false) this.clearValues(targetPathKey) return; } } else { let targetPathKey = this.fieldsPathMemory[visibilityRule.targetControlId] this.getObject(this.currentModel, "id", visibilityRule.targetControlId, this.currentModel, true) this.elementVisibilityMap.set(visibilityRule.targetControlId, false) this.clearValues(targetPathKey) return; } } } let obj = this.getObject(this.initialModel, "id", visibilityRule.targetControlId, this.initialModel) let targetObjPathKey = this.fieldsPathMemory[visibilityRule.targetControlId] ? this.fieldsPathMemory[visibilityRule.targetControlId] : this.search("pages", this.initialModel.pages, obj); this.updateValue(this.currentModel, obj, targetObjPathKey) this.elementVisibilityMap.set(visibilityRule.targetControlId, true) } private getParentPath(parentId: string): string { return ''; } private clearValues(pathKey) { if (pathKey && this.formGroup.get(pathKey + '.value')) this.formGroup.get(pathKey + '.value').patchValue(null) if (pathKey && this.formGroup.get(pathKey)["controls"].fields) { for (var i = 0; i < this.formGroup.get(pathKey)["controls"].fields.length; i++) this.clearValues(pathKey + '.fields.' + i); } } // deleteFromModel(path: string, obj: any) { // if (!path) return // const _obj = JSON.parse(JSON.stringify(obj)); // const keys = path.split('.'); // keys.reduce((acc, key, index) => { // if (index === keys.length - 1) { // delete acc[key]; // return true; // } // return acc[key]; // }, _obj); // return _obj; // } updateValue(obj, value, path) { var i; if (value['id'].targetControlId === "other216a") debugger; path = path.split('.'); for (i = 0; i < path.length - 1; i++) obj = obj[path[i]]; for (let propIndex = 0; propIndex < obj.length; propIndex++) { if (obj[propIndex]["id"] === value["id"]) return } obj.splice(path[i], 0, value); } search(path, obj, target) { for (var k in obj) { if (obj.hasOwnProperty(k)) if (obj[k] === target) return path + "." + k else if (typeof obj[k] === "object") { var result = this.search(path + "." + k, obj[k], target); if (result) return result; } } return false; } private getObject(obj, key, val, parent, deleteObj = false) { for (var i in obj) { if (!obj.hasOwnProperty(i)) continue; if (typeof obj[i] == 'object') { let returnObj = this.getObject(obj[i], key, val, obj, deleteObj); if (returnObj) return returnObj } else if (i == key && obj[key] == val) { //console.log(obj[key]) if (deleteObj) parent.splice(parent.indexOf(obj), 1); return obj } } } }