diff --git a/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.html b/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.html index 129df6f804..b906e6c242 100644 --- a/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.html +++ b/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.html @@ -6,15 +6,13 @@ disableOptionCentering panelClass="dropdown-panel" placeholder="{{ 'FORMS.PLACEHOLDERS.SELECT_SUBORDINATION' | translate }}" - class="step-input" - > + class="step-input"> {{ institution.title }} - - + @@ -25,15 +23,13 @@ disableOptionCentering panelClass="dropdown-panel" class="step-input" - (selectionChange)="onHierarchyLevelSelect($event.value, hierarchy)" - > + (selectionChange)="onHierarchyLevelSelect(hierarchy)"> {{ option.title }} - - + diff --git a/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.ts b/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.ts index 8642379566..406001ea3e 100644 --- a/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.ts +++ b/src/app/shared/components/institution-hierarchy/institution-hierarchy.component.ts @@ -1,11 +1,12 @@ -import { FormControl, Validators } from '@angular/forms'; +import { Observable, Subject } from 'rxjs'; +import { filter, switchMap, take, takeUntil, tap } from 'rxjs/operators'; + import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { FormControl, Validators } from '@angular/forms'; import { Select, Store } from '@ngxs/store'; -import { Observable, Subject } from 'rxjs'; -import { tap, filter, takeUntil } from 'rxjs/operators'; -import { Provider } from '../../models/provider.model'; + import { HierarchyElement, InstituitionHierarchy, Institution, InstitutionFieldDescription } from '../../models/institution.model'; -import { MetaDataState } from '../../store/meta-data.state'; +import { Provider } from '../../models/provider.model'; import { GetAllByInstitutionAndLevel, GetAllInstitutions, @@ -14,53 +15,80 @@ import { GetInstitutionHierarchyParentsById, ResetInstitutionHierarchy } from '../../store/meta-data.actions'; +import { MetaDataState } from '../../store/meta-data.state'; + @Component({ selector: 'app-institution-hierarchy', templateUrl: './institution-hierarchy.component.html', styleUrls: ['./institution-hierarchy.component.scss'] }) export class InstitutionHierarchyComponent implements OnInit, OnDestroy { - @Input() instituitionHierarchyIdFormControl: FormControl; - @Input() instituitionIdFormControl: FormControl; - @Input() provider: Provider; + @Input() private instituitionHierarchyIdFormControl: FormControl; + @Input() private provider: Provider; + @Input() public instituitionIdFormControl: FormControl; @Select(MetaDataState.institutions) - institutions$: Observable; + public institutions$: Observable; @Select(MetaDataState.instituitionsHierarchy) - instituitionsHierarchy$: Observable; + private instituitionsHierarchy$: Observable; @Select(MetaDataState.editInstituitionsHierarchy) - editInstituitionsHierarchy$: Observable; - editInstituitionsHierarchy: InstituitionHierarchy[]; + private editInstituitionsHierarchy$: Observable; + private editInstituitionsHierarchy: InstituitionHierarchy[]; @Select(MetaDataState.institutionFieldDesc) - institutionFieldDesc$: Observable; - institutionFieldDesc: InstitutionFieldDescription[]; + private institutionFieldDesc$: Observable; + private institutionFieldDesc: InstitutionFieldDescription[]; - destroy$: Subject = new Subject(); - hierarchyArray: HierarchyElement[] = []; - private editMode: boolean; + private destroy$: Subject = new Subject(); + private isEditMode: boolean; + + public hierarchyArray: HierarchyElement[] = []; constructor(private store: Store) {} - ngOnInit(): void { + public ngOnInit(): void { this.store.dispatch(new GetAllInstitutions(false)); - this.editMode = !!this.instituitionIdFormControl.value; + this.isEditMode = !!this.instituitionIdFormControl.value; this.setInitialInstitution(); - this.createInstitutioHierarchy(); - if (this.editMode) { + if (this.isEditMode) { this.setEditMode(); + } else { + this.setFieldsDescriptionSubscribe(); } } + public onHierarchyLevelSelect(hierarchy: HierarchyElement): void { + const needToSlice = this.hierarchyArray[this.hierarchyArray.length - 1].hierarchyLevel - hierarchy.hierarchyLevel != 0; + + this.store.dispatch(new GetInstitutionHierarchyChildrenById(hierarchy.formControl.value)); + + if (needToSlice) { + const nextEl = this.hierarchyArray.indexOf(hierarchy) + 1; + this.hierarchyArray = this.hierarchyArray.slice(0, nextEl); + this.setFinalHierarchyLevel(null); + } + } + + public ngOnDestroy(): void { + this.store.dispatch(new ResetInstitutionHierarchy()); + this.destroy$.next(true); + this.destroy$.unsubscribe(); + } + private setInitialInstitution(): void { - const institutionId = this.editMode ? this.instituitionIdFormControl.value : this.provider.institution?.id; + const institutionId = this.isEditMode ? this.instituitionIdFormControl.value : this.provider.institution?.id; + if (institutionId) { this.instituitionIdFormControl.setValue(institutionId, { emitEvent: false }); this.store.dispatch(new GetFieldDescriptionByInstitutionId(this.instituitionIdFormControl.value)); } + this.setHierarchySubscribes(); + } + + private setHierarchySubscribes(): void { this.instituitionIdFormControl.valueChanges.subscribe((institutionId: string) => { this.store.dispatch(new GetFieldDescriptionByInstitutionId(institutionId)); }); @@ -72,48 +100,32 @@ export class InstitutionHierarchyComponent implements OnInit, OnDestroy { ) .subscribe((instituitionsHierarchy: InstituitionHierarchy[]) => { if (instituitionsHierarchy.length) { - const nextLevel = instituitionsHierarchy[0].hierarchyLevel - 1; - this.createInstitutionFormControl(nextLevel); - this.hierarchyArray[nextLevel].options = instituitionsHierarchy; - this.hierarchyArray[nextLevel].shouldDisplay = true; - - if (this.editInstituitionsHierarchy && this.editInstituitionsHierarchy[nextLevel]) { - const nextEditInstitution = this.editInstituitionsHierarchy[nextLevel + 1]; - this.hierarchyArray[nextLevel].formControl.setValue(this.editInstituitionsHierarchy[nextLevel].id, { emitEvent: false }); - nextEditInstitution && this.store.dispatch(new GetInstitutionHierarchyChildrenById(nextEditInstitution.id)); + const newHierarchyElementIndex = this.hierarchyArray.length; + const newHierarchyElement = this.createHierachyElement(newHierarchyElementIndex); + + this.hierarchyArray.push(newHierarchyElement); + this.hierarchyArray[newHierarchyElementIndex].options = instituitionsHierarchy; + this.hierarchyArray[newHierarchyElementIndex].shouldDisplay = true; + + if (this.editInstituitionsHierarchy && this.editInstituitionsHierarchy[newHierarchyElementIndex]) { + const nextEditInstitution = this.editInstituitionsHierarchy[newHierarchyElementIndex]; + + this.store.dispatch(new GetInstitutionHierarchyChildrenById(nextEditInstitution.id)); + this.hierarchyArray[newHierarchyElementIndex].formControl.setValue( + this.editInstituitionsHierarchy[newHierarchyElementIndex].id, + { emitEvent: false } + ); } } else { - let finalInstitutionId = this.hierarchyArray[this.hierarchyArray.length - 1].formControl.value; + const finalInstitutionId = this.hierarchyArray[this.hierarchyArray.length - 1].formControl.value; this.setFinalHierarchyLevel(finalInstitutionId); this.editInstituitionsHierarchy = null; } }); } - private setFinalHierarchyLevel(optionId: string): void { - this.instituitionHierarchyIdFormControl.setValue(optionId, { emitEvent: false }); - this.store.dispatch(new ResetInstitutionHierarchy()); - } - - private createInstitutioHierarchy(): void { - this.institutionFieldDesc$ - .pipe( - takeUntil(this.destroy$), - filter((institutionFieldDesc: InstitutionFieldDescription[]) => !!institutionFieldDesc), - tap((institutionFieldDesc: InstitutionFieldDescription[]) => - institutionFieldDesc.sort((a, b) => a.hierarchyLevel - b.hierarchyLevel) - ) - ) - .subscribe((institutionFieldDesc: InstitutionFieldDescription[]) => { - this.hierarchyArray = []; - this.institutionFieldDesc = institutionFieldDesc; - this.store.dispatch(new GetAllByInstitutionAndLevel(this.instituitionIdFormControl.value, 1)); - this.setFinalHierarchyLevel(null); - }); - } - - private createInstitutionFormControl(descriptionIndex: number): void { - const hierarchyEl = { + private createHierachyElement(descriptionIndex: number): HierarchyElement { + return { formControl: new FormControl('', Validators.required), title: this.institutionFieldDesc[descriptionIndex].title, hierarchyLevel: this.institutionFieldDesc[descriptionIndex].hierarchyLevel, @@ -121,38 +133,51 @@ export class InstitutionHierarchyComponent implements OnInit, OnDestroy { shouldDisplay: false, options: [] }; - - this.hierarchyArray.push(hierarchyEl); } - onHierarchyLevelSelect(optionId: string, hierarchy: HierarchyElement): void { - this.store.dispatch(new GetInstitutionHierarchyChildrenById(optionId)); - let needToSlice = this.hierarchyArray[this.hierarchyArray.length - 1].hierarchyLevel - hierarchy.hierarchyLevel != 0; - if (needToSlice) { - const nextEl = this.hierarchyArray.indexOf(hierarchy) + 1; - this.hierarchyArray = this.hierarchyArray.slice(0, nextEl); - this.setFinalHierarchyLevel(null); - } + private setFinalHierarchyLevel(optionId: string): void { + this.instituitionHierarchyIdFormControl.setValue(optionId, { emitEvent: false }); + this.store.dispatch(new ResetInstitutionHierarchy()); } - setEditMode(): void { + private setEditMode(): void { this.store.dispatch(new GetInstitutionHierarchyParentsById(this.instituitionHierarchyIdFormControl.value)); + this.setEditModeSubscribes(); + } + + private setEditModeSubscribes(): void { this.editInstituitionsHierarchy$ .pipe( takeUntil(this.destroy$), filter((instituitionsHierarchy: InstituitionHierarchy[]) => !!instituitionsHierarchy), tap((instituitionsHierarchy: InstituitionHierarchy[]) => instituitionsHierarchy.sort((a, b) => a.hierarchyLevel - b.hierarchyLevel)) ) - .subscribe((instituitionsHierarchy: InstituitionHierarchy[]) => { - this.editInstituitionsHierarchy = instituitionsHierarchy; - this.store.dispatch(new GetInstitutionHierarchyChildrenById(instituitionsHierarchy[0].id)); - }); + .subscribe((instituitionsHierarchy: InstituitionHierarchy[]) => (this.editInstituitionsHierarchy = instituitionsHierarchy)); + + // Subscribes to institutionFieldDesc$ only after receiving 1 editInstitutionsHierarchy$ result + this.editInstituitionsHierarchy$ + .pipe( + filter((instituitionsHierarchy: InstituitionHierarchy[]) => !!instituitionsHierarchy), + take(1) + ) + .subscribe(() => this.setFieldsDescriptionSubscribe()); } - ngOnDestroy(): void { - this.store.dispatch(new ResetInstitutionHierarchy()); - this.destroy$.next(true); - this.destroy$.unsubscribe(); + private setFieldsDescriptionSubscribe(): void { + this.institutionFieldDesc$ + .pipe( + takeUntil(this.destroy$), + filter((institutionFieldDesc: InstitutionFieldDescription[]) => !!institutionFieldDesc), + tap((institutionFieldDesc: InstitutionFieldDescription[]) => + institutionFieldDesc.sort((a, b) => a.hierarchyLevel - b.hierarchyLevel) + ) + ) + .subscribe((institutionFieldDesc: InstitutionFieldDescription[]) => { + this.hierarchyArray = []; + this.institutionFieldDesc = institutionFieldDesc; + this.store.dispatch(new GetAllByInstitutionAndLevel(this.instituitionIdFormControl.value, 1)); + this.setFinalHierarchyLevel(null); + }); } }