Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TM-739] Improve the defaults for which form step to start on in WizardForm #234

Merged
merged 3 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions src/components/extensive/WizardForm/index.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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[];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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 {
Expand All @@ -116,7 +116,7 @@ function WizardForm(props: WizardFormProps) {
};

const onClickSaveAndClose = () => {
props.onChange && props.onChange(formHook.getValues());
props.onChange?.(formHook.getValues());
modal.openModal(
<SaveAndCloseModal
{...props.saveAndCloseModal}
Expand All @@ -138,13 +138,14 @@ function WizardForm(props: WizardFormProps) {
formHook.reset(formHook.getValues());
}, [formHook, props.errors]);

const initialStepIndex = useMemo(() => {
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
}, []);

Expand Down
19 changes: 0 additions & 19 deletions src/components/extensive/WizardForm/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 14 additions & 1 deletion src/pages/entity/[entityName]/edit/[uuid]/index.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const EditEntityPage = () => {
const { getReportingWindow } = useGetReportingWindow();
const entityName = router.query.entityName as EntityName;
const entityUUID = router.query.uuid as string;
const mode = router.query.mode as string; //edit, provide-feedback-entity, provide-feedback-change-request
const mode = router.query.mode as string | undefined; //edit, provide-feedback-entity, provide-feedback-change-request

const isReport = isEntityReport(entityName);
const { data: entityData } = useGetV2ENTITYUUID({
Expand Down Expand Up @@ -107,6 +107,18 @@ const EditEntityPage = () => {
)
};

const initialStepProps = useMemo(() => {
if (isLoading) return {};

const stepIndex =
mode == null ? 0 : formSteps!.findIndex(step => step.fields.find(field => field.feedbackRequired) != null);

return {
initialStepIndex: stepIndex < 0 ? undefined : stepIndex,
disableInitialAutoProgress: stepIndex >= 0
};
}, [isLoading]);

return (
<BackgroundLayout>
<LoadingContainer loading={isLoading}>
Expand Down Expand Up @@ -152,6 +164,7 @@ const EditEntityPage = () => {
router.push(getEntityDetailPageLink(entityName, entityUUID));
}
}}
{...initialStepProps}
/>
</LoadingContainer>
</BackgroundLayout>
Expand Down