457 lines
17 KiB
TypeScript
457 lines
17 KiB
TypeScript
// 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<String, Map<String, boolean>>(); /// keep saved the values of each form control validity value
|
|
// private _changeMade$ = new Subject<void>();
|
|
|
|
|
|
// // 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<Rule>, 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<String, boolean>();
|
|
|
|
|
|
// 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<String, Map<String, boolean>>();
|
|
// 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<String, boolean>();
|
|
// // 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;
|
|
// // (<UntypedFormArray>(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<String, boolean>();
|
|
// 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<string, boolean> {
|
|
// get(key) {
|
|
// //console.log('MapWithDefault');
|
|
// if (!this.has(key)) {
|
|
// this.set(key, true);
|
|
// }
|
|
// return super.get(key);
|
|
// }
|
|
// }
|