Merged PR 380: added validation and updated git ignore

Related work items: #5210, #5242
This commit is contained in:
Robert Bond
2021-07-23 13:34:23 +00:00
15 changed files with 668 additions and 329 deletions
+18 -2
View File
@@ -1,3 +1,19 @@
node_modules // .gitignore
# next.js build output
.next .next
package-lock.json
# dotenv environment variables file - set in pipeline as environment variables
.env
.env.build
# Dependency directories
node_modules/
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
#lock files
yarn.lock
package-lock.json
+16
View File
@@ -72,6 +72,22 @@ const Breadcrumbs = (props) => {
) : ( ) : (
"" ""
)} )}
{router.pathname == "/searchresults" ? (
<>
<li className="govuk-breadcrumbs__list-item">
<Link href="/myportal">
<a className="govuk-breadcrumbs__link">
My Portal
</a>
</Link>
</li>
<li className="govuk-breadcrumbs__list-item">
Search results
</li>
</>
) : (
""
)}
{router.pathname == "/newappeal" ? ( {router.pathname == "/newappeal" ? (
<> <>
<li className="govuk-breadcrumbs__list-item"> <li className="govuk-breadcrumbs__list-item">
+214 -89
View File
@@ -6,25 +6,77 @@ import React, { useState } from "react";
import "react-datepicker/dist/react-datepicker.css"; import "react-datepicker/dist/react-datepicker.css";
import moment from "moment"; import moment from "moment";
const RenderTextfield = ({
id,
className,
rows,
datafieldname,
name,
label,
input,
errorMsg,
meta: { touched, error },
...custom
}) => {
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<label className="govuk-label " htmlFor={id} id={id + "_label"}>
{label}
</label>
{touched && error && (
<span id={id + "-error"} className="govuk-error-message">
<span className="govuk-visually-hidden">Error:</span>{" "}
{errorMsg}
</span>
)}
<input {...input} className={className} name={name} id={id} />
</div>
</>
);
};
export function Textfield(props) { export function Textfield(props) {
const { name, label } = props; const { name, label } = props;
const required = (value) => (value ? undefined : "Required");
return ( return (
<div className="govuk-form-group"> <Field
<label className="govuk-label " htmlFor="event-name"> name={props.name}
{props.label} id={props.name}
</label> component={RenderTextfield}
<Field type="text"
name={props.name} className="govuk-input govuk-input--width-20"
id={props.name} validate={[required]}
component="input" label={props.label}
type="text" errorMsg="Is required"
className="govuk-input govuk-input--width-20" />
/>
</div>
); );
} }
const RenderMultiline = ({
className,
rows,
datafieldname,
name,
label,
input,
meta: { touched, error },
...custom
}) => {
return (
<>
<textarea {...input} rows={rows} className={className}></textarea>
</>
);
};
export function MultiLinefield(props) { export function MultiLinefield(props) {
const { name, label } = props; const { name, label } = props;
@@ -42,13 +94,14 @@ export function MultiLinefield(props) {
Do not include personal or financial information, like your Do not include personal or financial information, like your
National Insurance number or credit card details. National Insurance number or credit card details.
</div> </div>
<Field <Field
name={props.name} name={props.name}
id={props.name} id={props.name}
component="input" component={RenderMultiline}
type="text" type="text"
rows="5" rows="5"
className="govuk-textarea govuk-input--width-20" className="govuk-textarea govuk-input--width-30"
aria-describedby="more-detail-hint" aria-describedby="more-detail-hint"
/> />
</div> </div>
@@ -59,48 +112,73 @@ const RenderDatePicker = ({
datafieldname, datafieldname,
name, name,
label, label,
id,
errorMsg,
input: { onChange, value }, input: { onChange, value },
meta: { touched, error }, meta: { touched, error },
...custom ...custom
}) => { }) => {
return ( return (
<> <>
<DatePicker <div
{...custom} className={
autoOk={true} touched && error
dateFormat="dd/MM/yyyy" ? "govuk-form-group govuk-form-group--error"
onChange={onChange} : "govuk-form-group "
selected={value || null} }
>
<fieldset
className="govuk-fieldset"
role="group"
aria-describedby="dob-hint"
>
<legend className="govuk-fieldset__legend govuk-fieldset__legend--s govuk-!-font-weight-regular">
<label
className="govuk-fieldset__heading"
id={id + "_label"}
>
{label}
</label>
</legend>
{touched && error && (
<span
id={id + "-error"}
className="govuk-error-message"
>
<span className="govuk-visually-hidden">
Error:
</span>{" "}
{errorMsg}
</span>
)}
<DatePicker
{...custom}
autoOk={true}
dateFormat="dd/MM/yyyy"
onChange={onChange}
selected={value || null}
// value={!value ? null : new Date(value)} // value={!value ? null : new Date(value)}
/> />
</fieldset>
{touched && error && <span>{error}</span>} </div>
</> </>
); );
}; };
export function DateFieldPicker(props) { export function DateFieldPicker(props) {
const { name, label } = props; const { name, label } = props;
const required = (value) => (value ? undefined : "Required");
return ( return (
<div className="govuk-form-group"> <Field
<fieldset name={name}
className="govuk-fieldset" id={name}
role="group" label={label}
aria-describedby="dob-hint" component={RenderDatePicker}
> //validate={[required]}
<legend className="govuk-fieldset__legend govuk-fieldset__legend--s govuk-!-font-weight-regular"> errorMsg="Select a date"
<label className="govuk-fieldset__heading"> />
{props.label}
</label>
</legend>
<Field
name={props.name}
id={props.name}
component={RenderDatePicker}
/>
</fieldset>
</div>
); );
} }
@@ -183,47 +261,96 @@ export function DateField(props) {
); );
} }
const RenderYesNo = ({
datafieldname,
name,
label,
id,
errorMsg,
options,
input: { onChange, value },
meta: { touched, error },
...custom
}) => {
return (
<>
<div
className={
touched && error
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<fieldset
className="govuk-fieldset"
aria-describedby={name + "-hint"}
>
<legend className="govuk-fieldset__legend govuk-fieldset__legend--s govuk-!-font-weight-regular">
<label
className="govuk-fieldset__heading govuk-body-m"
id={id + "_label"}
>
{label}
</label>
</legend>
{touched && error && (
<span
id={id + "-error"}
className="govuk-error-message"
>
<span className="govuk-visually-hidden">
Error:
</span>{" "}
{errorMsg}
</span>
)}
<div className="govuk-radios govuk-radios--inline govuk-radios--small">
{Object.keys(options).map((key, index) => (
<div
className="govuk-radios__item"
data-children-count={key}
key={key}
>
<Field
id={id + "_" + index}
name={id}
component="input"
type="radio"
className="govuk-radios__input"
value={options[key]}
/>
<label
className="govuk-label govuk-radios__label"
htmlFor={id + "_" + index}
>
{options[key]}
</label>
</div>
))}
</div>
</fieldset>
</div>
</>
);
};
export function YesNofield(props) { export function YesNofield(props) {
const { name, label } = props; const { name, label } = props;
const yesNo = ["Yes", "No"]; const yesNo = ["Yes", "No"];
return ( const required = (value) => (value ? undefined : "Required");
<div className="govuk-form-group">
<fieldset
className="govuk-fieldset"
aria-describedby={props.name + "-hint"}
>
<legend className="govuk-fieldset__legend govuk-fieldset__legend--s govuk-!-font-weight-regular">
<label className="govuk-fieldset__heading govuk-body-m">
{props.label}
</label>
</legend>
<div className="govuk-radios govuk-radios--inline govuk-radios--small"> return (
{Object.keys(yesNo).map((key, index) => ( <Field
<div name={props.name}
className="govuk-radios__item" datafieldname={props.name}
data-children-count={key} label={props.label}
key={key} options={yesNo}
> id={props.name}
<Field className="govuk-radios__input"
id={props.name + "_" + index} //validate={[required]}
name={props.name} errorMsg="Select and option"
component="input" component={RenderYesNo}
type="radio" />
className="govuk-radios__input"
value={yesNo[key]}
/>
<label
className="govuk-label govuk-radios__label"
htmlFor={props.name + "_" + index}
>
{yesNo[key]}
</label>
</div>
))}
</div>
</fieldset>
</div>
); );
} }
@@ -232,18 +359,15 @@ const RenderPickList = ({
name, name,
label, label,
input, input,
meta: { touched, error }, meta: { touched, errorStr },
}) => { }) => {
const fetcher = (url) => fetch(url).then((res) => res.json()); const fetcher = (url) => fetch(url).then((res) => res.json());
const { data, errorStr } = useSWR("/api/lookups/" + datafieldname, fetcher); const { data, error } = useSWR("/api/lookups/" + datafieldname, fetcher);
if (errorStr) if (error)
return ( return (
<div className="govuk-form-group"> <div className="govuk-form-group">
<label <label className="govuk-label govuk-body-m" htmlFor={name}>
className="govuk-label govuk-body-m"
htmlFor={props.name}
>
{label} {label}
</label> </label>
<select className="govuk-select" id={name} name={name}> <select className="govuk-select" id={name} name={name}>
@@ -257,9 +381,10 @@ const RenderPickList = ({
<div className="govuk-form-group">{label} loading...</div> <div className="govuk-form-group">{label} loading...</div>
</div> </div>
); );
console.log(JSON.stringify(data.GlobalOptionSet.Options)); //console.log(JSON.stringify(data.GlobalOptionSet.Options));
const dropdownObj = data.GlobalOptionSet.Options; const dropdownObj = data.GlobalOptionSet.Options;
return ( return (
<div> <div>
<select {...input} className="govuk-select" id={name} name={name}> <select {...input} className="govuk-select" id={name} name={name}>
@@ -279,7 +404,7 @@ const RenderPickList = ({
})} })}
</select> </select>
{touched && error && <span>{error}</span>} {touched && errorStr && <span>{errorStr}</span>}
</div> </div>
); );
}; };
@@ -351,7 +476,7 @@ const RenderCaseID = {};
export function ReadOnlyfield(props) { export function ReadOnlyfield(props) {
const { name, label, value } = props; const { name, label, value } = props;
console.log(props.value.refno); //console.log(props.value.refno);
return ( return (
<div className="govuk-form-group"> <div className="govuk-form-group">
<label className="govuk-label " htmlFor={props.name}> <label className="govuk-label " htmlFor={props.name}>
+10 -9
View File
@@ -61,16 +61,17 @@ export default function Header({ courseName }) {
</div> </div>
<div className="govuk-header__content govuk-!-width-two-thirds govuk-!-margin-top-3"> <div className="govuk-header__content govuk-!-width-two-thirds govuk-!-margin-top-3">
<a <Link href="/">
href="/" <a
onClick={() => { onClick={() => {
window.localStorage.clear(); window.localStorage.clear();
}} }}
className="govuk-header__link className="govuk-header__link
govuk-header__link--service-name" govuk-header__link--service-name"
> >
{t("common:service-name")} {t("common:service-name")}
</a> </a>
</Link>
</div> </div>
<div className="languageSwitch"> <div className="languageSwitch">
{router.path} {router.path}
+36 -12
View File
@@ -9,17 +9,24 @@ export default function CaseSearch() {
const router = useRouter(); const router = useRouter();
const { locale } = router; const { locale } = router;
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const [validationError, setValidationError] = useState("");
const handleParam = (setValue) => (e) => setValue(e.target.value); const handleParam = (setValue) => (e) => setValue(e.target.value);
const basicSearch = (event) => { const basicSearch = (event) => {
event.preventDefault(); event.preventDefault();
console.log(query);
// /searchresults
router.push({ if (query == "" || query == null) {
pathname: "/searchresults", setValidationError(true);
query: { q: query }, } else {
}); setValidationError(false);
console.log(query);
// /searchresults
router.push({
pathname: "/searchresults",
query: { q: query },
});
}
}; };
return ( return (
@@ -29,8 +36,14 @@ export default function CaseSearch() {
<h3 className="heading-small card-heading"> <h3 className="heading-small card-heading">
{t("home:casesearch-card-title")} {t("home:casesearch-card-title")}
</h3> </h3>
<div className="govuk-form-group"> <div
<div id="event-name-hint" className="govuk-hint "> className={
validationError
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<div id="basicSearch-hint" className="govuk-hint ">
{t("home:casesearch-card-search-hint")}: {t("home:casesearch-card-search-hint")}:
<br /> <br />
<span className="govuk-body-s"> <span className="govuk-body-s">
@@ -41,15 +54,26 @@ export default function CaseSearch() {
)} )}
: :
</span>{" "} </span>{" "}
APP/A1234/A/99/1234567 CAS-00009-W8N6W4
</span> </span>
</div> </div>
{validationError && (
<span
id="basicSearch-error"
className="govuk-error-message"
>
<span className="govuk-visually-hidden">
Error:
</span>{" "}
Case reference is required
</span>
)}
<input <input
className="govuk-input" className="govuk-input"
id="event-name" id="basicSearch"
name="event-name" name="basicSearch"
type="text" type="text"
aria-describedby="event-name-hint" aria-describedby="basicSearch-hint"
onChange={handleParam(setQuery)} onChange={handleParam(setQuery)}
/> />
</div> </div>
+32 -8
View File
@@ -9,17 +9,24 @@ export default function SearchCases() {
const router = useRouter(); const router = useRouter();
const { locale } = router; const { locale } = router;
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
const [validationError, setValidationError] = useState("");
const handleParam = (setValue) => (e) => setValue(e.target.value); const handleParam = (setValue) => (e) => setValue(e.target.value);
const basicSearch = (event) => { const basicSearch = (event) => {
event.preventDefault(); event.preventDefault();
console.log(query);
// /searchresults
router.push({ if (query == "" || query == null) {
pathname: "/searchresults", setValidationError(true);
query: { q: query }, } else {
}); setValidationError(false);
console.log(query);
// /searchresults
router.push({
pathname: "/searchresults",
query: { q: query },
});
}
}; };
return ( return (
@@ -29,7 +36,13 @@ export default function SearchCases() {
<h3 className="heading-small card-heading"> <h3 className="heading-small card-heading">
{t("myportal:searchcases-card-title")} {t("myportal:searchcases-card-title")}
</h3> </h3>
<div className="govuk-form-group"> <div
className={
validationError
? "govuk-form-group govuk-form-group--error"
: "govuk-form-group "
}
>
<div id="event-name-hint" className="govuk-hint "> <div id="event-name-hint" className="govuk-hint ">
{t("myportal:searchcases-card-search-hint")}: {t("myportal:searchcases-card-search-hint")}:
<br /> <br />
@@ -41,9 +54,20 @@ export default function SearchCases() {
)} )}
: :
</span>{" "} </span>{" "}
APP/A1234/A/99/1234567 CAS-00009-W8N6W4
</span> </span>
</div> </div>
{validationError && (
<span
id="basicSearch-error"
className="govuk-error-message"
>
<span className="govuk-visually-hidden">
Error:
</span>{" "}
Case reference is required
</span>
)}
<input <input
className="govuk-input" className="govuk-input"
id="event-name" id="event-name"
-2
View File
@@ -45,8 +45,6 @@ let BuildCheckRow = (props) => {
var fieldtype = xpath.select("//@classid", doc); var fieldtype = xpath.select("//@classid", doc);
var datafieldname = xpath.select("//@datafieldname", doc); var datafieldname = xpath.select("//@datafieldname", doc);
console.log(props.form);
return ( return (
<div className="govuk-summary-list__row" key={key}> <div className="govuk-summary-list__row" key={key}>
<dt className="govuk-summary-list__key"> <dt className="govuk-summary-list__key">
@@ -73,6 +73,7 @@ let BuildCheckSection = (props) => {
whichSection={parseInt(key) + 1} whichSection={parseInt(key) + 1}
sectionCount={key} sectionCount={key}
props={props} props={props}
key={key}
/> />
</dl> </dl>
</> </>
+1 -5
View File
@@ -97,10 +97,6 @@ export default function BuildField(props) {
}; };
return ( return (
<div className="govuk-grid-row"> <div className="govuk-grid-row">{whichFieldType(props.fieldType)}</div>
<div className="govuk-grid-column-full">
{whichFieldType(props.fieldType)}
</div>
</div>
); );
} }
+19 -21
View File
@@ -15,27 +15,25 @@ export default function BuildRow(props) {
const parser = new DOMParser(); const parser = new DOMParser();
return ( return (
<div className="govuk-grid-row"> <div className="govuk-grid-column-full">
<div className="govuk-grid-column-full"> {Object.keys(rowXML).map((key, index) => {
{Object.keys(rowXML).map((key, index) => { var doc = parser.parseFromString(
var doc = parser.parseFromString( rowXML[key].outerHTML,
rowXML[key].outerHTML, "text/xml"
"text/xml" );
); var rows = xpath.select("//label/@description", doc);
var rows = xpath.select("//label/@description", doc); var fieldtype = xpath.select("//@classid", doc);
var fieldtype = xpath.select("//@classid", doc); var datafieldname = xpath.select("//@datafieldname", doc);
var datafieldname = xpath.select("//@datafieldname", doc); return (
return ( <BuildField
<BuildField fieldType={fieldtype[0].value}
fieldType={fieldtype[0].value} label={rows[0].value}
label={rows[0].value} datafieldname={datafieldname[0].value}
datafieldname={datafieldname[0].value} key={key}
key={key} props={props}
props={props} />
/> );
); })}
})}
</div>
</div> </div>
); );
} }
+78 -5
View File
@@ -1,10 +1,11 @@
import Link from "next/link"; import Link from "next/link";
import _, { has } from "lodash";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import useTranslation from "next-translate/useTranslation"; import useTranslation from "next-translate/useTranslation";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import xpath from "xpath"; import xpath from "xpath";
import BuildRow from "./buildrow"; import BuildRow from "./buildrow";
import { reduxForm, formValueSelector } from "redux-form"; import { reduxForm, formValueSelector, getFormSubmitErrors } from "redux-form";
import { useDispatch, useSelector, shallowEqual, connect } from "react-redux"; import { useDispatch, useSelector, shallowEqual, connect } from "react-redux";
import { import {
setCaseReference, setCaseReference,
@@ -56,12 +57,73 @@ let BuildSection = (props) => {
const onHandleSubmit = (values) => { const onHandleSubmit = (values) => {
setCurrentSection(currentSection + 1); setCurrentSection(currentSection + 1);
setCaseReference(router.query.refno);
}; };
// const initialValues = { const [hasErrors, setHasErrors] = useState("");
// email: router.query.refno,
// }; const getErrors = () => {
let errorsobj = props.props.form["appealForm"];
setHasErrors(errorsobj.hasOwnProperty("syncErrors"));
window.scrollTo(0, 0);
};
let errorsobj = {};
const ShowErrorHeader = (props) => {
errorsobj = props.props.appealForm.syncErrors;
errorsobj = _.keys(errorsobj);
const getErrorLabel = (whichField) => {
var doc = parser.parseFromString(props.formXML, "text/xml");
var errorFieldLabel = xpath.select(
"//*[control/@id='" + whichField + "']//@description",
doc
);
return errorFieldLabel[0].value;
};
const ShowErrors = () => {
let errorList = [];
for (let i = 0; i < errorsobj.length; ++i) {
//get label from error key - search rowxml for id = errorobj
errorList.push(
<li>
<a href={"#" + errorsobj[i] + "_label"}>
{" "}
{getErrorLabel(errorsobj[i])}
</a>
</li>
);
}
return errorList;
};
return !_.isEmpty(errorsobj) ? (
<div
className="govuk-error-summary"
aria-labelledby="error-summary-title"
role="alert"
tabIndex="-1"
data-module="govuk-error-summary"
>
<h2
className="govuk-error-summary__title"
id="error-summary-title"
>
The following fields have a problem :
</h2>
<div className="govuk-error-summary__body">
<ul className="govuk-list govuk-error-summary__list">
<ShowErrors />
</ul>
</div>
</div>
) : (
""
);
};
return ( return (
<div className="govuk-grid-row"> <div className="govuk-grid-row">
@@ -70,6 +132,16 @@ let BuildSection = (props) => {
{titles[0].value}{" "} {titles[0].value}{" "}
</h1> </h1>
<form onSubmit={handleSubmit(onHandleSubmit)}> <form onSubmit={handleSubmit(onHandleSubmit)}>
{hasErrors == true ? (
<ShowErrorHeader
hasErrors={hasErrors}
props={props.props.form}
formXML={formXML}
/>
) : (
""
)}
<BuildRow <BuildRow
rowXML={rowXML} rowXML={rowXML}
whichSection={props.whichSection} whichSection={props.whichSection}
@@ -84,6 +156,7 @@ let BuildSection = (props) => {
type="submit" type="submit"
className="govuk-button" className="govuk-button"
data-module="govuk-button" data-module="govuk-button"
onClick={() => getErrors()}
> >
Continue Continue
</button> </button>
+147 -99
View File
@@ -15,8 +15,6 @@ import {
getAppealTypeObj, getAppealTypeObj,
} from "../../store/appealType/action"; } from "../../store/appealType/action";
import { createCase } from "../../actions";
let CreateCase = (props) => { let CreateCase = (props) => {
// useEffect(() => { // useEffect(() => {
// window.scrollTo(0, 0); // window.scrollTo(0, 0);
@@ -29,37 +27,85 @@ let CreateCase = (props) => {
const { LPAData, onSubmit, handleSubmit } = props; const { LPAData, onSubmit, handleSubmit } = props;
const appealOptionsObj = props.appealType.appealTypeOptions.GlobalOptionSet const appealOptionsObj = _.isEmpty(props)
.Options || [{}]; ? [{}]
: _.isEmpty(props.appealType)
? [{}]
: _.isEmpty(props.appealType.appealTypeOptions)
? [{}]
: _.isEmpty(props.appealType.appealTypeOptions.GlobalOptionSet)
? [{}]
: _.isEmpty(props.appealType.appealTypeOptions.GlobalOptionSet.Options)
? [{}]
: props.appealType.appealTypeOptions.GlobalOptionSet.Options;
let lpaOptionsObj = jsonpath.query(props.LPAData.LPAData, "$..name"); let lpaOptionsObj = _.isEmpty(props)
? [{}]
: _.isEmpty(props.LPAData)
? [{}]
: _.isEmpty(props.LPAData.LPAData)
? [{}]
: jsonpath.query(props.LPAData.LPAData, "$..name");
const RenderLPAList = ({ const RenderLPAList = ({
name, name,
input, input,
optionsObj, optionsObj,
meta: { touched, error }, meta: { touched, error },
label,
errorMsg,
}) => { }) => {
return ( return (
<div> <>
<select <div
{...input} className={
className="govuk-select" touched && error
id="lpatypes" ? "govuk-form-group govuk-form-group--error"
name={name} : "govuk-form-group "
//onChange={(e) => props.onChangeSelectLPA(e)} }
> >
<option>Select...</option> {" "}
{Object.keys(optionsObj).map((key, index) => { <label className="govuk-label" htmlFor="sort">
return ( {label}
<option key={key} value={optionsObj[key]}> </label>
{optionsObj[key]} {touched && error && (
<span
id="passport-issued-error"
className="govuk-error-message"
>
<span className="govuk-visually-hidden">
Error:
</span>{" "}
{errorMsg}
</span>
)}
<div>
<select
{...input}
className="govuk-select govuk-input--error"
id="lpatypes"
name={name}
//onChange={(e) => props.onChangeSelectLPA(e)}
>
<option value="" disabled defaultValue>
Select...
</option> </option>
); {_.isEmpty(optionsObj)
})} ? ""
</select> : Object.keys(optionsObj).map((key, index) => {
{touched && error && <span>{error}</span>} return (
</div> <option
key={key}
value={optionsObj[key]}
>
{optionsObj[key]}
</option>
);
})}
</select>
</div>
</div>
</>
); );
}; };
@@ -68,97 +114,99 @@ let CreateCase = (props) => {
input, input,
optionsObj, optionsObj,
meta: { touched, error }, meta: { touched, error },
label,
errorMsg,
}) => { }) => {
return ( return (
<div> <>
<select <div
{...input} className={
className="govuk-select" touched && error
id="appealTypes" ? "govuk-form-group govuk-form-group--error"
name={name} : "govuk-form-group "
//onChange={(e) => props.onChangeSelectAppealType(e)} }
> >
<option>Select...</option> <label className="govuk-label" htmlFor="sort">
{Object.keys(optionsObj).map((key, index) => { {label}
return ( </label>
<option {touched && error && (
key={key} <span
value={optionsObj[ id="passport-issued-error"
key className="govuk-error-message"
].Label.LocalizedLabels[0].Label.replace( >
/[\s\-\+\(\)\,]/g, <span className="govuk-visually-hidden">
"" Error:
).toLowerCase()} </span>{" "}
> {errorMsg}
{optionsObj[key].Label.LocalizedLabels[0].Label} </span>
)}
<div>
<select
{...input}
className="govuk-select"
id="appealTypes"
name={name}
//onChange={(e) => props.onChangeSelectAppealType(e)}
>
<option value="" disabled defaultValue>
Select...
</option> </option>
); {_.isEmpty(optionsObj)
})} ? ""
</select> : Object.keys(optionsObj).map((key, index) => {
{touched && error && <span>{error}</span>} return (
</div> <option
key={key}
value={optionsObj[
key
].Label.LocalizedLabels[0].Label.replace(
/[\s\-\+\(\)\,]/g,
""
).toLowerCase()}
>
{
optionsObj[key].Label
.LocalizedLabels[0].Label
}
</option>
);
})}
</select>
</div>
</div>
</>
); );
}; };
const required = (value) => (value ? undefined : "Required");
const onHandleSubmit = (values) => { const onHandleSubmit = (values) => {
event.preventDefault(); event.preventDefault();
router.replace("/newappeal/" + values.appealTypes, null, {
console.log(createCase("asasa", "asasa")); shallow: true,
});
const caseReference = createCase("123123", "213132");
router.replace(
"/newappeal/" + values.appealTypes + "?refno=" + caseReference,
null,
{
shallow: true,
}
);
console.log(values);
}; };
return ( return (
<form onSubmit={handleSubmit(onHandleSubmit)}> <form onSubmit={handleSubmit(onHandleSubmit)}>
<div className="govuk-form-group"> <Field
<label className="govuk-label" htmlFor="sort"> name="lpaTypes"
Select your local planning authority component={RenderLPAList}
</label> optionsObj={lpaOptionsObj}
<Field validate={[required]}
name="lpaTypes" label="Select your local planning authority"
component={RenderLPAList} errorMsg="Local authority is required"
optionsObj={lpaOptionsObj} />
/>
{/* <select <Field
className="govuk-select" name="appealTypes"
id="appealTypes" component={RenderAppealTypeList}
name="appealTypes" optionsObj={appealOptionsObj}
onChange={(e) => props.onChangeSelectLPA(e)} validate={[required]}
> label="Select an appeal type"
{" "} errorMsg="Appeal type is required"
<option>Select...</option> />
{lpaOptions}
</select> */}
</div>
<div className="govuk-form-group">
<label className="govuk-label" htmlFor="sort">
Select an appeal type
</label>
<Field
name="appealTypes"
component={RenderAppealTypeList}
optionsObj={appealOptionsObj}
/>
{/* <select
className="govuk-select"
id="appealTypes"
name="appealTypes"
onChange={(e) => props.onChangeSelectAppealType(e)}
>
<option>Select...</option>
{appealOptions}
</select> */}
</div>
<button <button
type="submit" type="submit"
className="govuk-button" className="govuk-button"
+41 -30
View File
@@ -22,7 +22,7 @@ import {
setCaseReference, setCaseReference,
} from "../../store/appealType/action"; } from "../../store/appealType/action";
import { setForm, getFormObj } from "../../store/formData/action"; import { setForm, getFormObj } from "../../store/formData/action";
import { getFormData, getAppealsTypes } from "../../actions"; import { getFormData, getAppealsTypes, createCase } from "../../actions";
import xpath from "xpath"; import xpath from "xpath";
import { reduxForm, FormName } from "redux-form"; import { reduxForm, FormName } from "redux-form";
@@ -40,9 +40,10 @@ let Home = (props) => {
const { appealtypes } = router.query; const { appealtypes } = router.query;
useEffect(() => { useEffect(() => {
props.setFormTitle(formTitle); //setFormTitle(formTitle);
props.setCaseReference(router.query.refno); setCaseReference(router.query.refno);
}, []); }, []); // eslint-disable-line react-hooks/exhaustive-deps
const formXML = props.formData.formData; const formXML = props.formData.formData;
const parser = new DOMParser(); const parser = new DOMParser();
var doc = parser.parseFromString(formXML, "text/xml"); var doc = parser.parseFromString(formXML, "text/xml");
@@ -78,7 +79,7 @@ let Home = (props) => {
(key) => optionsTitleObj[key] === appealtypes (key) => optionsTitleObj[key] === appealtypes
); );
console.log(formTitle); //console.log(formTitle);
// crm api query for looking up picklist fields/drop downs // crm api query for looking up picklist fields/drop downs
// <url path to >/api/data/v8.2/EntityDefinitions(LogicalName='{appeal type form}')/Attributes(LogicalName='{drop down datafield name}')/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=GlobalOptionSet($select=Options) // <url path to >/api/data/v8.2/EntityDefinitions(LogicalName='{appeal type form}')/Attributes(LogicalName='{drop down datafield name}')/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=GlobalOptionSet($select=Options)
@@ -110,31 +111,38 @@ let Home = (props) => {
<div id="page_wrapper"> <div id="page_wrapper">
<CookieBanner /> <CookieBanner />
<Header courseName={t("common:service-name")} /> <Header courseName={t("common:service-name")} />
<div className="govuk-width-container"> <main
<Banner /> className="govuk-main-wrapper govuk-main-wrapper--auto-spacing"
<Breadcrumbs slug={appealtypes} formTitle={formTitle} /> id="main-content"
role="main"
>
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} formTitle={formTitle} />
{props.appealType.currentSection == 9999 ? ( {props.appealType.currentSection == 9999 ? (
<CompleteAppeal /> <CompleteAppeal />
) : props.appealType.currentSection == sectionCount + 1 ? ( ) : props.appealType.currentSection ==
<BuildCheckSection sectionCount + 1 ? (
formXML={formXML} <BuildCheckSection
sectionCount={sectionCount} formXML={formXML}
onSubmit={onSubmit} sectionCount={sectionCount}
formTitle={formTitle} onSubmit={onSubmit}
appealType={props.appealType} formTitle={formTitle}
props={props} appealType={props.appealType}
/> props={props}
) : ( />
<BuildSection ) : (
formXML={formXML} <BuildSection
sectionCount={sectionCount} formXML={formXML}
onSubmit={onSubmit} sectionCount={sectionCount}
formTitle={formTitle} onSubmit={onSubmit}
props={props} formTitle={formTitle}
/> props={props}
)} />
</div> )}
</div>
</main>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
</div> </div>
@@ -144,14 +152,17 @@ let Home = (props) => {
export const getServerSideProps = wrapper.getServerSideProps( export const getServerSideProps = wrapper.getServerSideProps(
(store) => (store) =>
async ({ query, req, res }) => { async ({ query, req, res }) => {
console.log("the query", query); //console.log("the query", query);
store.dispatch(setAppealTypeID(query.appealtypes)); store.dispatch(setAppealTypeID(query.appealtypes));
const appealTypeData = await getAppealsTypes(); const appealTypeData = await getAppealsTypes();
const formdata = (await getFormData(query.appealtypes)) || null; const formdata = (await getFormData(query.appealtypes)) || null;
const caseReference = createCase("asasa", "asasa");
let xmlStr = formdata; let xmlStr = formdata;
xmlStr = formdata.value[0].formxml; xmlStr = formdata.value[0].formxml;
xmlStr = xmlStr.replace(/\\"/g, ""); xmlStr = xmlStr.replace(/\\"/g, "");
store.dispatch(setCaseReference(caseReference));
store.dispatch(setForm(xmlStr)); store.dispatch(setForm(xmlStr));
store.dispatch(setAppealType(appealTypeData)); store.dispatch(setAppealType(appealTypeData));
} }
+17 -13
View File
@@ -49,22 +49,26 @@ const Home = (props) => {
<div id="page_wrapper"> <div id="page_wrapper">
<CookieBanner /> <CookieBanner />
<Header courseName={t("common:service-name")} /> <Header courseName={t("common:service-name")} />
<main
className="govuk-main-wrapper govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<div className="govuk-grid-row"> <h1>New Appeal</h1>
<div className="govuk-grid-column-full"> <CreateCase
<div className="govuk-width-container"> LPAData={props.LPAData}
<Banner /> appealType={props.setAppealType}
<Breadcrumbs slug={appealtypes} /> />
</div>
<h1>New Appeal</h1>
<CreateCase
LPAData={props.LPAData}
appealType={props.setAppealType}
/>
</div> </div>
</div> </div>
</div> </main>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
</div> </div>
+38 -34
View File
@@ -68,45 +68,49 @@ const Home = (props) => {
<div id="page_wrapper"> <div id="page_wrapper">
<CookieBanner /> <CookieBanner />
<Header courseName={t("common:service-name")} /> <Header courseName={t("common:service-name")} />
<main
className="govuk-main-wrapper govuk-main-wrapper--auto-spacing"
id="main-content"
role="main"
>
<div className="govuk-grid-row">
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<div className="govuk-grid-row"> <h1>New Appeal</h1>
<div className="govuk-grid-column-full">
<div className="govuk-width-container">
<Banner />
<Breadcrumbs slug={appealtypes} />
<h1>New Appeal</h1> <form onSubmit={selectAppealType}>
<div className="govuk-form-group">
<form onSubmit={selectAppealType}> <label
<div className="govuk-form-group"> className="govuk-label"
<label htmlFor="sort"
className="govuk-label" >
htmlFor="sort" Select an appeal Type
</label>
<select
className="govuk-select"
id="appealTypes"
name="appealTypes"
onChange={(e) =>
props.onChangeSelect(e)
}
>
{appealOptions}
</select>
</div>
<button
className="govuk-button"
data-module="govuk-button"
> >
Select an appeal Type Continue
</label> </button>
<select </form>
className="govuk-select" </div>
id="appealTypes"
name="appealTypes"
onChange={(e) =>
props.onChangeSelect(e)
}
>
{appealOptions}
</select>
</div>
<button
className="govuk-button"
data-module="govuk-button"
>
Continue
</button>
</form>
</div> </div>
</div> </div>
</div> </main>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
</div> </div>
</div> </div>