blob: cd1c83d8fefb42b895dbdf8687a7b502c46d3408 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
import * as communicationTypesActions from '@shared/store/actions/admin/communication-types.action';
import * as internalAddressDetailsFormReducer from '@shared/store/reducers/persons/internal-person/addresses-details-form.reducer';
import * as internalCommunicationsDataDetailsFormReducer from '@shared/store/reducers/persons/internal-person/communications-data-details-form.reducer';
import * as internalPersonActions from '@shared/store/actions/persons/internal-person.action';
import * as keycloakUserActions from '@shared/store/actions/users/keycloak-user.action';
import * as ldapUserActions from '@shared/store/actions/users/ldap-user.action';
import * as internalPersonDetailsFormReducer from '@shared/store/reducers/persons/internal-person/internal-person-details-form.reducer';
import * as store from '@shared/store';
import { ActionsSubject, Store } from '@ngrx/store';
import { Address, CommunicationsData, CommunicationType, InternalPerson, KeycloakUser, LdapUser } from '@shared/models';
import { BaseSandbox } from '@shared/sandbox/base.sandbox';
import { FormGroupState, MarkAsTouchedAction, ResetAction, SetValueAction } from 'ngrx-forms';
import { Injectable } from '@angular/core';
import { map, take, takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { Observable } from 'rxjs';
import { ofType } from '@ngrx/effects';
import { Router } from '@angular/router';
import { SafetyQueryDialogComponent } from '@shared/components/dialogs/safety-query-dialog/safety-query-dialog.component';
import { UtilService } from '@shared/utility';
@Injectable()
export class InternalPersonDetailsSandBox extends BaseSandbox {
public internalPersonDetailsFormState$: Observable<FormGroupState<InternalPerson>> = this.appState$.select(store.getInternalPersonDetails);
public internalPersonDetailsCurrentFormState: FormGroupState<InternalPerson>;
public communicationsDataDetailsFormState$: Observable<FormGroupState<CommunicationsData>> = this.appState$.select(
store.getInternalPersonCommunicationsDataDetails
);
public communicationsDataDetailsCurrentFormState: FormGroupState<CommunicationsData>;
public communicationsDataList$: Observable<Array<CommunicationsData>> = this.appState$.select(store.getInternalCommunicationsDataData);
public communicationsDataListLoading$: Observable<boolean> = this.appState$.select(store.getInternalCommunicationsDataLoading);
public addressDetailsFormState$: Observable<FormGroupState<Address>> = this.appState$.select(store.getInternalPersonAddressesDetails);
public addressDetailsCurrentFormState: FormGroupState<Address>;
public addressList$: Observable<Array<Address>> = this.appState$.select(store.getInternalAddressesData);
public addressListLoading$: Observable<boolean> = this.appState$.select(store.getInternalAddressesLoading);
public isCommunicationsDataDetailViewVisible: boolean = false;
public isAddressDataDetailViewVisible: boolean = false;
public existMainAddress = false;
public isCurrentAddressMainAddress = false;
public internalPersonContactId: string;
private _currentInternalPerson: InternalPerson = null;
private _communicationTypes: Array<CommunicationType> = new Array<CommunicationType>();
private _keycloakUsers: Array<KeycloakUser> = new Array<KeycloakUser>();
private _ldapUsers: Array<LdapUser> = new Array<LdapUser>();
constructor(
public appState$: Store<store.State>,
public utilService: UtilService,
protected actionsSubject: ActionsSubject,
protected router: Router,
protected modalService: NgbModal
) {
super(appState$);
this.addressList$.pipe(takeUntil(this._endSubscriptions$)).subscribe(addresses => {
this._checkIfMainAddressExist(addresses);
});
this.actionsSubject
.pipe(
ofType(internalPersonActions.loadInternalPersonDetailAddressDetailsSuccess),
map((action: { payload: Address }) => action.payload),
takeUntil(this._endSubscriptions$)
)
.subscribe((address: Address) => {
this._checkIfCurrentAddressIsMainAddress(address);
});
// this.actionsSubject
// .pipe(
// ofType(keycloakUserActions.loadKeycloakUsersSuccess),
// map((action: keycloakUserActions.ILoadKeycloakUsersSuccess) => action.payload),
// takeUntil(this._endSubscriptions$)
// )
// .subscribe((users: Array<KeycloakUser>) => {
// this._keycloakUsers = users;
// });
const user1: KeycloakUser = { username: 'admin', firstName: 'admin', lastName: 'admin' };
for (let index = 0; index < 40; index++) {
this._keycloakUsers.push(user1);
}
this.actionsSubject
.pipe(
ofType(ldapUserActions.loadLdapUsersSuccess),
map((action: ldapUserActions.ILoadLdapUsersSuccess) => action.payload),
takeUntil(this._endSubscriptions$)
)
.subscribe((users: Array<LdapUser>) => {
this._ldapUsers = users;
});
}
public loadInternalPerson(id: string): void {
this.internalPersonContactId = id;
this.appState$.dispatch(internalPersonActions.loadInternalPersonDetail({ payload: id }));
this.actionsSubject
.pipe(
ofType(internalPersonActions.loadInternalPersonDetailSuccess),
map((action: internalPersonActions.ILoadInternalPersonDetailsSuccess) => action.payload),
take(1),
takeUntil(this._endSubscriptions$)
)
.subscribe((payload: InternalPerson) => {
this._currentInternalPerson = payload;
});
}
public loadInternalPersonAddresses(internalPersonId: string): void {
this.appState$.dispatch(internalPersonActions.loadInternalPersonDetailAddresses({ payload: internalPersonId }));
}
public loadInternalPersonDetailsAddressDetails(addressId: string): void {
this.appState$.dispatch(
internalPersonActions.loadInternalPersonDetailAddressDetails({ payload_contactId: this.internalPersonContactId, payload_addressId: addressId })
);
}
public persistInternalPerson(): void {
if (this.internalPersonDetailsCurrentFormState.isValid) {
const currentValue = this.internalPersonDetailsCurrentFormState.value;
if (currentValue.userRef && currentValue.uid) {
this.utilService.displayNotification('InternalError.UserRefOrUid', 'alert');
return;
}
let isUidUnique: boolean = null;
let isUserrefUnique: boolean = null;
const isNew: boolean = currentValue.contactId === null;
if (currentValue.uid) {
this.appState$.dispatch(internalPersonActions.loadInternalPersonsForUid({ payload: { uid: currentValue.uid } }));
}
if (currentValue.userRef) {
this.appState$.dispatch(internalPersonActions.loadInternalPersonsForUserref({ payload: { userRef: currentValue.userRef } }));
}
if (!currentValue.uid && !currentValue.userRef) {
this.appState$.dispatch(internalPersonActions.persistInternalPersonDetail({ payload: currentValue }));
}
this.actionsSubject
.pipe(
ofType(internalPersonActions.loadInternalPersonsForUidSuccess),
map((action: internalPersonActions.ILoadInternalPersonsForUidSuccess) => action.payload),
take(1),
takeUntil(this._endSubscriptions$)
)
.subscribe((payload: Array<InternalPerson>) => {
isUidUnique = payload.length == 0 || (!isNew && payload.length == 1 && payload[0].uid === this._currentInternalPerson.uid);
if (!isUidUnique) {
this.utilService.displayNotification('InternalError.UniqueUid', 'alert');
} else {
if ((isUidUnique && currentValue.userRef && isUserrefUnique) || (isUidUnique && !currentValue.userRef)) {
this.appState$.dispatch(internalPersonActions.persistInternalPersonDetail({ payload: currentValue }));
}
}
});
this.actionsSubject
.pipe(
ofType(internalPersonActions.loadInternalPersonsForUserrefSuccess),
map((action: internalPersonActions.ILoadInternalPersonsForUserrefSuccess) => action.payload),
take(1),
takeUntil(this._endSubscriptions$)
)
.subscribe((payload: Array<InternalPerson>) => {
isUserrefUnique = payload.length == 0 || (!isNew && payload.length == 1 && payload[0].userRef === this._currentInternalPerson.userRef);
if (!isUserrefUnique) {
this.utilService.displayNotification('InternalError.UniqueUserref', 'alert');
} else {
if ((isUserrefUnique && currentValue.uid && isUidUnique) || (isUserrefUnique && !currentValue.uid)) {
this.appState$.dispatch(internalPersonActions.persistInternalPersonDetail({ payload: currentValue }));
}
}
});
this.actionsSubject.pipe(ofType(internalPersonActions.persistInternalPersonDetailSuccess), take(1), takeUntil(this._endSubscriptions$)).subscribe(() => {
this.newInternalPerson();
this.router.navigateByUrl(`/overview`);
});
} else {
this.utilService.displayNotification('MandatoryFieldsNotFilled', 'alert');
}
}
public persistAddress(): void {
if (this.addressDetailsCurrentFormState.isValid) {
const newAddress = new Address(this.addressDetailsCurrentFormState.value);
newAddress.contactId = newAddress.contactId !== null ? newAddress.contactId : this.internalPersonContactId;
this.appState$.dispatch(internalPersonActions.persistAddressDetail({ payload: newAddress }));
this.actionsSubject.pipe(ofType(internalPersonActions.persistAddressDetailSuccess), take(1), takeUntil(this._endSubscriptions$)).subscribe(() => {
this.closeAddressDataDetail();
});
} else {
this.utilService.displayNotification('MandatoryFieldsNotFilled', 'alert');
}
}
public deleteAddress(address: Address): void {
const modalRef = this.modalService.open(SafetyQueryDialogComponent);
modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
modalRef.result.then(
() => {
this.appState$.dispatch(internalPersonActions.deleteAddress({ payload: address }));
if (address.isMainAddress) {
this.existMainAddress = false;
}
this.closeAddressDataDetail();
},
() => {}
);
}
public closeAddressDataDetail(): void {
this.clearAddressData();
this.isAddressDataDetailViewVisible = false;
}
public newInternalPerson(): void {
this.clearInternalPerson();
this.appState$.dispatch(new MarkAsTouchedAction(internalPersonDetailsFormReducer.FORM_ID));
}
public clearInternalPerson(): void {
this.appState$.dispatch(new SetValueAction(internalPersonDetailsFormReducer.FORM_ID, internalPersonDetailsFormReducer.INITIAL_STATE.value));
this.appState$.dispatch(new ResetAction(internalPersonDetailsFormReducer.FORM_ID));
}
public newAddressData(): void {
this.clearAddressData();
this.appState$.dispatch(new MarkAsTouchedAction(internalAddressDetailsFormReducer.FORM_ID));
}
public clearAddressData(): void {
this.isCurrentAddressMainAddress = false;
this.appState$.dispatch(new SetValueAction(internalAddressDetailsFormReducer.FORM_ID, internalAddressDetailsFormReducer.INITIAL_STATE.value));
this.appState$.dispatch(new ResetAction(internalAddressDetailsFormReducer.FORM_ID));
}
public registerInternalPersonEvents(): void {
// subscribes to formState
this.internalPersonDetailsFormState$
.pipe(takeUntil(this._endSubscriptions$))
.subscribe((formState: FormGroupState<InternalPerson>) => (this.internalPersonDetailsCurrentFormState = formState));
}
public loadCommunicationsData(internalPersonId: string): void {
this.actionsSubject
.pipe(
ofType(communicationTypesActions.loadCommunicationTypesSuccess),
map((action: communicationTypesActions.ILoadCommunicationTypesSuccess) => action.payload),
take(1),
takeUntil(this._endSubscriptions$)
)
.subscribe((payload: Array<CommunicationType>) => {
this._communicationTypes = payload;
this.appState$.dispatch(internalPersonActions.loadInternalPersonDetailCommunicationsData({ payload: internalPersonId }));
});
this.actionsSubject
.pipe(
ofType(internalPersonActions.loadInternalPersonDetailCommunicationsDataSuccess),
map((action: internalPersonActions.ILoadInternalPersonCommunicationsDataSuccess) => action.payload),
take(1),
takeUntil(this._endSubscriptions$)
)
.subscribe((communicationsData: Array<CommunicationsData>) => {
if (this._communicationTypes) {
for (let i = 0; i < this._communicationTypes.length; i++) {
const ct = this._communicationTypes[i];
const existingCommunicationsData: CommunicationsData = communicationsData.find(cd => cd.communicationTypeId == ct.id);
ct.isDisabled = existingCommunicationsData ? true : false;
}
}
});
}
public loadCommunicationsDataDetails(communicationsDataId: string): void {
this.appState$.dispatch(
internalPersonActions.loadInternalPersonDetailCommunicationsDataDetails({
payload_contactId: this.internalPersonContactId,
payload_communicationsId: communicationsDataId,
})
);
}
public persistCommunicationsData(): void {
if (this.communicationsDataDetailsCurrentFormState.isValid) {
const newCommunicationsData = new CommunicationsData(this.communicationsDataDetailsCurrentFormState.value);
newCommunicationsData.contactId = newCommunicationsData.contactId !== null ? newCommunicationsData.contactId : this.internalPersonContactId;
this.appState$.dispatch(internalPersonActions.persistCommunicationsDataDetail({ payload: newCommunicationsData }));
this.actionsSubject
.pipe(ofType(internalPersonActions.persistCommunicationsDataDetailSuccess), take(1), takeUntil(this._endSubscriptions$))
.subscribe(() => {
this.closeCommunicationsDataDetail();
});
} else {
this.utilService.displayNotification('MandatoryFieldsNotFilled', 'alert');
}
}
public deleteCommunicationsData(communicationsData: CommunicationsData): void {
const modalRef = this.modalService.open(SafetyQueryDialogComponent);
modalRef.componentInstance.title = 'ConfirmDialog.Action.delete';
modalRef.componentInstance.body = 'ConfirmDialog.Deletion';
modalRef.result.then(
() => {
this.appState$.dispatch(internalPersonActions.deleteCommunicationsData({ payload: communicationsData }));
this.closeCommunicationsDataDetail();
},
() => {}
);
}
public closeCommunicationsDataDetail(): void {
this.loadCommunicationsData(this.internalPersonContactId);
this.clearCommunicationsData();
this.isCommunicationsDataDetailViewVisible = false;
}
public newCommunicationsData(): void {
this.clearCommunicationsData();
this.appState$.dispatch(new MarkAsTouchedAction(internalCommunicationsDataDetailsFormReducer.FORM_ID));
}
public clearCommunicationsData(): void {
this.appState$.dispatch(
new SetValueAction(internalCommunicationsDataDetailsFormReducer.FORM_ID, internalCommunicationsDataDetailsFormReducer.INITIAL_STATE.value)
);
this.appState$.dispatch(new ResetAction(internalCommunicationsDataDetailsFormReducer.FORM_ID));
}
public registerCommunicationsDataEvents(): void {
// subscribes to formState
this.communicationsDataDetailsFormState$
.pipe(takeUntil(this._endSubscriptions$))
.subscribe((formState: FormGroupState<CommunicationsData>) => (this.communicationsDataDetailsCurrentFormState = formState));
}
public registerAddressEvents(): void {
// subscribes to formState
this.addressDetailsFormState$
.pipe(takeUntil(this._endSubscriptions$))
.subscribe((formState: FormGroupState<Address>) => (this.addressDetailsCurrentFormState = formState));
}
public loadKeycloakUsers(): void {
this.appState$.dispatch(keycloakUserActions.loadKeycloakUsers());
}
public searchForKeycloakUser = (text$: Observable<string>) =>
text$.pipe(
debounceTime(200),
distinctUntilChanged(),
map(term =>
term.length < 2
? []
: this._keycloakUsers
.map((user: KeycloakUser) => `${user.firstName} ${user.lastName} (${user.username})`)
.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
)
);
public setUserRefValue(event: any): void {
// set the value only if exists - take only the username from the rounded bruckets
this.appState$.dispatch(
new SetValueAction(this.internalPersonDetailsCurrentFormState.controls.userRef.id, event == null ? null : event.item.match(/\(([^)]+)\)/)[1])
);
}
public loadLdapUsers(): void {
this.appState$.dispatch(ldapUserActions.loadLdapUsers());
}
public searchForLdapUser = (text$: Observable<string>) =>
text$.pipe(
debounceTime(200),
distinctUntilChanged(),
map(term =>
term.length < 2
? []
: this._ldapUsers.map((user: LdapUser) => `${user.fullName} (${user.uid})`).filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
)
);
public setLdapUidValue(event: any): void {
// set the value only if exists - take only the username from the rounded bruckets
this.appState$.dispatch(
new SetValueAction(this.internalPersonDetailsCurrentFormState.controls.uid.id, event == null ? null : event.item.match(/\(([^)]+)\)/)[1])
);
}
private _checkIfMainAddressExist(addresses: Array<Address>) {
for (let i = 0; i < addresses.length; i++) {
const address = addresses[i];
if (address.isMainAddress) {
this.existMainAddress = true;
break;
}
this.existMainAddress = false;
}
}
private _checkIfCurrentAddressIsMainAddress(address: Address) {
this.isCurrentAddressMainAddress = address.isMainAddress ? true : false;
}
}