Skip to content

Commit

Permalink
add validation for allRequired and maxItems
Browse files Browse the repository at this point in the history
  • Loading branch information
jamdelion committed Dec 18, 2024
1 parent 9585660 commit ef50330
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 37 deletions.
31 changes: 23 additions & 8 deletions editor.planx.uk/src/@planx/components/Checklist/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { ModalFooter } from "ui/editor/ModalFooter";
import ModalSection from "ui/editor/ModalSection";
import ModalSectionContent from "ui/editor/ModalSectionContent";
import RichTextInput from "ui/editor/RichTextInput/RichTextInput";
import ErrorWrapper from "ui/shared/ErrorWrapper";
import Input from "ui/shared/Input/Input";
import InputRow from "ui/shared/InputRow";
import { Switch } from "ui/shared/Switch";

import { parseBaseNodeData } from "../../shared";
import { Option, parseBaseNodeData } from "../../shared";
import { ICONS } from "../../shared/icons";
import type { Checklist } from "../model";
import { toggleExpandableChecklist } from "../model";
Expand Down Expand Up @@ -39,7 +40,7 @@ export const ChecklistEditor: React.FC<ChecklistProps> = (props) => {
: groupedOptions?.flatMap((group) => group.children);

const filteredOptions = (sourceOptions || []).filter(
(option) => option.data.text,
(option) => option.data.text
);

const processedOptions = filteredOptions.map((option) => ({
Expand All @@ -66,21 +67,33 @@ export const ChecklistEditor: React.FC<ChecklistProps> = (props) => {
}),
},
},
processedOptions,
processedOptions
);
} else {
alert(JSON.stringify({ type, ...values, options }, null, 2));
}
},
validate: ({ options, groupedOptions, ...values }) => {
validate: ({ options, groupedOptions, allRequired, ...values }) => {
const errors: FormikErrors<FormikValues> = {};

const exclusiveOptions: Option[] | undefined = options?.filter(
(option) => option.data.exclusive
);
if (allRequired && exclusiveOptions && exclusiveOptions.length > 0) {
errors.allRequired =
'Cannot configure exclusive "or" option alongside "all required" setting';
}
// Account for flat or expandable Checklist options
options =
options || groupedOptions?.map((group) => group.children)?.flat();
if (values.fn && !options?.some((option) => option.data.val)) {
errors.fn =
"At least one option must set a data value when the checklist has a data field";
}
if (exclusiveOptions && exclusiveOptions.length > 1) {
errors.options =
"There should be a maximum of one exclusive option configured";
}
return errors;
},
});
Expand Down Expand Up @@ -160,28 +173,30 @@ export const ChecklistEditor: React.FC<ChecklistProps> = (props) => {
onChange={() =>
formik.setFieldValue(
"allRequired",
!formik.values.allRequired,
!formik.values.allRequired
)
}
label="All required"
/>
</InputRow>

<InputRow>
<Switch
checked={formik.values.neverAutoAnswer}
onChange={() =>
formik.setFieldValue(
"neverAutoAnswer",
!formik.values.neverAutoAnswer,
!formik.values.neverAutoAnswer
)
}
label="Always put to user (forgo automation)"
/>
</InputRow>
</InputGroup>
</ModalSectionContent>

<Options formik={formik} />
<ErrorWrapper error={formik.errors.options}>
<Options formik={formik} />
</ErrorWrapper>
</ModalSection>

<ModalFooter formik={formik} />
Expand Down
55 changes: 29 additions & 26 deletions editor.planx.uk/src/@planx/components/Checklist/Editor/Options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import React from "react";
import { FormikHookReturn } from "types";
import ListManager from "ui/editor/ListManager/ListManager";
import ModalSectionContent from "ui/editor/ModalSectionContent";
import ErrorWrapper from "ui/shared/ErrorWrapper";
import Input from "ui/shared/Input/Input";
import InputRow from "ui/shared/InputRow";

Expand Down Expand Up @@ -164,32 +165,34 @@ export const Options: React.FC<{ formik: FormikHookReturn }> = ({ formik }) => {
)}
{exclusiveOrOptionManagerShouldRender ? (
<Box mt={1}>
<ListManager
values={exclusiveOptions || []}
onChange={(newExclusiveOptions) => {
const newCombinedOptions = [
...nonExclusiveOptions,
...newExclusiveOptions,
];
formik.setFieldValue("options", newCombinedOptions);
}}
newValueLabel='add "or" option'
maxItems={1}
disableDragAndDrop
newValue={() =>
({
data: {
text: "",
description: "",
val: "",
exclusive: true,
},
}) as Option
}
Editor={BaseOptionsEditor}
editorExtraProps={{ showValueField: !!formik.values.fn }}
/>
</Box>
<ErrorWrapper error={formik.errors.allRequired as string}>
<ListManager
values={exclusiveOptions || []}
onChange={(newExclusiveOptions) => {
const newCombinedOptions = [
...nonExclusiveOptions,
...newExclusiveOptions,
];
formik.setFieldValue("options", newCombinedOptions);
}}
newValueLabel='add "or" option'
maxItems={1}
disableDragAndDrop
newValue={() =>
({
data: {
text: "",
description: "",
val: "",
exclusive: true,
},
}) as Option
}
Editor={BaseOptionsEditor}
editorExtraProps={{ showValueField: !!formik.values.fn }}
/>
</ErrorWrapper>
</Box>
) : (
<></>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ export const toggleNonExclusiveCheckbox = (
thisCheckboxId,
currentlyCheckedOptionIds
);
return newCheckedOptionIds.filter(
(id: string) => exclusiveOrOption && id !== exclusiveOrOption.id
);
if (exclusiveOrOption) {
return newCheckedOptionIds.filter(
(id: string) => exclusiveOrOption && id !== exclusiveOrOption.id
);
}
return newCheckedOptionIds;
};

0 comments on commit ef50330

Please sign in to comment.