From bdf40be31b432822b7fc0779659a07046402ab32 Mon Sep 17 00:00:00 2001 From: Jessica McInchak Date: Mon, 4 Nov 2024 16:21:55 +0100 Subject: [PATCH] fix: ensure questions that set a data field with no option data values are not automated (#3903) --- .../@planx/components/Checklist/Editor.tsx | 13 ++++++++++-- .../src/@planx/components/Question/Editor.tsx | 20 +++++++++++++++---- .../src/pages/FlowEditor/lib/store/preview.ts | 7 ++++--- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx b/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx index 28bbda8ce5..8c52fd02fd 100644 --- a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx @@ -5,7 +5,7 @@ import FormControlLabel from "@mui/material/FormControlLabel"; import IconButton from "@mui/material/IconButton"; import Switch from "@mui/material/Switch"; import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; -import { useFormik } from "formik"; +import { FormikErrors, FormikValues, useFormik } from "formik"; import adjust from "ramda/src/adjust"; import compose from "ramda/src/compose"; import remove from "ramda/src/remove"; @@ -312,7 +312,14 @@ export const ChecklistComponent: React.FC = (props) => { alert(JSON.stringify({ type, ...values, options }, null, 2)); } }, - validate: () => {}, + validate: ({ options, ...values }) => { + const errors: FormikErrors = {}; + 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"; + } + return errors; + }, }); const focusRef = useRef(null); @@ -365,6 +372,8 @@ export const ChecklistComponent: React.FC = (props) => { value={formik.values.fn} placeholder="Data Field" onChange={formik.handleChange} + error={Boolean(formik.errors?.fn)} + errorMessage={formik.errors?.fn} /> diff --git a/editor.planx.uk/src/@planx/components/Question/Editor.tsx b/editor.planx.uk/src/@planx/components/Question/Editor.tsx index d9a33237e0..c3160c7238 100644 --- a/editor.planx.uk/src/@planx/components/Question/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/Question/Editor.tsx @@ -1,7 +1,7 @@ import FormControlLabel from "@mui/material/FormControlLabel"; import Switch from "@mui/material/Switch"; import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; -import { useFormik } from "formik"; +import { FormikErrors, FormikValues, useFormik } from "formik"; import React, { useEffect, useRef } from "react"; import { ComponentTagSelect } from "ui/editor/ComponentTagSelect"; import ImgInput from "ui/editor/ImgInput/ImgInput"; @@ -109,7 +109,11 @@ const OptionEditor: React.FC<{ )} { props.onChange({ ...props.value, @@ -151,7 +155,14 @@ export const Question: React.FC = (props) => { alert(JSON.stringify({ type, ...values, children }, null, 2)); } }, - validate: () => { }, + validate: ({ options, ...values }) => { + const errors: FormikErrors = {}; + if (values.fn && !options.some((option) => option.data.val)) { + errors.fn = + "At least one option must set a data value when the question has a data field"; + } + return errors; + }, }); const focusRef = useRef(null); @@ -201,6 +212,8 @@ export const Question: React.FC = (props) => { value={formik.values.fn} placeholder="Data Field" onChange={formik.handleChange} + error={Boolean(formik.errors?.fn)} + errorMessage={formik.errors?.fn} /> @@ -221,7 +234,6 @@ export const Question: React.FC = (props) => { - flow[nodeId].data?.fn === data.fn, + ([nodeId, _breadcrumb]) => + [flow[nodeId].data?.fn, flow[nodeId].data?.output].includes(data.fn), ); - if (!visitedFns) return; + if (!visitedFns.length) return; // Get all options (aka edges or Answer nodes) for this node const options: Array = edges.map((edgeId) => ({