// import { ApplicationRef, Injectable, NgZone } from '@angular/core'; // import { AbstractControl, UntypedFormArray, UntypedFormGroup } from '@angular/forms'; // import { isNumeric } from '@app/utilities/enhancers/utils'; // import { Observable, Subject } from 'rxjs'; // import { VisibilityRule } from './models/visibility-rule'; // import { VisibilityRuleSource } from './models/visibility-rule-source'; // import { VisibilityRulesContext } from './models/visibility-rules-context'; // import { DescriptionTemplate, DescriptionTemplatePage, DescriptionTemplateSection } from '@app/core/model/description-template/description-template'; // import { Rule } from './models/rule'; // @Injectable() // export class VisibilityRulesService { // private readonly VISIBILITY_RULE_LOGIC: 'OR' | 'AND' = 'OR'; // private readonly DEFAULTVISIBILITY = false; // private visibilityRuleContext: VisibilityRulesContext; // private form: AbstractControl; // public isVisibleMap: { [key: string]: boolean } = {}; // private elementVisibilityMapSubject = new Subject<{ [key: string]: boolean }>(); // private elementComputationalMap = new Map>(); /// keep saved the values of each form control validity value // private _changeMade$ = new Subject(); // // get isVisibleMap(): MapWithDefault { // // // console.log('isVisibleMap'); // // return this.elementVisibilityMap; // // }; /// keep saved the values of each form control validity value // constructor( // public applicationReference: ApplicationRef, // public ngZone: NgZone // ) { // } // getElementVisibilityMapObservable(): Observable<{ [key: string]: boolean }> { // // this.isVisibleMap // // console.log('getElementVisibilityMapObservable: '); // return this.elementVisibilityMapSubject.asObservable(); // } // public checkElementVisibility(id: string): boolean { // //console.log('checkElementVisibility: ' + id); // return true; // // if (this.visibilityRuleContext.rules.filter(item => item.targetControlId === id).length === 0) { return true; } // // console.log(this.elementVisibilityMap.has(id) ? this.elementVisibilityMap.get(id) : false); // // return this.elementVisibilityMap.has(id) ? this.elementVisibilityMap.get(id) : false; // } // public buildVisibilityRules(item: Array, form: AbstractControl) { // this.visibilityRuleContext = new VisibilityRulesContext(); // this.visibilityRuleContext.buildVisibilityRuleContext(item || []); // this.form = form; // this.resetVisibilityRules(); // } // public updateValueAndVisibility(id: string, value: any) { // //console.log('updateValueAndVisibility: ' + id + ' value: ' + value); // const visibilityRules = this.visibilityRuleContext.rules.filter(item => item.sourceVisibilityRules.filter(source => source.sourceControlId === id).length > 0); // if (visibilityRules.length > 0) { // visibilityRules.forEach(item => this.evaluateVisibility(item, value, id)); // this.elementVisibilityMapSubject.next(this.isVisibleMap); // } // } // private evaluateVisibility(visibilityRule: VisibilityRule, value: any, sourceId: string) {// source controlId is the same // //console.log('evaluateVisibility: ' + visibilityRule + ' value: ' + value + ' sourceId: ' + sourceId); // const targetId = visibilityRule.targetControlId; // const visibilityMap = this.elementComputationalMap.get(targetId) ? this.elementComputationalMap.get(targetId) : new Map(); // if (value instanceof Array) { // const parsedSourceControlValues = visibilityRule.sourceVisibilityRules.map(e => this.parseValue(e.sourceControlValue)); // const parsedValues = value.map(e => this.parseValue(e)); // const isVisible = parsedValues.map(v => parsedSourceControlValues.includes(v)).reduce((acc, current) => acc || current, false); // // if(isVisible){ // // this._emitChangesIfNeeded(visibilityRule.targetControlId, true); // // this.elementVisibilityMap.set(visibilityRule.targetControlId, true); // // return; // // } // visibilityMap.set(sourceId, isVisible); // } else { // const visibilityDependencySource = visibilityRule.sourceVisibilityRules.filter(x => x.sourceControlId === sourceId); // const shouldBeVisible = visibilityDependencySource.reduce((isVisible, x) => { // const shouldBeHidden = value !== null && (this.parseValue(value) !== this.parseValue(x.sourceControlValue)); // return this.VISIBILITY_RULE_LOGIC === 'OR' ? (isVisible || !shouldBeHidden) : (isVisible && !shouldBeHidden); // // if(value !== null && ) // }, this.VISIBILITY_RULE_LOGIC === 'AND'); // visibilityMap.set(sourceId, shouldBeVisible); // } // this.elementComputationalMap.set(targetId, visibilityMap);// unnessecary // const isVisible = this._computeVisibility(targetId); // this._emitChangesIfNeeded(targetId, isVisible); // const previousVisibility = this.isVisibleMap[targetId]; // this.isVisibleMap[targetId] = isVisible; // if (!isVisible && previousVisibility !== isVisible) { // this.resetControlWithId(this.form, targetId); // } // // for (let i = 0; i < visibilityRule.sourceVisibilityRules.length; i++) { // // if (value != null && (this.parseValue(value) !== this.parseValue(visibilityRule.sourceVisibilityRules[i].sourceControlValue))) { // // this._emitChangesIfNeeded(visibilityRule.targetControlId, false); // // this.elementVisibilityMap.set(visibilityRule.targetControlId, false); // // this.resetControlWithId(this.form, visibilityRule.targetControlId); // // //this.updateValueAndVisibility(visibilityRule.targetControlId, null); // // // this.clearValues(targetPathKey); // // return; // // } // // } // // this._emitChangesIfNeeded(visibilityRule.targetControlId, true); // // this.elementVisibilityMap.set(visibilityRule.targetControlId, true); // // this.updateValueAndVisibility(visibilityRule.targetControlId, null); // } // private _computeVisibility(targetId: string): boolean { // //console.log('_computeVisibility: ' + targetId); // const visibilityMap = this.elementComputationalMap.get(targetId); // const values = visibilityMap.values(); // let currentVal = values.next(); // let visibilityValues: boolean[] = []; // while (!currentVal.done) { // visibilityValues.push(currentVal.value); // currentVal = values.next(); // } // if (visibilityValues.length) { // return visibilityValues.reduce((r, c) => { // if (this.VISIBILITY_RULE_LOGIC === 'OR') { // return r || c; // } else { // return r && c; // } // }, visibilityValues[0]); // } // return this.DEFAULTVISIBILITY; // } // private resetVisibilityRules() { // //console.log('resetVisibilityRules: '); // this.isVisibleMap = {}; // this.elementComputationalMap.clear(); // this.elementComputationalMap = new Map>(); // this._populateComputationMap(); /// !IMPORTANT FOR THE AND LOGIC // this._changeMade$.next(); // } // private _populateComputationMap(): void { // //console.log('_populateComputationMap: '); // // this.visibilityRuleContext.rules.forEach(rule => { // // const targetId = rule.targetControlId; // // const visibilityMap = this.elementComputationalMap.get(targetId) ? this.elementComputationalMap.get(targetId) : new Map(); // // rule.sourceVisibilityRules.forEach(vr => { // // visibilityMap.set(vr.sourceControlId, this.DEFAULTVISIBILITY); // // }); // // this.elementComputationalMap.set(targetId, visibilityMap); // // }); // } // 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: UntypedFormGroup): boolean { // // console.log('scanIfChildsOfCompositeFieldHasVisibleItems: ' + compositeFieldParent); // //TODO: implement this // return true; // // 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; // } // } // private resetControlWithId(formControl: AbstractControl, id: string) { // //'resetControlWithId: ' + id); // //TODO: implement this // // if (formControl instanceof UntypedFormGroup) { // // if ((formControl as UntypedFormGroup).contains('id') && (formControl as UntypedFormGroup).contains('value') && (formControl as UntypedFormGroup).get('id').value === id) { // // this.resetFieldFormGroup(formControl); // // } if ((formControl as UntypedFormGroup).contains('id') && (formControl as UntypedFormGroup).contains('fields') && (formControl as UntypedFormGroup).get('id').value === id) { // // this.resetCompositeFieldFormGroup(formControl); // // } else { // // Object.keys(formControl.controls).forEach(item => { // // const control = formControl.get(item); // // this.resetControlWithId(control, id); // // }); // // } // // } else if (formControl instanceof UntypedFormArray) { // // formControl.controls.forEach(item => { // // this.resetControlWithId(item, id); // // }); // // } // } // private resetFieldFormGroup(formGroup: UntypedFormGroup) { // //console.log('resetFieldFormGroup: ' + formGroup); // //TODO: implement this // // const renderStyle = formGroup.getRawValue().viewStyle.renderStyle; // // if (renderStyle === DatasetProfileFieldViewStyle.Validation || renderStyle === DatasetProfileFieldViewStyle.DatasetIdentifier) { // // formGroup.get('value').setValue({ identifier: '', type: '' }); // // } else { // // formGroup.get('value').setValue(formGroup.get('defaultValue').value ? this.parseValue(formGroup.get('defaultValue').value.value) : undefined); // // } // } // private resetCompositeFieldFormGroup(formGroup: UntypedFormGroup) { // //console.log('resetCompositeFieldFormGroup: ' + formGroup); // //TODO: implement this // // (formGroup.get('fields') as UntypedFormArray).controls.forEach((element: UntypedFormGroup) => { // // this.resetFieldFormGroup(element); // // }); // // (formGroup.get('multiplicityItems') as UntypedFormArray).controls.splice(0); // } // private _emitChangesIfNeeded(id: string, valueToBeSet: boolean) { // if (this.isVisibleMap[id]) { // if (this.isVisibleMap[id] != valueToBeSet) { // this._changeMade$.next(); // } // } else { // this._changeMade$.next(); // } // } // public get visibilityChange() { // return this._changeMade$.asObservable(); // } // public getVisibilityDependency(targetId: string): VisibilityRuleSource[] | null { // //console.log('getVisibilityDependency: ' + targetId); // return this.visibilityRuleContext.rules.reduce((hasDependency, rule) => { // if (hasDependency) return hasDependency; // if (rule.targetControlId === targetId) { // return rule.sourceVisibilityRules; // } // return null; // }, null) as VisibilityRuleSource[]; // } // public getVisibilityTargets(sourceId: string): string[] { // console.log('getVisibilityTargets: ' + sourceId); // return this.visibilityRuleContext.rules.filter(x => { // const result = x.sourceVisibilityRules.filter(y => y.sourceControlId === sourceId); // return result.length; // }).map(x => x.targetControlId); // } // // public appendVisibilityRule(rule: VisibilityRule): void{ // // const existingTargetRule = this.visibilityRuleContext.rules.find( r => r.targetControlId === rule.targetControlId); // // if(existingTargetRule){ // // rule.sourceVisibilityRules.forEach(svr =>{ // // existingTargetRule.sourceVisibilityRules.push(svr); // // }); // // }else{ // // this.visibilityRuleContext.rules.push(rule); // // } // // } // //removes rule that has the specific id either as a source either as a target // public removeAllIdReferences(id: string): void { // //console.log('removeAllIdReferences: ' + id); // // * Remove from visibility rues and visibility rules context // //remove as a target // const temp = this.visibilityRuleContext.rules.map((x, i) => (x.targetControlId === id) ? i : null); // const indexes = temp.filter(x => x !== null); // indexes.reverse().forEach(index => this.visibilityRuleContext.rules.splice(index, 1)); // this.isVisibleMap[id] = undefined; // //remove as a source // const tbd = this.visibilityRuleContext.rules.reduce((to_be_deleted, rule, ruleIdx) => { // const idxs = rule.sourceVisibilityRules.map((x, i) => (x.sourceControlId === id) ? i : null).filter(x => x !== null); // idxs.reverse().forEach(index => rule.sourceVisibilityRules.splice(index, 1)); // if (!rule.sourceVisibilityRules.length) { // to_be_deleted.push(ruleIdx); // } // return to_be_deleted // }, []); // //clean up empty // tbd.reverse().forEach(index => { // this.visibilityRuleContext.rules.splice(index, 1); // }); // // * Remove from computational map // // as a target // if (this.elementComputationalMap.get(id)) { // this.elementComputationalMap.delete(id); // } // // as a source // const keyIterator = this.elementComputationalMap.keys(); // let currentKey = keyIterator.next(); // while (!currentKey.done) { // const currentVals = this.elementComputationalMap.get(currentKey.value); // currentVals.delete(id); // currentKey = keyIterator.next(); // } // } // public addNewRule(rule: Rule, currentVisibility = this.DEFAULTVISIBILITY): void { // //console.log('addNewRule: ' + rule + ' currentVisibility: ' + currentVisibility); // const targetId = rule.targetField; // const sourceId = rule.sourceField; // this.visibilityRuleContext.addToVisibilityRulesContext(rule); // let visibilityMap = this.elementComputationalMap.get(targetId); // if (!visibilityMap) { // visibilityMap = new Map(); // this.elementComputationalMap.set(targetId, visibilityMap); // } // visibilityMap.set(sourceId, currentVisibility); // const isVisible = this._computeVisibility(targetId); // this._emitChangesIfNeeded(targetId, isVisible); // this.isVisibleMap[targetId] = isVisible; // this.elementVisibilityMapSubject.next(this.isVisibleMap); // } // /** // * Check what sourceId hides or shows the target field // * return true if no rule found // */ // public checkTargetVisibilityProvidedBySource(sourceId: string, targetId: string): boolean { // //console.log('checkTargetVisibilityProvidedBySource: ' + sourceId + ' targetId: ' + targetId); // const computationalMap = this.elementComputationalMap.get(targetId); // if (computationalMap) { // return !!computationalMap.get(sourceId); // } // return true; // } // public getVisibilityRulesFromDescriptionTempalte(descriptionTemplate: DescriptionTemplate): Rule[] { // //console.log('getVisibilityRulesFromDescriptionTempalte: ' + descriptionTemplate); // const result: Rule[] = this.getVisibilityRulesFromDescriptionTempalteSections(descriptionTemplate?.definition?.pages); // return result; // } // public getVisibilityRulesFromDescriptionTempalteSections(pages: DescriptionTemplatePage[]): Rule[] { // //console.log('getVisibilityRulesFromDescriptionTempalteSections: ' + sections); // const result: Rule[] = []; // pages.forEach(page => { // page?.sections?.forEach(section => { // if (section.sections != null) { result.push(...this.getVisibilityRulesFromDescriptionTempalteSections(section.sections)); }; // section?.fieldSets?.forEach(fieldSet => { // fieldSet?.fields?.forEach(field => { // field.visibilityRules?.forEach(visibilityRule => { // result.push({ // sourceField: field.id.toString(), // targetField: visibilityRule.target, // dateValue: visibilityRule.dateValue, // textValue: visibilityRule.textValue, // textListValue: visibilityRule.textListValue // }) // }); // }); // }); // }); // }); // return result; // } // } // class MapWithDefault extends Map { // get(key) { // //console.log('MapWithDefault'); // if (!this.has(key)) { // this.set(key, true); // } // return super.get(key); // } // }