| /******************************************************************************** |
| * 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; |
| } |
| } |