Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue#2126 institution hierarchy fix #2128

Merged
merged 2 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
disableOptionCentering
panelClass="dropdown-panel"
placeholder="{{ 'FORMS.PLACEHOLDERS.SELECT_SUBORDINATION' | translate }}"
class="step-input"
>
class="step-input">
<mat-option *ngFor="let institution of institutions$ | async" [value]="institution.id" class="dropdown-option">
{{ institution.title }}
</mat-option>
</mat-select>
</mat-form-field>
<app-validation-hint [validationFormControl]="instituitionIdFormControl">
</app-validation-hint>
<app-validation-hint [validationFormControl]="instituitionIdFormControl"> </app-validation-hint>

<ng-container *ngFor="let hierarchy of hierarchyArray">
<ng-container *ngIf="hierarchy.shouldDisplay">
Expand All @@ -25,15 +23,13 @@
disableOptionCentering
panelClass="dropdown-panel"
class="step-input"
(selectionChange)="onHierarchyLevelSelect($event.value, hierarchy)"
>
(selectionChange)="onHierarchyLevelSelect(hierarchy)">
<mat-option *ngFor="let option of hierarchy.options" [value]="option.id" class="dropdown-option">
{{ option.title }}
</mat-option>
</mat-select>
</mat-form-field>
<app-validation-hint [validationFormControl]="hierarchy.formControl">
</app-validation-hint>
<app-validation-hint [validationFormControl]="hierarchy.formControl"> </app-validation-hint>
</ng-container>
</ng-container>
</div>
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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<Institution[]>;
public institutions$: Observable<Institution[]>;
@Select(MetaDataState.instituitionsHierarchy)
instituitionsHierarchy$: Observable<InstituitionHierarchy[]>;
private instituitionsHierarchy$: Observable<InstituitionHierarchy[]>;
@Select(MetaDataState.editInstituitionsHierarchy)
editInstituitionsHierarchy$: Observable<InstituitionHierarchy[]>;
editInstituitionsHierarchy: InstituitionHierarchy[];
private editInstituitionsHierarchy$: Observable<InstituitionHierarchy[]>;
private editInstituitionsHierarchy: InstituitionHierarchy[];
@Select(MetaDataState.institutionFieldDesc)
institutionFieldDesc$: Observable<InstitutionFieldDescription[]>;
institutionFieldDesc: InstitutionFieldDescription[];
private institutionFieldDesc$: Observable<InstitutionFieldDescription[]>;
private institutionFieldDesc: InstitutionFieldDescription[];

destroy$: Subject<boolean> = new Subject<boolean>();
hierarchyArray: HierarchyElement[] = [];
private editMode: boolean;
private destroy$: Subject<boolean> = new Subject<boolean>();
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));
});
Expand All @@ -72,87 +100,84 @@ 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,
institutionId: this.institutionFieldDesc[descriptionIndex].institutionId,
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);
});
}
}