uat fixes

This commit is contained in:
2024-11-27 11:00:12 +00:00
parent 630ed8d32b
commit 85f323d580
16 changed files with 284 additions and 137 deletions
+1 -1
View File
@@ -309,7 +309,7 @@ let PersonalDetails = (props) => {
name="telephone1"
id="telephone1"
component={RenderTextfield}
type="number"
type="text"
className="govuk-input govuk-input--width-20"
validate={[required, phoneNumber]}
label={t("account:account-telephone-label")}
@@ -30,7 +30,7 @@ const PersonalDetailsComplete = (props) => {
<>
<p className="govuk-body">{t("account:account-complete-para-1")}</p>
<p className="govuk-body">{t("account:account-complete-para-2")}</p>
{/* <p className="govuk-body">{t("account:account-complete-para-2")}</p> */}
<p className="govuk-body">
<Link
+1 -1
View File
@@ -190,7 +190,7 @@ const RegisterForm = (props) => {
name="telephone1"
id="telephone1"
component={RenderTextfield}
type="number"
type="text"
className="govuk-input govuk-input--width-20"
validate={[required, phoneNumber]}
label={t(
+154 -57
View File
@@ -70,7 +70,11 @@ const RenderTextfield = ({
: 100
: 200
}
// pattern={custom.hasOwnProperty("pattern") && custom.pattern}
pattern={
custom.hasOwnProperty("pattern")
? custom.pattern
: undefined
}
/>
</div>
</>
@@ -379,24 +383,40 @@ export const RenderRichMultiline = ({
return (
<>
<label className="govuk-label" htmlFor={name}>
{label}
</label>
<ReactQuill
modules={modules}
theme="snow"
value={editValue}
onChange={changeEdit}
/>
<textarea
{...input}
id={id}
name={name}
rows={rows}
className={className}
value={editValue}
style={{ display: "none" }}
></textarea>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label" htmlFor={name}>
{label}
</label>
{error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{error}
</span>
)}
<ReactQuill
modules={modules}
theme="snow"
value={editValue}
onChange={changeEdit}
/>
<textarea
{...input}
id={id}
name={name}
rows={rows}
className={className}
value={editValue}
style={{ display: "none" }}
></textarea>
</div>
</>
);
};
@@ -503,6 +523,7 @@ const RenderDatePicker = ({
}) => {
const router = useRouter();
let { t } = useTranslation();
var startDateArr =
custom.dateStart != "0" ? custom.dateStart.split("") : custom.dateStart;
var endDateArr =
@@ -560,6 +581,9 @@ const RenderDatePicker = ({
>
{FieldsTranslations(label)}
</label>
{custom.hint != false && (
<div className="govuk-hint">{t(custom.hint)}</div>
)}
</legend>
{touched && error && (
<span
@@ -637,6 +661,7 @@ export function DateFieldPicker(props) {
errorMsg="Select a date"
dateStart={dateStart}
dateEnd={dateEnd}
hint={props.hint}
/>
)
) : (
@@ -649,6 +674,7 @@ export function DateFieldPicker(props) {
errorMsg="Select a date"
dateStart={dateStart}
dateEnd={dateEnd}
hint={props.hint}
/>
)}
</div>
@@ -1230,7 +1256,7 @@ const RenderPickList = ({
dropdownObj = dropdownObj[0];
const required = (value) => {
return value || value == 0 ? undefined : "Requirewwwd";
return value || value == 0 ? undefined : "Is required";
};
return (
@@ -1251,13 +1277,10 @@ const RenderPickList = ({
{error}
</span>
)}
<select
{...input}
className="govuk-select "
id={label}
name={label}
>
<option>{t("newappeal:select-default")}</option>
<select {...input} className="govuk-select " id={id} name={id}>
<option value="" disabled defaultValue>
{t("newappeal:select-default")}
</option>
{Object.keys(dropdownObj).map((key, index) => {
return (
<option key={key} value={dropdownObj[key].Value}>
@@ -1311,7 +1334,7 @@ export function NumericField(props) {
};
const isNumber = (value) => {
const regex = /^\d*\.?\d{0,1}$/;
return regex.test(value) ? undefined : "Should be a number or decimal";
return regex.test(value) ? undefined : "Should be a number";
};
const maxLength = (max) => (value) =>
@@ -1358,35 +1381,40 @@ export function NumericField(props) {
) : (
<div className="govuk-form-group">
<Field
name={props.name}
id={props.name}
type="number"
className="govuk-input govuk-input--width-20 wwwww"
spellCheck="false"
aria-describedby={name}
pattern="[0-9]*"
inputMode="numeric"
parse={Number}
validate={[required]}
component={RenderTextfield}
label={label}
normalize={(value) => parseInt(value)}
// name={props.name}
// id={props.name}
// // component="input"
// type="text"
// className="govuk-input govuk-input--width-20 wwww"
// className="govuk-input govuk-input--width-20 wwwww"
// aria-describedby={name}
// pattern="^\d*(\.\d{0,2})?$"
// //pattern="^\d*\.?\d+$"
// pattern="[0-9]*"
// // inputMode="numeric"
// // parse={Number}
// validate={[
// required,
// isNumber,
// // isNumber,
// maxLength(props.maxFieldLength),
// ]}
// component={RenderTextfield}
// label={props.label}
// label={label}
// // normalize={(value) => parseInt(value)}
// maxFieldLength={props.maxFieldLength}
name={props.name}
id={props.name}
type="text"
className="govuk-input govuk-input--width-10"
aria-describedby={name}
//pattern="^\d*\.?\d+$"
pattern="[0-9]*"
validate={[
required,
isNumber,
maxLength(props.maxFieldLength),
]}
component={RenderTextfield}
label={props.label}
maxFieldLength={props.maxFieldLength}
/>
</div>
)}
@@ -1460,21 +1488,18 @@ export function DecimalField(props) {
name={props.name}
id={props.name}
// component="input"
type="number"
type="text"
className="govuk-input govuk-input--width-10"
spellCheck="false"
aria-describedby={name}
pattern="^\d*(\.\d{0,2})?$"
inputMode="numeric"
parse={Number}
validate={[
required,
isNumber,
maxLength(props.maxFieldLength),
]}
component={RenderTextfield}
pattern="^\d*\.?\d+$"
// inputMode="numeric"
// parse={Number}
validate={validateDecimal}
component={RenderDecimalField}
label={props.label}
maxFieldLength={props.maxFieldLength}
// normalize={normalizeDecimal} // Normalizing input as float
/>
</div>
)}
@@ -1482,6 +1507,78 @@ export function DecimalField(props) {
);
}
const normalizeDecimal = (value) => {
return value ? parseFloat(value) : value;
};
const validateDecimal = (value) => {
if (!value) return "This field is required";
// Regex to match whole numbers or decimal numbers (up to 7 characters including decimal)
const regex = /^\d{1,6}(\.\d{1,2})?$/; // Up to 6 digits before the decimal, 2 after
// Check if the value matches the regex pattern
if (!regex.test(value)) {
return "Invalid number (max 7 characters, 2 decimal places)";
}
return undefined;
};
const RenderDecimalField = ({
name,
id,
label,
datafieldname,
className,
input,
errorMsg,
meta: { touched, error },
...custom
}) => {
// <div>
// <label>{label}</label>
// <input {...input} type="text" />
// {touched && error && <span>{error}</span>}
// </div>;
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{FieldsTranslations(label)}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{error}
</span>
)}
<input
{...input}
// type={custom.type}
className={className}
name={name}
id={id}
maxLength={
custom.hasOwnProperty("maxFieldLength")
? custom.maxFieldLength
? custom.maxFieldLength
: 100
: 200
}
/>
</div>
</>
);
};
const RenderCaseID = {};
export function ReadOnlyfield(props) {
+2 -2
View File
@@ -611,7 +611,7 @@ let AboutYou = (props) => {
name={"pinswg_appellantphonenumber"}
id={"pinswg_appellantphonenumber"}
component={RenderTextfield}
type="number"
type="text"
className="govuk-input govuk-input--width-20"
validate={[required, phoneNumber]}
label={t(
@@ -794,7 +794,7 @@ let AboutYou = (props) => {
name={"pinswg_agentphonenumber"}
id={"pinswg_agentphonenumber"}
component={RenderTextfield}
type="number"
type="text"
className="govuk-input govuk-input--width-20"
validate={[required, phoneNumber]}
label={t(
+22 -20
View File
@@ -130,27 +130,29 @@ let BuildCheckSection = (props) => {
};
const finaliseAppeal = async () => {
setFinaliseAppealProcess(true);
//console.log("finalising appeal:");
await generateAppealPDF(
pdfObj,
props.props.accountDetails.containerID,
props.appealType.caseReference.ticketnumber,
router.query.appealtypes,
pdfObj.filesList
// props.appealType.fileList
)
.then((data) => {
console.log("have generated pdf:", data);
sendCaseCompleteMessage(
props.props.accountDetails.containerID,
props.appealType.caseReference.ticketnumber
);
})
.then(() => {
//console.log("have sent complete message :");
setCurrentSection(9999);
});
confirmSections
? (setFinaliseAppealProcess(true),
await generateAppealPDF(
pdfObj,
props.props.accountDetails.containerID,
props.appealType.caseReference.ticketnumber,
router.query.appealtypes,
pdfObj.filesList
// props.appealType.fileList
)
.then((data) => {
console.log("have generated pdf:", data);
sendCaseCompleteMessage(
props.props.accountDetails.containerID,
props.appealType.caseReference.ticketnumber
);
})
.then(() => {
//console.log("have sent complete message :");
setCurrentSection(9999);
}))
: setConfirmSections(false);
};
return (
+1
View File
@@ -129,6 +129,7 @@ export default function BuildField(props) {
validation={props.validation}
dateStart={props.dateStart}
dateEnd={props.dateEnd}
hint={props.hint}
/>
);
break;
+87 -40
View File
@@ -313,6 +313,26 @@ let BuildSection = (props) => {
// Object.assign(values, { "filesList": buildAppealFilesArray });
// Function to parse a specific key (e.g., 'price') in an array of objects
const parseFloatForKeyInObject = (obj, key) => {
// Check if the object has the key and the value can be parsed as a float
if (
obj.hasOwnProperty(key) &&
typeof obj[key] === "string" &&
!isNaN(obj[key].trim())
) {
// Parse the value as a float and update the object
return { ...obj, [key]: parseFloat(obj[key]) };
}
// If the key doesn't exist or value can't be parsed, return the original object
return obj;
};
valuesObj = parseFloatForKeyInObject(
valuesObj,
"pinswg_areaofsiteinhectaresdec"
);
delete valuesObj["_pinswg_appellant_value"];
//console.log("has errors:", props.invalid);
props.invalid == false && updateCaseProgress(valuesObj, false, false);
@@ -440,53 +460,56 @@ let BuildSection = (props) => {
false,
false
);
// currentSection == 1 &&
// setCurrentSection(1);
}}
>
{t("common:continue-button")}
</button>
{savingStatus ? (
<span className=" progress-save-active">
{router.locale == "cy"
? "Nôl data"
: "Saving data"}
<img
className="data-loading-icon"
src="/assets/images/loading.gif"
alt={
router.locale == "cy"
? "Nôl data"
: "Saving data"
}
/>
</span>
) : (
<button
className="govuk-button progress-save "
onClick={() => {
let valuesObj =
props.props.form[props.form]
.values || {};
{currentSection > 1 &&
(savingStatus ? (
<span className=" progress-save-active">
{router.locale == "cy"
? "Nôl data"
: "Saving data"}
<img
className="data-loading-icon"
src="/assets/images/loading.gif"
alt={
router.locale == "cy"
? "Nôl data"
: "Saving data"
}
/>
</span>
) : (
<button
className="govuk-button progress-save "
onClick={() => {
let valuesObj =
props.props.form[props.form]
.values || {};
// console.log(
// "valuesobj:",
// valuesObj
// );
// console.log(
// "valuesobj:",
// valuesObj
// );
delete valuesObj[
"_pinswg_appellant_value"
];
delete valuesObj[
"_pinswg_appellant_value"
];
// console.log("on save:", valuesObj);
updateCaseProgress(
valuesObj,
true,
true
);
}}
>
{t("common:save-exit-button")}
</button>
)}
// console.log("on save:", valuesObj);
updateCaseProgress(
valuesObj,
true,
true
);
}}
>
{t("common:save-exit-button")}
</button>
))}
{/* <span
onClick={() =>
setCurrentSection(sectionCount + 1)
@@ -669,6 +692,29 @@ const mapDispatchToProps = (dispatch) => {
const selector = formValueSelector("appealForm"); // <-- same as form name
const validate = (values) => {
const errors = {};
const strippedHtml = (htmlStr) => {
return htmlStr.replace(/(<([^>]+)>)/gi, "").trim();
};
if (values.hasOwnProperty("pinswg_attachsoc")) {
if (values.pinswg_attachsoc == "false") {
if (values.hasOwnProperty("pinswg_statementofcase")) {
if (strippedHtml(values.pinswg_statementofcase).length == 0)
errors.pinswg_statementofcase =
"Enter submit a statement of case or select Yes to attach a separate Statement of Case Document";
} else {
errors.pinswg_statementofcase =
"Enter submit a statement of case or select Yes to attach a separate Statement of Case Document";
}
}
}
return errors;
};
export default connect(
mapStateToProps,
mapDispatchToProps
@@ -677,5 +723,6 @@ export default connect(
form: "appealForm",
destroyOnUnmount: false,
enableReinitialize: true, // this is needed!!
validate,
})(BuildSection)
);
+1 -1
View File
@@ -2225,7 +2225,7 @@
"value_cy": "A yw'n hanfodol i'r Arolygydd fynd i mewn i'r safle i wirio mesuriadau neu ffeithiau perthnasol eraill?"
},
{
"value": "Please explain why the inspector needs to enter the site",
"value": "Please explain why the Inspector needs to enter the site",
"value_cy": "Eglurwch pam fod angen i'r arolygydd fynd i mewn i'r safle"
},
{
+1 -1
View File
@@ -203,7 +203,7 @@
</row>
<row>
<labels>
<label description="Please explain why the inspector needs to enter the site" />
<label description="Please explain why the Inspector needs to enter the site" />
</labels>
<control id="pinswg_whyisinspectorneededonsite" parentField="pinswg_inspectorneededonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_whyisinspectorneededonsite" maxFieldLength="800" disabled="false" />
</row>
@@ -795,7 +795,7 @@
</row>
<row>
<labels>
<label description="Please explain why the inspector needs to enter the site" />
<label description="Please explain why the Inspector needs to enter the site" />
</labels>
<control id="pinswg_whyisinspectorneededonsite" parentField="pinswg_inspectorneededonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_whyisinspectorneededonsite" maxFieldLength="800" disabled="false" />
</row>
+1 -1
View File
@@ -208,7 +208,7 @@
</row>
<row>
<labels>
<label description="Please explain why the inspector needs to enter the site" hint="newappeal:new-appeal-inspector-onsite-paragraph" />
<label description="Please explain why the Inspector needs to enter the site" hint="newappeal:new-appeal-inspector-onsite-paragraph" />
</labels>
<control id="pinswg_whyisinspectorneededonsite" parentField="pinswg_inspectorneededonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_whyisinspectorneededonsite" maxFieldLength="800" disabled="false" />
</row>
@@ -170,7 +170,7 @@
</row>
<row>
<labels>
<label description="Please explain why the inspector needs to enter the site" />
<label description="Please explain why the Inspector needs to enter the site" />
</labels>
<control id="pinswg_whyisinspectorneededonsite" parentField="pinswg_inspectorneededonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_whyisinspectorneededonsite" maxFieldLength="800" disabled="false" />
</row>
+8 -8
View File
@@ -56,7 +56,7 @@
</row>
<row>
<labels>
<label description="Application form dated" />
<label description="Application form dated" hint="newappeal:new-appeal-dateofapplication-hint" />
</labels>
<control validation="[required]" id="pinswg_dateofapplication" classid="{5B773807-9FB2-42db-97C3-7A91EFF8ADFF}" datafieldname="pinswg_dateofapplication" dateStart="-5y" dateEnd="0" disabled="false" />
</row>
@@ -106,13 +106,13 @@
<labels>
<label description="Size of overall appeal site (in hectares)" />
</labels>
<control validation="[required]" id="pinswg_areaofsiteinhectaresdec" classid="{C3EFE0C3-0EC6-42be-8349-CBD9079DFD8E}" datafieldname="pinswg_areaofsiteinhectaresdec" maxFieldLength="4" disabled="false" />
<control validation="[required]" id="pinswg_areaofsiteinhectaresdec" classid="{C3EFE0C3-0EC6-42be-8349-CBD9079DFD8E}" datafieldname="pinswg_areaofsiteinhectaresdec" maxFieldLength="7" disabled="false" />
</row>
<row>
<labels>
<label description="What is the area of floor space proposed (in square metres)? If no new floor space enter 0." />
</labels>
<control validation="[required]" id="pinswg_floorspaceinsquaremeters" classid="{C6D124CA-7EDA-4a60-AEA9-7FB8D318B68F}" datafieldname="pinswg_floorspaceinsquaremeters" maxFieldLength="5" disabled="false" />
<control validation="[required]" id="pinswg_floorspaceinsquaremeters" classid="{C6D124CA-7EDA-4a60-AEA9-7FB8D318B68F}" datafieldname="pinswg_floorspaceinsquaremeters" maxFieldLength="7" disabled="false" />
</row>
</rows>
</section>
@@ -202,9 +202,9 @@
</row>
<row>
<labels>
<label description="Please explain why the inspector needs to enter the site" hint="newappeal:new-appeal-inspector-onsite-paragraph" />
<label description="Please explain why the Inspector needs to enter the site" hint="newappeal:new-appeal-inspector-onsite-paragraph" />
</labels>
<control id="pinswg_whyisinspectorneededonsite" parentField="pinswg_inspectorneededonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_whyisinspectorneededonsite" maxFieldLength="800" disabled="false" />
<control validation="[required]" id="pinswg_whyisinspectorneededonsite" parentField="pinswg_inspectorneededonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_whyisinspectorneededonsite" maxFieldLength="800" disabled="false" />
</row>
<row>
<labels>
@@ -216,7 +216,7 @@
<labels>
<label description="Please set out the potential health and safety issues" />
</labels>
<control id="pinswg_outlinehealthandsafetyissuesonsite" parentField="pinswg_healthandsafetyissuesonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_outlinehealthandsafetyissuesonsite" maxFieldLength="800" disabled="false" />
<control validation="[required]" id="pinswg_outlinehealthandsafetyissuesonsite" parentField="pinswg_healthandsafetyissuesonsite" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_outlinehealthandsafetyissuesonsite" maxFieldLength="800" disabled="false" />
</row>
</rows>
</section>
@@ -252,7 +252,7 @@
<labels>
<label description="Please provide details of the appeals including our reference number, if known" />
</labels>
<control id="pinswg_additionalappealsmadedetails" parentField="pinswg_additionalappealsmade" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_additionalappealsmadedetails" maxFieldLength="800" disabled="false" />
<control validation="[required]" id="pinswg_additionalappealsmadedetails" parentField="pinswg_additionalappealsmade" parentFieldShowOnValue="true" classid="{E0DECE4B-6FC8-4a8f-A065-082708572369}" datafieldname="pinswg_additionalappealsmadedetails" maxFieldLength="800" disabled="false" />
</row>
</rows>
</section>
@@ -282,7 +282,7 @@
<labels>
<label description="Please submit your statement of case" hint="newappeal:new-appeal-submission-of-case-hint" />
</labels>
<control validation="[required]" id="pinswg_statementofcase" classid="{E0DECE4B-6666-4a8f-A065-082708572369}" datafieldname="pinswg_statementofcase" maxFieldLength="5000" disabled="false" />
<control id="pinswg_statementofcase" classid="{E0DECE4B-6666-4a8f-A065-082708572369}" datafieldname="pinswg_statementofcase" maxFieldLength="5000" disabled="false" />
</row>
<row>
<labels>
+1 -1
View File
@@ -1,7 +1,7 @@
{
"login-card-title-temp": "Apeliadau neu geisiadau newydd",
"login-comingsoon-temp-1": "Mae'r gwasanaeth hwn yn cael ei ddatblygu i gefnogi apeliadau a cheisiadau ar-lein.",
"login-comingsoon-temp-1a": "Ar hyn o bryd gallwch godi Apeliadau Cynllunio a78, Caniatâd Adeilad Rhestredig ac Ardal Gadwraeth, Apeliadau Deiliaid Tai a Mân Apeliadau Masnachol - HAS/CAS, Hysbysebion ac apeliadau Dilysu.",
"login-comingsoon-temp-1a": "Ar hyn o bryd gallwch godi Apeliadau Cynllunio a78.",
"login-comingsoon-temp-2": "Wrth i ni ddatblygur gwasanaeth ar-lein, dewch o hyd i:",
"login-comingsoon-forms-link-1": "https://llyw.cymru/ffurflenni-apelio",
"login-comingsoon-forms-label-1": "ffurflenni apêl cynllunio a ffurflenni cais cynllunio",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"login-card-title-temp": "New appeals or applications",
"login-comingsoon-temp-1": "This service is being developed to support online appeals and applications.",
"login-comingsoon-temp-1a": "You can currently raise Planning Appeals s78, Listed Building and Conservation Area Consent, Householder and Minor Commercial Appeals - HAS/CAS, Adverts and Non-Validation appeals.",
"login-comingsoon-temp-1a": "You can currently raise Planning Appeals s78.",
"login-comingsoon-temp-2": "While we develop the online service, find:",
"login-comingsoon-forms-link-1": "https://gov.wales/planning-appeal-forms",
"login-comingsoon-forms-label-1": "planning appeal and application forms",