Merged PR 355: added redux store for form elements

added redux store for form elements

Related work items: #5212
This commit is contained in:
Robert Bond
2021-07-12 13:45:07 +00:00
8 changed files with 162 additions and 131 deletions
+11 -11
View File
@@ -30,7 +30,7 @@ export const getBasicSearch = (searchString) => {
axios axios
//.get("https://devcrm2016.llcdt.gov.wales/DVPINS/api/data/v8.2/incidents?$select=_accountid_value,_customerid_value,pinswg_appealcasetype,statuscode,ticketnumber,title&$filter=contains(title, '" + searchString + "')&$count=true", crmHeaders) //.get("https://devcrm2016.llcdt.gov.wales/DVPINS/api/data/v8.2/incidents?$select=_accountid_value,_customerid_value,pinswg_appealcasetype,statuscode,ticketnumber,title&$filter=contains(title, '" + searchString + "')&$count=true", crmHeaders)
//.get("https://jsonplaceholder.typicode.com/todos/1",{proxy:{protocol: 'http',host:'lon3.sme.zscloud.net',port: 80}}) //.get("https://jsonplaceholder.typicode.com/todos/1",{proxy:{protocol: 'http',host:'lon3.sme.zscloud.net',port: 80}})
.get("http://localhost:3000/api/searchresults2", { .get("/api/searchresults2", {
httpsAgent: new https.Agent({ rejectUnauthorized: false }), httpsAgent: new https.Agent({ rejectUnauthorized: false }),
}) })
.then((res) => res.data) .then((res) => res.data)
@@ -45,15 +45,15 @@ export const getFormData = (whichForm) => {
return ( return (
axios axios
//.get("http://localhost:3000/api/appealforms/pinswg_dns", { //.get("api/appealforms/pinswg_dns", {
//.get("http://localhost:3000/api/appealforms/pinswg_planningobligationappeals106", { //.get("api/appealforms/pinswg_planningobligationappeals106", {
//.get("http://localhost:3000/api/appealforms/pinswg_planningconditionss73s79", { //.get("api/appealforms/pinswg_planningconditionss73s79", {
//.get("http://localhost:3000/api/appealforms/pinswg_row", { //.get("api/appealforms/pinswg_row", {
//.get("http://localhost:3000/api/appealforms/pinswg_transportandworkact", { //.get("api/appealforms/pinswg_transportandworkact", {
//.get("http://localhost:3000/api/appealforms/pinswg_harbourrevisionorder", { //.get("api/appealforms/pinswg_harbourrevisionorder", {
//.get("http://localhost:3000/api/appealforms/pinswg_planningappeals78", { //.get("api/appealforms/pinswg_planningappeals78", {
//.get(http://localhost:3000/api/appealforms/pinswg_householderappealhas", { //.get(api/appealforms/pinswg_householderappealhas", {
.get("http://localhost:3000/api/appealforms/pinswg_" + whichForm, { .get("/api/appealforms/pinswg_" + whichForm, {
httpsAgent: new https.Agent({ rejectUnauthorized: false }), httpsAgent: new https.Agent({ rejectUnauthorized: false }),
}) })
.then((res) => res.data) .then((res) => res.data)
@@ -67,7 +67,7 @@ export const getAppealsTypes = () => {
console.log("got to axios: appeal types"); console.log("got to axios: appeal types");
return axios return axios
.get("http://localhost:3000/api/lookups/pinswg_appealcasetype", { .get("/api/lookups/pinswg_appealcasetype", {
httpsAgent: new https.Agent({ rejectUnauthorized: false }), httpsAgent: new https.Agent({ rejectUnauthorized: false }),
}) })
.then((res) => res.data) .then((res) => res.data)
+72 -71
View File
@@ -1,4 +1,5 @@
import useSWR from "swr"; import useSWR from "swr";
import { Field, reduxForm } from "redux-form";
export function Textfield(props) { export function Textfield(props) {
const { name, label } = props; const { name, label } = props;
@@ -8,12 +9,12 @@ export function Textfield(props) {
<label className="govuk-label govuk-label--m " htmlFor="event-name"> <label className="govuk-label govuk-label--m " htmlFor="event-name">
{props.label} {props.label}
</label> </label>
<Field
<input
className="govuk-input govuk-input--width-20"
id="event-name"
name={props.name} name={props.name}
id={props.name}
component="input"
type="text" type="text"
className="govuk-input govuk-input--width-20"
/> />
</div> </div>
); );
@@ -36,13 +37,15 @@ 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>
<textarea <Field
className="govuk-textarea" name={props.name}
id="more-detail" id={props.name}
name="more-detail" component="input"
type="text"
rows="5" rows="5"
className="govuk-textarea govuk-input--width-20"
aria-describedby="more-detail-hint" aria-describedby="more-detail-hint"
></textarea> />
</div> </div>
); );
} }
@@ -70,18 +73,18 @@ export function DateField(props) {
<div className="govuk-form-group"> <div className="govuk-form-group">
<label <label
className="govuk-label govuk-date-input__label" className="govuk-label govuk-date-input__label"
htmlFor="dob-day" htmlFor={props.name + "-day"}
> >
Day Day
</label> </label>
<input <Field
className="govuk-input govuk-date-input__input govuk-input--width-2" name={props.name + "-day"}
id="dob-day" id={props.name + "-day"}
name="dob-day" component="input"
type="text" type="text"
autoComplete="bday-day"
pattern="[0-9]*" pattern="[0-9]*"
inputMode="numeric" inputMode="numeric"
className="govuk-input govuk-date-input__input govuk-input--width-2"
/> />
</div> </div>
</div> </div>
@@ -89,18 +92,18 @@ export function DateField(props) {
<div className="govuk-form-group"> <div className="govuk-form-group">
<label <label
className="govuk-label govuk-date-input__label" className="govuk-label govuk-date-input__label"
htmlFor="dob-month" htmlFor={props.name + "-month"}
> >
Month Month
</label> </label>
<input <Field
className="govuk-input govuk-date-input__input govuk-input--width-2" name={props.name + "-month"}
id="dob-month" id={props.name + "-month"}
name="dob-month" component="input"
type="text" type="text"
autoComplete="bday-month"
pattern="[0-9]*" pattern="[0-9]*"
inputMode="numeric" inputMode="numeric"
className="govuk-input govuk-date-input__input govuk-input--width-2"
/> />
</div> </div>
</div> </div>
@@ -108,18 +111,18 @@ export function DateField(props) {
<div className="govuk-form-group"> <div className="govuk-form-group">
<label <label
className="govuk-label govuk-date-input__label" className="govuk-label govuk-date-input__label"
htmlFor="dob-year" htmlFor={props.name + "-year"}
> >
Year Year
</label> </label>
<input <Field
className="govuk-input govuk-date-input__input govuk-input--width-4" name={props.name + "-year"}
id="dob-year" id={props.name + "-year"}
name="dob-year" component="input"
type="text" type="text"
autoComplete="bday-year"
pattern="[0-9]*" pattern="[0-9]*"
inputMode="numeric" inputMode="numeric"
className="govuk-input govuk-date-input__input govuk-input--width-4"
/> />
</div> </div>
</div> </div>
@@ -131,7 +134,7 @@ export function DateField(props) {
export function YesNofield(props) { export function YesNofield(props) {
const { name, label } = props; const { name, label } = props;
const yesNo = ["Yes", "No"];
return ( return (
<div className="govuk-form-group"> <div className="govuk-form-group">
<fieldset <fieldset
@@ -145,36 +148,28 @@ export function YesNofield(props) {
</legend> </legend>
<div className="govuk-radios govuk-radios--inline"> <div className="govuk-radios govuk-radios--inline">
<div className="govuk-radios__item"> {Object.keys(yesNo).map((key, index) => (
<input <div
className="govuk-radios__input" className="govuk-radios__item"
id="changed-name" data-children-count={key}
name="changed-name" key={key}
type="radio"
value="yes"
/>
<label
className="govuk-label govuk-radios__label"
htmlFor="changed-name"
> >
Yes <Field
</label> id={props.name + "_" + index}
</div> name={props.name}
<div className="govuk-radios__item"> component="input"
<input type="radio"
className="govuk-radios__input" className="govuk-radios__input"
id="changed-name-2" value={yesNo[key]}
name="changed-name" />
type="radio" <label
value="no" className="govuk-label govuk-radios__label"
/> htmlFor={props.name + "_" + index}
<label >
className="govuk-label govuk-radios__label" {yesNo[key]}
htmlFor="changed-name-2" </label>
> </div>
No ))}
</label>
</div>
</div> </div>
</fieldset> </fieldset>
</div> </div>
@@ -193,7 +188,11 @@ export function PickList(props) {
<label className="govuk-label govuk-body-m" htmlFor="sort"> <label className="govuk-label govuk-body-m" htmlFor="sort">
{props.label} {props.label}
</label> </label>
<select className="govuk-select" id="sort" name="sort"> <select
className="govuk-select"
id={props.name}
name={props.name}
>
<option value="">empty</option> <option value="">empty</option>
</select> </select>
</div> </div>
@@ -213,7 +212,7 @@ export function PickList(props) {
<label className="govuk-label govuk-body-m" htmlFor="sort"> <label className="govuk-label govuk-body-m" htmlFor="sort">
{props.label} {props.label}
</label> </label>
<select className="govuk-select" id="sort" name="sort"> <select className="govuk-select" id={props.name} name={props.name}>
{Object.keys(dropdownObj).map((key, index) => { {Object.keys(dropdownObj).map((key, index) => {
return ( return (
<option <option
@@ -247,11 +246,12 @@ export function NumericField(props) {
<div id="account-number-hint" className="govuk-hint"> <div id="account-number-hint" className="govuk-hint">
Must be between 6 and 8 digits long Must be between 6 and 8 digits long
</div> </div>
<input <Field
className="govuk-input govuk-input--width-10" name={props.name}
id="account-number" id={props.name}
name="account-number" component="input"
type="text" type="text"
className="govuk-input govuk-input--width-20"
spellCheck="false" spellCheck="false"
aria-describedby="account-number-hint" aria-describedby="account-number-hint"
pattern="[0-9]*" pattern="[0-9]*"
@@ -276,11 +276,12 @@ export function DecimalField(props) {
<div id="account-number-hint" className="govuk-hint"> <div id="account-number-hint" className="govuk-hint">
Must be between 6 and 8 digits long Must be between 6 and 8 digits long
</div> </div>
<input <Field
className="govuk-input govuk-input--width-10" name={props.name}
id="account-number" id={props.name}
name="account-number" component="input"
type="text" type="text"
className="govuk-input govuk-input--width-10"
spellCheck="false" spellCheck="false"
aria-describedby="account-number-hint" aria-describedby="account-number-hint"
pattern="[0-9]*" pattern="[0-9]*"
@@ -298,12 +299,12 @@ export function ReadOnlyfield(props) {
<label className="govuk-label govuk-label--m " htmlFor="event-name"> <label className="govuk-label govuk-label--m " htmlFor="event-name">
{props.label} {props.label}
</label> </label>
<Field
<input
className="govuk-input govuk-input--width-20"
id="event-name"
name={props.name} name={props.name}
id={props.name}
component="input"
type="text" type="text"
className="govuk-input govuk-input--width-20"
disabled disabled
/> />
</div> </div>
+1 -1
View File
@@ -10,7 +10,7 @@ export default function BuildRow(props) {
const router = useRouter(); const router = useRouter();
const { locale } = router; const { locale } = router;
const { rowXML, whichSection, sectionCount } = props; const { rowXML, whichSection, sectionCount, onSubmit } = props;
const parser = new DOMParser(); const parser = new DOMParser();
+61 -42
View File
@@ -4,18 +4,20 @@ 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 { useDispatch, useSelector, shallowEqual, connect } from "react-redux";
const BuildSection = (props) => { let BuildSection = (props) => {
useEffect(() => { // useEffect(() => {
window.scrollTo(0, 0); // window.scrollTo(0, 0);
}); // });
let { t } = useTranslation(); let { t } = useTranslation();
const router = useRouter(); const router = useRouter();
const { locale } = router; const { locale } = router;
const { formXML, sectionCount } = props; const { formXML, sectionCount, onSubmit, handleSubmit } = props;
const [currentSection, setCurrentSection] = useState(1); const [currentSection, setCurrentSection] = useState(1);
const parser = new DOMParser(); const parser = new DOMParser();
@@ -36,8 +38,6 @@ const BuildSection = (props) => {
doc doc
); );
console.log(titleList);
const handleParam = (setValue) => (e) => setValue(e.target.value); const handleParam = (setValue) => (e) => setValue(e.target.value);
const basicSearch = (event) => { const basicSearch = (event) => {
@@ -46,44 +46,49 @@ const BuildSection = (props) => {
// /searchresults // /searchresults
}; };
const onHandleSubmit = (values) => {
setCurrentSection(currentSection + 1);
};
return ( return (
<div className="govuk-grid-row"> <div className="govuk-grid-row">
<div className="govuk-grid-column-two-thirds"> <div className="govuk-grid-column-two-thirds">
<h2>{titles[0].value} </h2> <h2>{titles[0].value} </h2>
<BuildRow <form onSubmit={handleSubmit(onHandleSubmit)}>
rowXML={rowXML} <BuildRow
whichSection={props.whichSection} rowXML={rowXML}
sectionCount={props.sectionCount} whichSection={props.whichSection}
/> sectionCount={props.sectionCount}
{} onSubmit={onSubmit}
<div className="govuk-button-group"> />
{props.sectionCount != currentSection ? ( {}
<button <div className="govuk-button-group">
className="govuk-button" {props.sectionCount != currentSection ? (
data-module="govuk-button" <button
onClick={() => type="submit"
setCurrentSection(currentSection + 1) className="govuk-button"
} data-module="govuk-button"
> >
Continue Continue
</button> </button>
) : ( ) : (
"" ""
)} )}
{currentSection > 1 ? ( {currentSection > 1 ? (
<a <a
className="govuk-link" className="govuk-link"
href="#" href="#"
onClick={() => onClick={() =>
setCurrentSection(currentSection - 1) setCurrentSection(currentSection - 1)
} }
> >
Back Back
</a> </a>
) : ( ) : (
"" ""
)} )}
</div> </div>
</form>
</div> </div>
<div className="govuk-grid-column-one-third"> <div className="govuk-grid-column-one-third">
<nav <nav
@@ -118,4 +123,18 @@ const BuildSection = (props) => {
); );
}; };
export default BuildSection; const mapStateToProps = (state) => {
return {
form: state.form,
};
};
BuildSection = reduxForm({
// a unique name for the form
form: "sssappealForm",
destroyOnUnmount: false,
})(BuildSection);
const selector = formValueSelector("appealForm"); // <-- same as form name
export default connect(mapStateToProps)(BuildSection);
+2 -2
View File
@@ -5,7 +5,7 @@
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "node server.js" "start": "next start -p 80"
}, },
"dependencies": { "dependencies": {
"@webdeb/next-styles": "^1.1.1", "@webdeb/next-styles": "^1.1.1",
@@ -46,4 +46,4 @@
"eslint-config-next": "^11.0.1", "eslint-config-next": "^11.0.1",
"prettier": "2.3.2" "prettier": "2.3.2"
} }
} }
+6 -3
View File
@@ -16,10 +16,11 @@ import useTranslation from "next-translate/useTranslation";
import { setForm, getFormObj } from "../../store/formData/action"; import { setForm, getFormObj } from "../../store/formData/action";
import { getFormData } from "../../actions"; import { getFormData } from "../../actions";
import xpath from "xpath"; import xpath from "xpath";
import { reduxForm } from "redux-form";
import BuildSection from "../../components/newappeal/buildsection"; import BuildSection from "../../components/newappeal/buildsection";
const Home = (props) => { let Home = (props) => {
const { footerLinks, pages, formData } = props; const { footerLinks, pages, formData } = props;
let { t, lang } = useTranslation(); let { t, lang } = useTranslation();
@@ -57,8 +58,6 @@ const Home = (props) => {
/// to get dropdowns names /// to get dropdowns names
// form/tabs/tab[*]//rows/row//control[@classid="{3EF39988-22BB-4f0b-BBBE-64B5A3748AEE}"]/@datafieldname // form/tabs/tab[*]//rows/row//control[@classid="{3EF39988-22BB-4f0b-BBBE-64B5A3748AEE}"]/@datafieldname
console.log(titles);
const Sections = Object.keys(tabs).map((key, index) => ( const Sections = Object.keys(tabs).map((key, index) => (
<BuildSection <BuildSection
formXML={formXML} formXML={formXML}
@@ -68,6 +67,8 @@ const Home = (props) => {
/> />
)); ));
const { onSubmit } = props;
return ( return (
<div> <div>
<Head> <Head>
@@ -85,6 +86,7 @@ const Home = (props) => {
<BuildSection <BuildSection
formXML={formXML} formXML={formXML}
sectionCount={sectionCount} sectionCount={sectionCount}
onSubmit={onSubmit}
/> />
</div> </div>
<Footer footerLinks={footerLinks} /> <Footer footerLinks={footerLinks} />
@@ -133,6 +135,7 @@ const mapStateToProps = (state) => {
searchResultsObj: state.searchResultsObj, searchResultsObj: state.searchResultsObj,
formData: state.formData, formData: state.formData,
appealType: state.appealType, appealType: state.appealType,
form: state.form,
}; };
}; };
+9 -1
View File
@@ -16,6 +16,7 @@ const combinedReducer = combineReducers({
searchResultsObj, searchResultsObj,
formData, formData,
appealType, appealType,
form: formReducer,
}); });
const reducer = (state = { progress: "{}" }, action) => { const reducer = (state = { progress: "{}" }, action) => {
@@ -76,7 +77,14 @@ const makeStore = ({ isServer }) => {
const persistConfig = { const persistConfig = {
key: "nextjs", key: "nextjs",
whitelist: ["progress,search,searchResults,formData,appealType"], whitelist: [
"progress",
"search",
"searchResults",
"formData",
"appealType",
"form",
],
storage, storage,
stateReconciler: autoMergeLevel2, // if needed, use a safer storage stateReconciler: autoMergeLevel2, // if needed, use a safer storage
}; };