From 40db9fe743aec220bfc6e4d8f832ba4db6a8d00f Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Wed, 5 Jun 2024 20:16:04 -0700 Subject: [PATCH] [TM-739] Make the default behavior when not responding to feedback a bit more sane. --- src/components/extensive/WizardForm/index.tsx | 25 ++++++++++--------- src/components/extensive/WizardForm/utils.ts | 19 -------------- .../[entityName]/edit/[uuid]/index.page.tsx | 8 +++--- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/components/extensive/WizardForm/index.tsx b/src/components/extensive/WizardForm/index.tsx index c34218eaa..886fca41f 100644 --- a/src/components/extensive/WizardForm/index.tsx +++ b/src/components/extensive/WizardForm/index.tsx @@ -1,6 +1,6 @@ import { yupResolver } from "@hookform/resolvers/yup"; import { useT } from "@transifex/react"; -import { memo, useEffect, useLayoutEffect, useMemo, useState } from "react"; +import { memo, useEffect, useLayoutEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { When } from "react-if"; import { twMerge } from "tailwind-merge"; @@ -18,7 +18,7 @@ import { FormFooter } from "./FormFooter"; import { WizardFormHeader } from "./FormHeader"; import FormSummary, { FormSummaryOptions } from "./FormSummary"; import SaveAndCloseModal, { SaveAndCloseModalProps } from "./modals/SaveAndCloseModal"; -import { downloadAnswersCSV, getSchema, getStepIndexByValues } from "./utils"; +import { downloadAnswersCSV, getSchema } from "./utils"; export interface WizardFormProps { steps: FormStepSchema[]; @@ -67,7 +67,7 @@ function WizardForm(props: WizardFormProps) { const t = useT(); const modal = useModalContext(); - const [selectedStepIndex, setSelectedStepIndex] = useState(props.initialStepIndex || 0); + const [selectedStepIndex, setSelectedStepIndex] = useState(props.initialStepIndex ?? 0); const selectedStep = props.steps?.[selectedStepIndex]; const selectedValidationSchema = selectedStep ? getSchema(selectedStep.fields) : undefined; const lastIndex = props.summaryOptions ? props.steps.length : props.steps.length - 1; @@ -96,7 +96,7 @@ function WizardForm(props: WizardFormProps) { console.debug("Form Errors", formHook.formState.errors); } - const onChange = useDebounce(() => !formHasError && props.onChange && props.onChange(formHook.getValues())); + const onChange = useDebounce(() => !formHasError && props.onChange?.(formHook.getValues())); const onSubmitStep = (data: any) => { if (selectedStepIndex < lastIndex) { @@ -105,7 +105,7 @@ function WizardForm(props: WizardFormProps) { //Disable auto step progress if disableAutoProgress was passed setSelectedStepIndex(n => n + 1); } - props.onChange && props.onChange(formHook.getValues()); + props.onChange?.(formHook.getValues()); props.onStepChange?.(data, selectedStep); formHook.clearErrors(); } else { @@ -116,7 +116,7 @@ function WizardForm(props: WizardFormProps) { }; const onClickSaveAndClose = () => { - props.onChange && props.onChange(formHook.getValues()); + props.onChange?.(formHook.getValues()); modal.openModal( { - return getStepIndexByValues(props.defaultValues, props.steps); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [props.defaultValues, props.steps]); - useEffect(() => { - if (!props.disableAutoProgress && !props.disableInitialAutoProgress) setSelectedStepIndex(initialStepIndex); + if (props.disableAutoProgress || props.disableInitialAutoProgress) return; + + const stepIndex = props.steps.findIndex(step => !getSchema(step.fields).isValidSync(props.defaultValues)); + + // If none of the steps has an invalid field, use the last step + setSelectedStepIndex(stepIndex < 0 ? lastIndex : stepIndex); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/src/components/extensive/WizardForm/utils.ts b/src/components/extensive/WizardForm/utils.ts index c05085046..c373499bd 100644 --- a/src/components/extensive/WizardForm/utils.ts +++ b/src/components/extensive/WizardForm/utils.ts @@ -53,25 +53,6 @@ export const getSchemaFields = (fields: FormField[]) => { return schema; }; -export const getStepIndexByValues = (values: any, steps: FormStepSchema[], skipValueCheck?: boolean) => { - let currentStepIndex = -1; - - for (const step of steps) { - currentStepIndex++; - - if (!getSchema(step.fields).isValidSync(values)) { - return currentStepIndex; - } else if (!skipValueCheck) { - for (const field of step.fields) { - if (!values[field.name]) { - return currentStepIndex; - } - } - } - } - return currentStepIndex; -}; - export const getAnswer = ( field: FormField, values: any diff --git a/src/pages/entity/[entityName]/edit/[uuid]/index.page.tsx b/src/pages/entity/[entityName]/edit/[uuid]/index.page.tsx index be5bbebfc..f50619081 100644 --- a/src/pages/entity/[entityName]/edit/[uuid]/index.page.tsx +++ b/src/pages/entity/[entityName]/edit/[uuid]/index.page.tsx @@ -110,15 +110,17 @@ const EditEntityPage = () => { const initialStepProps = useMemo(() => { if (isLoading) return {}; - const initialStepIndex = formSteps!.findIndex(step => step.fields.find(field => field.feedbackRequired) != null); + const stepIndex = formSteps!.findIndex(step => step.fields.find(field => field.feedbackRequired) != null); - return { initialStepIndex, disableInitialAutoProgress: initialStepIndex != null }; + return { + initialStepIndex: stepIndex < 0 ? undefined : stepIndex, + disableInitialAutoProgress: stepIndex >= 0 + }; }, [isLoading]); return ( - !isLoading &&{" "}