Merged PR 1565: eval fixes

Related work items: #12956
This commit is contained in:
Robert Bond
2025-04-16 13:57:17 +00:00
8 changed files with 224 additions and 39 deletions
@@ -287,13 +287,13 @@ const RepAgent = (props) => {
props.props.props.form[props.form] props.props.props.form[props.form]
.values || {}; .values || {};
console.log("valuesobj:", valuesObj); //console.log("valuesobj:", valuesObj);
delete valuesObj[ delete valuesObj[
"_pinswg_appellant_value" "_pinswg_appellant_value"
]; ];
console.log("on save:", valuesObj); //console.log("on save:", valuesObj);
updateRepresentation( updateRepresentation(
valuesObj, valuesObj,
false, false,
@@ -275,13 +275,13 @@ const RepAppellant = (props) => {
props.props.props.form[props.form] props.props.props.form[props.form]
.values || {}; .values || {};
console.log("valuesobj:", valuesObj); //console.log("valuesobj:", valuesObj);
delete valuesObj[ delete valuesObj[
"_pinswg_appellant_value" "_pinswg_appellant_value"
]; ];
console.log("on save:", valuesObj); //console.log("on save:", valuesObj);
updateRepresentation( updateRepresentation(
valuesObj, valuesObj,
false, false,
@@ -283,13 +283,13 @@ const RepInterestedPartyPerson = (props) => {
props.props.props.form[props.form] props.props.props.form[props.form]
.values || {}; .values || {};
console.log("valuesobj:", valuesObj); //console.log("valuesobj:", valuesObj);
delete valuesObj[ delete valuesObj[
"_pinswg_appellant_value" "_pinswg_appellant_value"
]; ];
console.log("on save:", valuesObj); //console.log("on save:", valuesObj);
updateRepresentation( updateRepresentation(
valuesObj, valuesObj,
false, false,
@@ -480,16 +480,16 @@ let RepLPA = (props) => {
props.form props.form
].values || {}; ].values || {};
console.log( // console.log(
"valuesobj:", // "valuesobj:",
valuesObj // valuesObj
); // );
delete valuesObj[ delete valuesObj[
"_pinswg_appellant_value" "_pinswg_appellant_value"
]; ];
console.log("on save:", valuesObj); //console.log("on save:", valuesObj);
updateRepresentation( updateRepresentation(
valuesObj, valuesObj,
false, false,
@@ -515,13 +515,13 @@ let RepLPA = (props) => {
props.props.props.form[props.form] props.props.props.form[props.form]
.values || {}; .values || {};
console.log("valuesobj:", valuesObj); //console.log("valuesobj:", valuesObj);
delete valuesObj[ delete valuesObj[
"_pinswg_appellant_value" "_pinswg_appellant_value"
]; ];
console.log("on save:", valuesObj); //console.log("on save:", valuesObj);
updateRepresentation( updateRepresentation(
valuesObj, valuesObj,
false, false,
@@ -571,16 +571,16 @@ let RepLPA = (props) => {
props.form props.form
].values || {}; ].values || {};
console.log( // console.log(
"valuesobj:", // "valuesobj:",
valuesObj // valuesObj
); // );
delete valuesObj[ delete valuesObj[
"_pinswg_appellant_value" "_pinswg_appellant_value"
]; ];
console.log("on save:", valuesObj); //console.log("on save:", valuesObj);
updateRepresentation( updateRepresentation(
valuesObj, valuesObj,
false, false,
+130 -14
View File
@@ -37,6 +37,7 @@ const ReactQuill = dynamic(() => import("react-quill-new"), { ssr: false });
import { useStore as store, useSelector } from "react-redux"; import { useStore as store, useSelector } from "react-redux";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { validateField } from "./validationUtils"; // Import the validation function
const RenderTextfield = ({ const RenderTextfield = ({
id, id,
@@ -223,7 +224,9 @@ export function Textfield(props) {
// console.log(parentField, formProps, form); // console.log(parentField, formProps, form);
//console.log("validation props:", validation); //console.log("validation props:", validation);
const requiredMessage = t("newappeal:is-required-label");
const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label");
const invalidPostcodeMessage = t("newappeal:invalid-postcode-label");
return ( return (
<div className="govuk-form-group"> <div className="govuk-form-group">
{parentField != false ? ( {parentField != false ? (
@@ -234,7 +237,15 @@ export function Textfield(props) {
component={RenderTextfield} component={RenderTextfield}
type="text" type="text"
className="govuk-input govuk-input--width-20" className="govuk-input govuk-input--width-20"
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
label={props.label} label={props.label}
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
/> />
@@ -246,7 +257,15 @@ export function Textfield(props) {
component={RenderTextfield} component={RenderTextfield}
type="text" type="text"
className="govuk-input govuk-input--width-20" className="govuk-input govuk-input--width-20"
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
label={props.label} label={props.label}
errorMsg={t("newappeal:is-required-label")} errorMsg={t("newappeal:is-required-label")}
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
@@ -356,6 +375,9 @@ export function MultiLinefield(props) {
//console.log(showIfHasParentShowValue, formProps[form].values[parentField]); //console.log(showIfHasParentShowValue, formProps[form].values[parentField]);
let { t } = useTranslation(); let { t } = useTranslation();
const requiredMessage = t("newappeal:is-required-label");
const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label");
const invalidPostcodeMessage = t("newappeal:invalid-postcode-label");
return ( return (
<> <>
{parentField != false ? ( {parentField != false ? (
@@ -383,7 +405,15 @@ export function MultiLinefield(props) {
rows="5" rows="5"
className="govuk-textarea govuk-input--width-30" className="govuk-textarea govuk-input--width-30"
aria-describedby={props.name + "-hint"} aria-describedby={props.name + "-hint"}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
/> />
</div> </div>
@@ -412,7 +442,15 @@ export function MultiLinefield(props) {
rows="5" rows="5"
className="govuk-textarea govuk-input--width-30" className="govuk-textarea govuk-input--width-30"
aria-describedby={props.name + "-hint"} aria-describedby={props.name + "-hint"}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
/> />
</div> </div>
@@ -517,6 +555,9 @@ export function RichMultiLinefield(props) {
//console.log(showIfHasParentShowValue, formProps[form].values[parentField]); //console.log(showIfHasParentShowValue, formProps[form].values[parentField]);
let { t } = useTranslation(); let { t } = useTranslation();
const requiredMessage = t("newappeal:is-required-label");
const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label");
const invalidPostcodeMessage = t("newappeal:invalid-postcode-label");
return ( return (
<> <>
{parentField != false ? ( {parentField != false ? (
@@ -543,7 +584,15 @@ export function RichMultiLinefield(props) {
rows="5" rows="5"
className="govuk-textarea govuk-input--width-30" className="govuk-textarea govuk-input--width-30"
aria-describedby={props.name + "-hint"} aria-describedby={props.name + "-hint"}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
/> />
</div> </div>
@@ -572,7 +621,15 @@ export function RichMultiLinefield(props) {
rows="5" rows="5"
className="govuk-textarea govuk-input--width-30" className="govuk-textarea govuk-input--width-30"
aria-describedby={props.name + "-hint"} aria-describedby={props.name + "-hint"}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
/> />
</div> </div>
@@ -738,6 +795,9 @@ export function DateFieldPicker(props) {
_.has(formProps[form].values, parentField) && _.has(formProps[form].values, parentField) &&
formProps[form].values[parentField]) == parentFieldShowOnValue; formProps[form].values[parentField]) == parentFieldShowOnValue;
const requiredMessage = t("newappeal:is-required-label");
const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label");
const invalidPostcodeMessage = t("newappeal:invalid-postcode-label");
return ( return (
<div className="govuk-form-group"> <div className="govuk-form-group">
{parentField != false ? ( {parentField != false ? (
@@ -747,7 +807,15 @@ export function DateFieldPicker(props) {
id={name} id={name}
label={label} label={label}
component={RenderDatePicker} component={RenderDatePicker}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
errorMsg={t("newappeal:select-a-date-label")} errorMsg={t("newappeal:select-a-date-label")}
dateStart={dateStart} dateStart={dateStart}
dateEnd={dateEnd} dateEnd={dateEnd}
@@ -760,7 +828,15 @@ export function DateFieldPicker(props) {
id={name} id={name}
label={label} label={label}
component={RenderDatePicker} component={RenderDatePicker}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
errorMsg={t("newappeal:select-a-date-label")} errorMsg={t("newappeal:select-a-date-label")}
dateStart={dateStart} dateStart={dateStart}
dateEnd={dateEnd} dateEnd={dateEnd}
@@ -1187,6 +1263,9 @@ export function Radiofield(props) {
(showIfHasParentShowValue == parentField) != false && (showIfHasParentShowValue == parentField) != false &&
showIfHasParentShowValue; showIfHasParentShowValue;
const requiredMessage = t("newappeal:is-required-label");
const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label");
const invalidPostcodeMessage = t("newappeal:invalid-postcode-label");
return ( return (
<> <>
{parentField != false ? ( {parentField != false ? (
@@ -1202,7 +1281,15 @@ export function Radiofield(props) {
component={RenderRadio} component={RenderRadio}
inline={props.inline} inline={props.inline}
hint={props.hint} hint={props.hint}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
requiredDocumentLabel={props.requiredDocumentLabel} requiredDocumentLabel={props.requiredDocumentLabel}
requiredDocumentValue={props.requiredDocumentValue} requiredDocumentValue={props.requiredDocumentValue}
setDocumentsList={props.setDocumentsList} setDocumentsList={props.setDocumentsList}
@@ -1221,7 +1308,15 @@ export function Radiofield(props) {
component={RenderRadio} component={RenderRadio}
inline={props.inline} inline={props.inline}
hint={props.hint} hint={props.hint}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
requiredDocumentLabel={props.requiredDocumentLabel} requiredDocumentLabel={props.requiredDocumentLabel}
requiredDocumentValue={props.requiredDocumentValue} requiredDocumentValue={props.requiredDocumentValue}
setDocumentsList={props.setDocumentsList} setDocumentsList={props.setDocumentsList}
@@ -1458,7 +1553,9 @@ export function NumericField(props) {
showIfHasParentShowValue; showIfHasParentShowValue;
//console.log("parentField:", parentField, showIfHasParentShowValue); //console.log("parentField:", parentField, showIfHasParentShowValue);
const requiredMessage = t("newappeal:is-required-label");
const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label");
const invalidPostcodeMessage = t("newappeal:invalid-postcode-label");
return ( return (
<> <>
{parentField != false ? ( {parentField != false ? (
@@ -1474,7 +1571,15 @@ export function NumericField(props) {
pattern="[0-9]*" pattern="[0-9]*"
inputMode="numeric" inputMode="numeric"
parse={Number} parse={Number}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
component={RenderTextfield} component={RenderTextfield}
label={label} label={label}
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
@@ -1586,6 +1691,9 @@ export function DecimalField(props) {
return undefined; return undefined;
}; };
const requiredMessage = t("newappeal:is-required-label");
const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label");
const invalidPostcodeMessage = t("newappeal:invalid-postcode-label");
return ( return (
<> <>
{parentField != false ? ( {parentField != false ? (
@@ -1602,7 +1710,15 @@ export function DecimalField(props) {
pattern="[0-9]*" pattern="[0-9]*"
inputMode="numeric" inputMode="numeric"
parse={Number} parse={Number}
validate={eval(validation)} validate={(value) =>
validateField(
value,
validation,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
)
} // Use the external validate function
component={RenderTextfield} component={RenderTextfield}
label={props.label} label={props.label}
maxFieldLength={props.maxFieldLength} maxFieldLength={props.maxFieldLength}
+69
View File
@@ -0,0 +1,69 @@
// validationUtils.js
// Validation functions
const required = (value, requiredMessage, emojiNotAllowedMessage) => {
let errors;
if (!value) {
errors = requiredMessage;
} else {
const emojiRegex =
/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{2300}-\u{23FF}\u{2B50}\u{1F004}-\u{1F0CF}\u{1F0A0}-\u{1F0A5}\u{1F170}-\u{1F251}]/gu;
if (emojiRegex.test(value)) {
errors = emojiNotAllowedMessage;
}
}
return errors;
};
const postcode = (value, invalidPostcodeMessage) =>
value &&
!/^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$/i.test(value)
? "Invalid postcode"
: undefined;
// Function to parse the validation string
export const parseValidationString = (validationString) => {
if (typeof validationString !== "string") {
return []; // Return an empty array if it's not a string
}
// Remove square brackets and split by commas
return validationString
.replace(/[\[\]']+/g, "") // Remove square brackets
.split(",") // Split by commas
.map((rule) => rule.trim()); // Trim each validation rule
};
// Function to handle multiple validation rules
export const validateField = (
value,
validationString,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
) => {
const validations = parseValidationString(validationString); // Parse the validation string
let errors;
for (let validationRule of validations) {
const validationFunc = validationFunctions[validationRule];
if (validationFunc) {
errors = validationFunc(
value,
requiredMessage,
emojiNotAllowedMessage,
invalidPostcodeMessage
);
}
if (errors) break; // Exit if any validation fails
}
return errors;
};
// Map validation strings to actual validation functions
export const validationFunctions = {
required,
postcode,
// Add other validation functions as needed
};
+1 -1
View File
@@ -290,7 +290,7 @@ let UploadFile = (props) => {
const uploadAction = await uploadFiles(dataObj, fileObj).then( const uploadAction = await uploadFiles(dataObj, fileObj).then(
(data) => { (data) => {
console.log("hello", data); console.log("$1", data);
} }
); );
// router.push({ // router.push({
+6 -6
View File
@@ -125,7 +125,7 @@ let BuildSection = (props) => {
props.props.accountDetails.containerID, props.props.accountDetails.containerID,
props.props.appealType.caseReference.ticketnumber props.props.appealType.caseReference.ticketnumber
).then((data) => { ).then((data) => {
console.log("hello", data); console.log("$1", data);
setCompletedUploadFiles(true); setCompletedUploadFiles(true);
return data; return data;
}); });
@@ -488,7 +488,7 @@ let BuildSection = (props) => {
"_pinswg_appellant_value" "_pinswg_appellant_value"
]; ];
console.log("on save:", valuesObj); //console.log("on save:", valuesObj);
updateCaseProgress( updateCaseProgress(
valuesObj, valuesObj,
false, false,
@@ -593,10 +593,10 @@ let BuildSection = (props) => {
props.props.form[props.form] props.props.form[props.form]
.values || {}; .values || {};
console.log( // console.log(
"valuesobj:", // "valuesobj:",
valuesObj // valuesObj
); // );
delete valuesObj[ delete valuesObj[
"_pinswg_appellant_value" "_pinswg_appellant_value"