Skip to content

Commit

Permalink
chore: refactor public component wrappers for auto-answering into pre…
Browse files Browse the repository at this point in the history
…view `Node` (#4108)
  • Loading branch information
jessicamcinchak authored Jan 6, 2025
1 parent 8c864f7 commit 2984d2a
Show file tree
Hide file tree
Showing 16 changed files with 247 additions and 309 deletions.
155 changes: 140 additions & 15 deletions editor.planx.uk/src/@planx/components/Checklist/Public/Public.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,153 @@
import { useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import Grid from "@mui/material/Grid";
import { visuallyHidden } from "@mui/utils";
import {
ChecklistLayout,
checklistValidationSchema,
} from "@planx/components/Checklist/model";
import Card from "@planx/components/shared/Preview/Card";
import { CardHeader } from "@planx/components/shared/Preview/CardHeader/CardHeader";
import { getIn, useFormik } from "formik";
import { partition } from "lodash";
import React, { useEffect } from "react";
import FullWidthWrapper from "ui/public/FullWidthWrapper";
import ErrorWrapper from "ui/shared/ErrorWrapper";
import { object } from "yup";

import { Option } from "../../shared";
import { Props } from "../types";
import { AutoAnsweredChecklist } from "./components/AutoAnsweredChecklist";
import { VisibleChecklist } from "./components/VisibleChecklist";
import { ChecklistItems } from "./components/ChecklistItems";
import { ExclusiveChecklistItem } from "./components/ExclusiveChecklistItem";
import { GroupedChecklistOptions } from "./components/GroupedChecklistOptions";
import { toggleNonExclusiveCheckbox } from "./helpers";
import { useExclusiveOption } from "./hooks/useExclusiveOption";
import { useSortedOptions } from "./hooks/useSortedOptions";

const ChecklistComponent: React.FC<Props> = (props) => {
const autoAnswerableOptions = useStore(
(state) => state.autoAnswerableOptions
const {
description = "",
groupedOptions,
handleSubmit,
howMeasured,
info,
options,
policyRef,
text,
img,
previouslySubmittedData,
id,
autoAnswers,
} = props;

const formik = useFormik<{ checked: Array<string> }>({
initialValues: {
checked: previouslySubmittedData?.answers || [],
},
onSubmit: (values) => {
handleSubmit?.({ answers: values.checked });
},
validateOnBlur: false,
validateOnChange: false,
validationSchema: object({
checked: checklistValidationSchema(props),
}),
});

const { setCheckedFieldValue, layout } = useSortedOptions(
options,
groupedOptions,
formik,
);

if (props.neverAutoAnswer) {
return <VisibleChecklist {...props} />;
}
const [exclusiveOptions, nonExclusiveOptions]: Option[][] = partition(
options,
(option) => option.data.exclusive,
);

const {
exclusiveOrOption,
exclusiveOptionIsChecked,
toggleExclusiveCheckbox,
} = useExclusiveOption(exclusiveOptions, formik);

let idsThatCanBeAutoAnswered: string[] | undefined;
if (props.id) idsThatCanBeAutoAnswered = autoAnswerableOptions(props.id);
if (idsThatCanBeAutoAnswered) {
return (
<AutoAnsweredChecklist {...props} answerIds={idsThatCanBeAutoAnswered} />
const changeCheckbox = (id: string) => () => {
const currentCheckedIds = formik.values.checked;

const currentCheckboxIsExclusiveOption =
exclusiveOrOption && id === exclusiveOrOption.id;

if (currentCheckboxIsExclusiveOption) {
const newCheckedIds = toggleExclusiveCheckbox(id);
setCheckedFieldValue(newCheckedIds);
return;
}
const newCheckedIds = toggleNonExclusiveCheckbox(
id,
currentCheckedIds,
exclusiveOrOption,
);
setCheckedFieldValue(newCheckedIds);
};

// Auto-answered Checklists still set a breadcrumb even though they render null
useEffect(() => {
if (autoAnswers) {
handleSubmit?.({
answers: autoAnswers,
auto: true,
});
}
}, [autoAnswers]);

// Auto-answered Checklists are not publicly visible
if (autoAnswers) {
return null;
}

return <VisibleChecklist {...props} />;
return (
<Card handleSubmit={formik.handleSubmit} isValid>
<CardHeader
title={text}
description={description}
info={info}
policyRef={policyRef}
howMeasured={howMeasured}
img={img}
/>
<FullWidthWrapper>
<ErrorWrapper error={getIn(formik.errors, "checked")} id={id}>
<Grid
container
spacing={layout === ChecklistLayout.Images ? 2 : 0}
component="fieldset"
>
<legend style={visuallyHidden}>{text}</legend>
<ChecklistItems
nonExclusiveOptions={nonExclusiveOptions}
layout={layout}
changeCheckbox={changeCheckbox}
formik={formik}
exclusiveOptionIsChecked={exclusiveOptionIsChecked}
/>
{exclusiveOrOption && (
<ExclusiveChecklistItem
exclusiveOrOption={exclusiveOrOption}
changeCheckbox={changeCheckbox}
formik={formik}
/>
)}
{groupedOptions && (
<GroupedChecklistOptions
groupedOptions={groupedOptions}
previouslySubmittedData={previouslySubmittedData}
changeCheckbox={changeCheckbox}
formik={formik}
/>
)}
</Grid>
</ErrorWrapper>
</FullWidthWrapper>
</Card>
);
};

export default ChecklistComponent;

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React from "react";
import FormWrapper from "ui/public/FormWrapper";
import ChecklistItem from "ui/shared/ChecklistItem/ChecklistItem";

import { ChecklistLayout } from "./VisibleChecklist";
import { ChecklistLayout } from "../../model";

interface Props {
nonExclusiveOptions: Option[];
Expand Down Expand Up @@ -50,7 +50,7 @@ export const ChecklistItems = ({
checkbox
/>
</Grid>
)
),
)}
</>
);

This file was deleted.

Loading

0 comments on commit 2984d2a

Please sign in to comment.