From 82de73077abaada34553cc6058a38db4d63209ee Mon Sep 17 00:00:00 2001 From: Ian Bolton Date: Tue, 10 Oct 2023 01:13:43 +0000 Subject: [PATCH] :bug: Async default values loading for assessment wizard (#1452) Resolves https://issues.redhat.com/browse/MTA-1402 Signed-off-by: ibolton336 --- .../app/pages/assessment/assessment-page.tsx | 10 +++---- .../assessment-wizard/assessment-wizard.tsx | 28 +++++++++++-------- .../multi-input-selection.tsx | 4 +-- .../questionnaire-form/questionnaire-form.tsx | 10 +++---- .../app/pages/assessment/form-utils.test.ts | 4 +-- client/src/app/pages/assessment/form-utils.ts | 7 ++++- 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/client/src/app/pages/assessment/assessment-page.tsx b/client/src/app/pages/assessment/assessment-page.tsx index cbfb5652ae..3bc1f97406 100644 --- a/client/src/app/pages/assessment/assessment-page.tsx +++ b/client/src/app/pages/assessment/assessment-page.tsx @@ -13,8 +13,6 @@ import BanIcon from "@patternfly/react-icons/dist/esm/icons/ban-icon"; import { AssessmentRoute } from "@app/Paths"; import { getAxiosErrorMessage } from "@app/utils/utils"; import { SimpleEmptyState } from "@app/components/SimpleEmptyState"; -import { ConditionalRender } from "@app/components/ConditionalRender"; -import { AppPlaceholder } from "@app/components/AppPlaceholder"; import { useFetchAssessmentById } from "@app/queries/assessments"; import { AssessmentPageHeader } from "./components/assessment-page-header"; import { AssessmentWizard } from "./components/assessment-wizard/assessment-wizard"; @@ -63,9 +61,11 @@ const AssessmentPage: React.FC = () => { } /> )} - }> - - + ); diff --git a/client/src/app/pages/assessment/components/assessment-wizard/assessment-wizard.tsx b/client/src/app/pages/assessment/components/assessment-wizard/assessment-wizard.tsx index 496cb84296..926ebdfe26 100644 --- a/client/src/app/pages/assessment/components/assessment-wizard/assessment-wizard.tsx +++ b/client/src/app/pages/assessment/components/assessment-wizard/assessment-wizard.tsx @@ -62,11 +62,13 @@ export interface AssessmentWizardValues { export interface AssessmentWizardProps { assessment?: Assessment; isOpen: boolean; + isLoadingAssessment: boolean; } export const AssessmentWizard: React.FC = ({ assessment, isOpen, + isLoadingAssessment, }) => { const isArchetype = useIsArchetype(); const queryClient = useQueryClient(); @@ -129,7 +131,7 @@ export const AssessmentWizard: React.FC = ({ }); } return questions; - }, [assessment]); + }, [assessment, isLoadingAssessment]); const validationSchema = yup.object().shape({ stakeholders: yup.array().of(yup.string()), @@ -137,22 +139,24 @@ export const AssessmentWizard: React.FC = ({ }); const methods = useForm({ - defaultValues: useMemo(() => { - return { - stakeholders: - assessment?.stakeholders?.map((sh) => sh.name).sort() ?? [], - stakeholderGroups: - assessment?.stakeholderGroups?.map((sg) => sg.name).sort() ?? [], - // comments: initialComments, - questions: initialQuestions, - [SAVE_ACTION_KEY]: SAVE_ACTION_VALUE.SAVE_AS_DRAFT, - }; - }, [assessment]), resolver: yupResolver(validationSchema), mode: "all", }); const values = methods.getValues(); + useEffect(() => { + methods.reset({ + stakeholders: assessment?.stakeholders?.map((sh) => sh.name).sort() ?? [], + stakeholderGroups: + assessment?.stakeholderGroups?.map((sg) => sg.name).sort() ?? [], + questions: initialQuestions, + [SAVE_ACTION_KEY]: SAVE_ACTION_VALUE.SAVE_AS_DRAFT, + }); + return () => { + methods.reset(); + }; + }, [assessment]); + const errors = methods.formState.errors; const isValid = methods.formState.isValid; const isSubmitting = methods.formState.isSubmitting; diff --git a/client/src/app/pages/assessment/components/questionnaire-form/multi-input-selection/multi-input-selection.tsx b/client/src/app/pages/assessment/components/questionnaire-form/multi-input-selection/multi-input-selection.tsx index aea19eeb74..56d6e82f7c 100644 --- a/client/src/app/pages/assessment/components/questionnaire-form/multi-input-selection/multi-input-selection.tsx +++ b/client/src/app/pages/assessment/components/questionnaire-form/multi-input-selection/multi-input-selection.tsx @@ -30,7 +30,7 @@ export const MultiInputSelection: React.FC = ({ return ( {sortedOptions.map((option, i) => { - const answerUniqueId = `${questionFieldName}-${option.text}-${i}}`; + const answerUniqueId = `${questionFieldName}-${option.text}-${i}`; return ( = ({ id={answerUniqueId} name={questionFieldName} isChecked={value === option.text} - onChange={(checked, e) => { + onChange={() => { onChange(option.text); }} aria-label={option.text} diff --git a/client/src/app/pages/assessment/components/questionnaire-form/questionnaire-form.tsx b/client/src/app/pages/assessment/components/questionnaire-form/questionnaire-form.tsx index 8bc3ddbb01..10b9bc3e63 100644 --- a/client/src/app/pages/assessment/components/questionnaire-form/questionnaire-form.tsx +++ b/client/src/app/pages/assessment/components/questionnaire-form/questionnaire-form.tsx @@ -12,7 +12,7 @@ import { import HelpIcon from "@patternfly/react-icons/dist/esm/icons/help-icon"; import { MultiInputSelection } from "./multi-input-selection"; import { Question, QuestionHeader, QuestionBody } from "./question"; -import { getCommentFieldName, getQuestionFieldName } from "../../form-utils"; +import { getCommentFieldName } from "../../form-utils"; import { HookFormPFTextInput } from "@app/components/HookFormPFFields"; import { useFormContext } from "react-hook-form"; import { Section } from "@app/api/models"; @@ -26,7 +26,7 @@ export const QuestionnaireForm: React.FC = ({ section, }) => { const { t } = useTranslation(); - const { control, getValues } = useFormContext(); + const { control } = useFormContext(); // Force the wizard parent to reset the scroll useEffect(() => { @@ -53,10 +53,10 @@ export const QuestionnaireForm: React.FC = ({ {section.name} - {sortedQuestions.map((question) => { + {sortedQuestions.map((question, i) => { const questionUniqueKey = `${section.name}-${ question.order || "no-order" - }-${question.text || "no-text"}`; + }-${question.text || "no-text"}-${i}`; return ( @@ -79,7 +79,7 @@ export const QuestionnaireForm: React.FC = ({ diff --git a/client/src/app/pages/assessment/form-utils.test.ts b/client/src/app/pages/assessment/form-utils.test.ts index 0cd0f574f0..32dc4a2128 100644 --- a/client/src/app/pages/assessment/form-utils.test.ts +++ b/client/src/app/pages/assessment/form-utils.test.ts @@ -26,11 +26,11 @@ describe("Application assessment - form utils", () => { it("getQuestionFieldName: fullName", () => { const fieldName = getQuestionFieldName(question, true); - expect(fieldName).toBe("questions.question-1-Question 321"); + expect(fieldName).toBe("questions.question-1-Question_321"); }); it("getQuestionFieldName: singleName", () => { const fieldName = getQuestionFieldName(question, false); - expect(fieldName).toBe("question-1-Question 321"); + expect(fieldName).toBe("question-1-Question_321"); }); }); diff --git a/client/src/app/pages/assessment/form-utils.ts b/client/src/app/pages/assessment/form-utils.ts index c75600bbc0..5b868b6a4e 100644 --- a/client/src/app/pages/assessment/form-utils.ts +++ b/client/src/app/pages/assessment/form-utils.ts @@ -13,8 +13,13 @@ export const getCommentFieldName = (section: Section, fullName: boolean) => { const fieldName = `category-${section.name}`; return fullName ? `${COMMENTS_KEY}.${fieldName}` : fieldName; }; +export const sanitizeKey = (text: string) => { + return text.replace(/[^a-zA-Z0-9-_:.]/g, "_"); +}; export const getQuestionFieldName = (question: Question, fullName: boolean) => { const fieldName = `question-${question.order}-${question.text}`; - return fullName ? `${QUESTIONS_KEY}.${fieldName}` : fieldName; + return fullName + ? `${QUESTIONS_KEY}.${sanitizeKey(fieldName)}` + : sanitizeKey(fieldName); };