blob: 9c3855cbb1cea9777efe067e89225ec8e5d7c1b1 [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 { 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),
statusInternId: validate(required),
statusExternId: 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;