Skip to content

Commit

Permalink
Merge pull request #135 from episerver/bugfix/AFORM-4129-fix-dependen…
Browse files Browse the repository at this point in the history
…cies-inconsitent

Revamp dependencies state manager to support multi dependent
  • Loading branch information
epi-qang2 authored Aug 26, 2024
2 parents 131161e + 0e6e26e commit 37db8ce
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 28 deletions.
7 changes: 6 additions & 1 deletion src/@episerver/forms-react/src/components/FormBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,14 @@ export const FormBody = (props: FormBodyProps) => {

let isLastStep = currentStepIndex === form.steps.length - 1;

//get inactives element
let inactives = (formContext?.elementDependencies ?? [])
.filter(dependency => !dependency.isSatisfied)
.map(dependency => dependency.elementKey);

//filter submissions by active elements and current step
let formSubmissions = (formContext?.formSubmissions ?? [])
.filter(fs => !isInArray(fs.elementKey, formContext?.dependencyInactiveElements ?? []) && stepHelper.isInCurrentStep(fs.elementKey, currentStepIndex));
.filter(fs => !isInArray(fs.elementKey, inactives) && stepHelper.isInCurrentStep(fs.elementKey, currentStepIndex));

//validate all submission data before submit
let formValidationResults = formSubmitter.doValidate(formSubmissions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export function FormContainerBlock(props: FormContainerProps){
const stepBuilder = new StepBuilder(props.form);
const form = stepBuilder.buildForm();
const state = initFormState(form, props.currentPageUrl, props.history);

{/* finally return the form */}
return (
<FormProvider initialState={state}>
Expand Down
8 changes: 8 additions & 0 deletions src/@episerver/forms-react/src/context/dispatchFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ export class DispatchFunctions {
});
}

UpdateElementDependencies = (elementKey: string, condition: boolean) => {
this._dispatch({
type: ActionType.UpdateElementDependencies,
elementKey: elementKey,
condition
});
}

updateAllValidation = (formValidationResults: FormValidationResult[]) => {
this._dispatch({
type: ActionType.UpdateAllValidation,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export class DependencyElementData {
elementId: string
condition: boolean
constructor(elementId: string, condition: boolean) {
this.elementId = elementId
this.condition = condition
}
}
16 changes: 14 additions & 2 deletions src/@episerver/forms-react/src/context/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { equals,
FormState,
FormSubmission,
FormValidationResult } from "@episerver/forms-sdk";
FormValidationResult,
ElementDependencies } from "@episerver/forms-sdk";


export enum ActionType {
UpdateValue = "UpdateValue",
Expand All @@ -14,7 +16,8 @@ export enum ActionType {
UpdateIdentityInfo = "UpdateIdentityInfo",
UpdateSubmissionKey = "UpdateSubmissionKey",
UpdateCurrentStepIndex = "UpdateCurrentStepIndex",
UpdateIsSubmitting = "UpdateIsSubmitting"
UpdateIsSubmitting = "UpdateIsSubmitting",
UpdateElementDependencies = "UpdateElementDependencies"
}

export function formReducer(formState: FormState, action: any) {
Expand All @@ -28,6 +31,15 @@ export function formReducer(formState: FormState, action: any) {
} as FormSubmission : fs)
} as FormState;
}
case ActionType.UpdateElementDependencies: {
return {
...formState,
elementDependencies: formState.elementDependencies.map(fs => equals(fs.elementKey, action.elementKey) ? {
elementKey: action.elementKey,
isSatisfied: action.condition
} as ElementDependencies : fs)
} as FormState;
}
case ActionType.UpdateValidation: {
return {
...formState,
Expand Down
19 changes: 3 additions & 16 deletions src/@episerver/forms-react/src/hooks/useElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,22 +103,9 @@ export const useElement = (element: FormElementBase) => {
isVisible.current = equals(conditionProps.satisfiedAction, SatisfiedActionType.Hide);
}

//update form state
let inactives = formContext?.dependencyInactiveElements ?? [];
let needUpdate = false;
if(isVisible.current){
if(inactives.includes(element.key)){
inactives = inactives.filter(ek => !equals(ek, element.key));
needUpdate = true;
}
}
else {
if(!isInArray(element.key, inactives)){
inactives.push(element.key);
needUpdate = true;
}
}
needUpdate && dispatchFuncs.updateDependencies(inactives);
// Update element dependencies state
dispatchFuncs.UpdateElementDependencies(element.key,checkConditions);

},[formContext?.formSubmissions]);

//focus on element if validate fail before submitting
Expand Down
19 changes: 12 additions & 7 deletions src/@episerver/forms-sdk/src/helpers/initFormState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FormCache } from "../form-cache";
import { StepHelper } from "./stepHelper";
import { FormStorage } from "../form-storage";
import { FormConstants, FormContainer, FormState, FormSubmission, FormValidationResult, StepDependencies } from "../models";
import { ElementDependencies, FormConstants, FormContainer, FormState, FormSubmission, FormValidationResult, StepDependencies } from "../models";
import { getDefaultValue } from "./elementHelper";
import { equals, isNullOrEmpty } from "./utils";

Expand All @@ -19,14 +19,18 @@ export function initFormState(formContainer: FormContainer, currentPageUrl?: str
let formSubmissions = [] as FormSubmission[];
let formValidationResults = [] as FormValidationResult[];
let stepDependencies = [] as StepDependencies[];
let elementDependencies = [] as ElementDependencies[]

formContainer.steps?.forEach(s => {
s.elements.forEach(e => {
//init form submission
formSubmissions = formSubmissions.concat({ elementKey: e.key, value: getDefaultValue(e) } as FormSubmission);

//init form validation
formValidationResults = formValidationResults.concat({ elementKey: e.key, result: {valid: true, message: ""} });
if (e.key != s.formStep.key) {
//init form validation
formValidationResults = formValidationResults.concat({ elementKey: e.key, result: {valid: true, message: ""} });
//init form submission
formSubmissions = formSubmissions.concat({ elementKey: e.key, value: getDefaultValue(e) } as FormSubmission);
//init form elements dependencies
elementDependencies = elementDependencies.concat({ elementKey: e.key, isSatisfied: true });
}
});
stepDependencies = stepDependencies.concat({ elementKey: s.formStep.key, isSatisfied: false });
});
Expand All @@ -53,6 +57,7 @@ export function initFormState(formContainer: FormContainer, currentPageUrl?: str
formValidationResults,
stepDependencies,
formContainer,
history
history,
elementDependencies
} as FormState;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ElementDependencies{
elementKey: string
isSatisfied: boolean
}
2 changes: 2 additions & 0 deletions src/@episerver/forms-sdk/src/models/states/FormState.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FormContainer } from "../FormContainer"
import { IdentityInfo } from "../IdentityInfo"
import { ElementDependencies } from "./ElementDependencies"
import { FormSubmission } from "./FormSubmission"
import { FormValidationResult } from "./FormValidation"
import { StepDependencies } from "./StepDependencies"
Expand All @@ -12,6 +13,7 @@ export interface FormState {
formSubmissions: FormSubmission[]
formValidationResults: FormValidationResult[]
stepDependencies: StepDependencies[]
elementDependencies: ElementDependencies[];
formContainer: FormContainer
dependencyInactiveElements: string[]
focusOn: string,
Expand Down
3 changes: 2 additions & 1 deletion src/@episerver/forms-sdk/src/models/states/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./FormState";
export * from "./FormSubmission";
export * from "./FormValidation";
export * from "./StepDependencies";
export * from "./StepDependencies";
export * from "./ElementDependencies";

0 comments on commit 37db8ce

Please sign in to comment.