| /******************************************************************************** |
| * 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 { MarkAsTouchedAction } from 'ngrx-forms'; |
| import { Action, ActionReducer, INIT, UPDATE } from '@ngrx/store'; |
| import * as gridFailureActions from '@grid-failure-information-app/shared/store/actions/grid-failures.action'; |
| import { |
| createFormGroupState, |
| createFormStateReducerWithUpdate, |
| updateGroup, |
| FormGroupState, |
| FormState, |
| SetValueAction, |
| validate, |
| setValue, |
| disable, |
| enable, |
| setUserDefinedProperty, |
| } from 'ngrx-forms'; |
| import { GridFailure, FailureHousenumber } from '@grid-failure-information-app/shared/models'; |
| import { required } from 'ngrx-forms/validation'; |
| |
| export const FORM_ID = 'gridFailureDetailsForm'; |
| export const DEPENDENT_FIELD_KEY = 'controlId'; |
| export const INITIAL_STATE: FormGroupState<GridFailure> = createFormGroupState<GridFailure>(FORM_ID, new GridFailure()); |
| /** |
| * Helper method checks if one of dependet fields (field nameIds passed as controlNames:string[]) is set to null. |
| * If so, it sets the current property value to null otherwise it reutrns the current property state |
| * |
| * @author Martin Gardyan <martin.gardyan@pta.de> |
| * @export |
| * @param {*} propState |
| * @param {*} formState |
| * @param {string[]} controlIds |
| * @returns {any} |
| */ |
| export function setDependentPropertyValueNull(propState: any, formState: any, controlIds: string[]): any { |
| const controlChanged: boolean = controlIds.some((controlId: string) => { |
| return formState.userDefinedProperties[DEPENDENT_FIELD_KEY] === controlId; |
| }); |
| |
| if (controlChanged) { |
| return setValue(propState, null); |
| } |
| |
| return propState; |
| } |
| /** |
| * Current ngrx-form version doesn't support validation with endable/disable |
| * |
| * @param state |
| * @param action |
| * @param controlId |
| */ |
| export function setControlEditState(propState: any, formState: FormState<any>, controlIds: string[]): any { |
| const dependentControlChanged: boolean = controlIds.some((controlId: string) => { |
| const controlName: string = controlId.substring(controlId.indexOf('.') + 1, controlId.length); |
| return !formState['controls'][controlName] || !formState['controls'][controlName]['value']; |
| }); |
| |
| if (formState.isDisabled) { |
| return propState; |
| } |
| if (dependentControlChanged) { |
| return disable(propState); |
| } |
| |
| return enable(propState); |
| } |
| |
| export function getDependentSingleValue(state: FormGroupState<GridFailure> = INITIAL_STATE, action: Action, controlId: string): FormGroupState<GridFailure> { |
| const data: Array<string> = <Array<string>>action['payload']; |
| |
| const controlName: string = controlId.substring(controlId.indexOf('.') + 1, controlId.length); |
| const isSingleValue: boolean = !!data && data.length <= 1 && data[0] !== state.controls[controlName].value; |
| let currentAction: Action = isSingleValue ? new SetValueAction<any>(controlId, data[0] || null) : new MarkAsTouchedAction(controlId); |
| |
| let formState = setUserDefinedProperty(state, DEPENDENT_FIELD_KEY, isSingleValue ? controlId : null); |
| return validateForm(formState, currentAction); |
| } |
| |
| export const validateForm: ActionReducer<FormState<GridFailure>> = createFormStateReducerWithUpdate<GridFailure>( |
| updateGroup<GridFailure>( |
| { |
| city: (propState, formState): any => { |
| return setDependentPropertyValueNull(propState, formState, [INITIAL_STATE.controls.postcode.id]); |
| }, |
| district: (propState, formState): any => { |
| return setDependentPropertyValueNull(propState, formState, [INITIAL_STATE.controls.city.id, INITIAL_STATE.controls.postcode.id]); |
| }, |
| street: (propState, formState): any => { |
| return setDependentPropertyValueNull(propState, formState, [ |
| INITIAL_STATE.controls.district.id, |
| INITIAL_STATE.controls.city.id, |
| INITIAL_STATE.controls.postcode.id, |
| ]); |
| }, |
| housenumber: (propState, formState): any => { |
| return setDependentPropertyValueNull(propState, formState, [ |
| INITIAL_STATE.controls.street.id, |
| INITIAL_STATE.controls.district.id, |
| INITIAL_STATE.controls.city.id, |
| INITIAL_STATE.controls.postcode.id, |
| ]); |
| }, |
| }, |
| { |
| city: (propState, formState): any => { |
| return setControlEditState(propState, formState, [INITIAL_STATE.controls.postcode.id]); |
| }, |
| district: (propState, formState): any => { |
| return setControlEditState(propState, formState, [INITIAL_STATE.controls.city.id, INITIAL_STATE.controls.postcode.id]); |
| }, |
| street: (propState, formState): any => { |
| return setControlEditState(propState, formState, [ |
| INITIAL_STATE.controls.district.id, |
| INITIAL_STATE.controls.city.id, |
| INITIAL_STATE.controls.postcode.id, |
| ]); |
| }, |
| housenumber: (propState, formState): any => { |
| return setControlEditState(propState, formState, [ |
| INITIAL_STATE.controls.street.id, |
| INITIAL_STATE.controls.district.id, |
| INITIAL_STATE.controls.city.id, |
| INITIAL_STATE.controls.postcode.id, |
| ]); |
| }, |
| }, |
| { |
| branchId: validate(required), |
| voltageLevel: validate(required), |
| failureBegin: validate(required), |
| expectedReasonId: validate(required), |
| postcode: validate(required), |
| city: validate(required), |
| street: validate(required), |
| district: validate(required), |
| housenumber: validate(required), |
| radiusId: validate(required), |
| } |
| ) |
| ); |
| |
| export function reducer(state: FormGroupState<GridFailure> = INITIAL_STATE, action: Action): FormGroupState<GridFailure> { |
| if (!action || action.type === INIT || action.type === UPDATE) { |
| const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, new GridFailure()); |
| return validateForm(INITIAL_STATE, setValueAction); |
| } |
| switch (action.type) { |
| case gridFailureActions.loadGridFailureDetailSuccess.type: { |
| const gridFailure: GridFailure = <GridFailure>action['payload']; |
| const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, gridFailure); |
| const formState = validateForm(state, setValueAction); |
| |
| return setUserDefinedProperty(formState, DEPENDENT_FIELD_KEY, FORM_ID); |
| } |
| case gridFailureActions.loadGridFailureVersionSuccess.type: { |
| const gridFailure: GridFailure = <GridFailure>action['payload']; |
| const setValueAction: SetValueAction<any> = new SetValueAction<any>(FORM_ID, gridFailure); |
| |
| return validateForm(state, setValueAction); |
| } |
| case gridFailureActions.loadAddressCommunitiesSuccess.type: { |
| return getDependentSingleValue(state, action, INITIAL_STATE.controls.city.id); |
| } |
| case gridFailureActions.loadAddressDistrictsSuccess.type: { |
| return getDependentSingleValue(state, action, INITIAL_STATE.controls.district.id); |
| } |
| case gridFailureActions.loadAddressStreetsSuccess.type: { |
| return getDependentSingleValue(state, action, INITIAL_STATE.controls.street.id); |
| } |
| case gridFailureActions.loadAddressHouseNumbersSuccess.type: { |
| const ac = { payload: !!action['payload'] && action['payload'].map((houseNumber: FailureHousenumber) => houseNumber.housenumber) } as any; |
| return getDependentSingleValue(state, ac, INITIAL_STATE.controls.housenumber.id); |
| } |
| default: |
| if (!!action && action.type === SetValueAction.TYPE) { |
| var formState = setUserDefinedProperty(state, DEPENDENT_FIELD_KEY, action[DEPENDENT_FIELD_KEY]); |
| return validateForm(formState, action); |
| } else { |
| return validateForm(state, action); |
| } |
| } |
| } |
| |
| export const getFormState = (state: FormGroupState<GridFailure>) => state; |