Extract CheckBox, DateFieldPicker and YesNo wrappers
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
import React from "react";
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { Field } from "redux-form";
|
||||||
|
import { RenderCheckBox } from "./renderCheckBox";
|
||||||
|
|
||||||
|
export function CheckBoxfield(props) {
|
||||||
|
const router = useRouter();
|
||||||
|
let { t } = useTranslation();
|
||||||
|
|
||||||
|
const fieldOptions =
|
||||||
|
router.locale == "cy" ? ["Ydw", "Na", "2323"] : ["Yes", "No", "23232"];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Field
|
||||||
|
name={props.name}
|
||||||
|
datafieldname={props.datafieldname}
|
||||||
|
label={props.label}
|
||||||
|
options={fieldOptions}
|
||||||
|
id={props.id}
|
||||||
|
className={props.className}
|
||||||
|
errorMsg={t("newappeal:select-an-option-label")}
|
||||||
|
component={RenderCheckBox}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import React from "react";
|
||||||
|
import _ from "lodash";
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
import { Field } from "redux-form";
|
||||||
|
import { RenderDatePicker } from "./renderDatePicker";
|
||||||
|
import { validateField } from "../validationUtils";
|
||||||
|
|
||||||
|
const dateDiffInDays = (a, b) => {
|
||||||
|
const _MS_PER_DAY = 1000 * 60 * 60 * 24;
|
||||||
|
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
|
||||||
|
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
|
||||||
|
|
||||||
|
return Math.floor((utc2 - utc1) / _MS_PER_DAY);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function DateFieldPicker(props) {
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
parentField,
|
||||||
|
form,
|
||||||
|
formProps,
|
||||||
|
parentFieldShowOnValue,
|
||||||
|
validation
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
let dateStart = props.dateStart;
|
||||||
|
let dateEnd = props.dateEnd;
|
||||||
|
let { t } = useTranslation();
|
||||||
|
|
||||||
|
const showIfHasParentShowValue =
|
||||||
|
parentField != false &&
|
||||||
|
!_.isEmpty(formProps[form]) &&
|
||||||
|
_.has(formProps[form].values, parentField) &&
|
||||||
|
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");
|
||||||
|
|
||||||
|
dateStart =
|
||||||
|
showIfHasParentShowValue && name == "pinswg_dateoflpadecision"
|
||||||
|
? "-" +
|
||||||
|
(dateDiffInDays(
|
||||||
|
new Date(formProps[form].values["pinswg_dateofapplication"]),
|
||||||
|
new Date()
|
||||||
|
) -
|
||||||
|
1) +
|
||||||
|
"d"
|
||||||
|
: dateStart;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="govuk-form-group">
|
||||||
|
{parentField != false ? (
|
||||||
|
showIfHasParentShowValue && (
|
||||||
|
<Field
|
||||||
|
name={name}
|
||||||
|
id={name}
|
||||||
|
label={label}
|
||||||
|
component={RenderDatePicker}
|
||||||
|
validate={(value) =>
|
||||||
|
validateField(
|
||||||
|
value,
|
||||||
|
validation,
|
||||||
|
requiredMessage,
|
||||||
|
emojiNotAllowedMessage,
|
||||||
|
invalidPostcodeMessage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
errorMsg={t("newappeal:select-a-date-label")}
|
||||||
|
dateStart={dateStart}
|
||||||
|
dateEnd={dateEnd}
|
||||||
|
hint={props.hint}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Field
|
||||||
|
name={name}
|
||||||
|
id={name}
|
||||||
|
label={label}
|
||||||
|
component={RenderDatePicker}
|
||||||
|
validate={(value) =>
|
||||||
|
validateField(
|
||||||
|
value,
|
||||||
|
validation,
|
||||||
|
requiredMessage,
|
||||||
|
emojiNotAllowedMessage,
|
||||||
|
invalidPostcodeMessage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
errorMsg={t("newappeal:select-a-date-label")}
|
||||||
|
dateStart={dateStart}
|
||||||
|
dateEnd={dateEnd}
|
||||||
|
hint={props.hint}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import React from "react";
|
||||||
|
import _ from "lodash";
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { Field } from "redux-form";
|
||||||
|
import { RenderYesNo } from "./renderYesNo";
|
||||||
|
|
||||||
|
export function YesNofield(props) {
|
||||||
|
const router = useRouter();
|
||||||
|
let { t } = useTranslation();
|
||||||
|
|
||||||
|
const { parentField, form, formProps, parentFieldShowOnValue } = props;
|
||||||
|
|
||||||
|
const yesNo = router.locale == "cy" ? ["Ydw", "Na"] : ["Yes", "No"];
|
||||||
|
const required = (value) => (value ? undefined : "Required");
|
||||||
|
|
||||||
|
const showIfHasParentShowValue =
|
||||||
|
parentField != false &&
|
||||||
|
!_.isEmpty(formProps[form]) &&
|
||||||
|
_.has(formProps[form].values, parentField) &&
|
||||||
|
parentFieldShowOnValue.indexOf(
|
||||||
|
formProps[form].values[parentField].toString()
|
||||||
|
) > -1;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{parentField != false ? (
|
||||||
|
showIfHasParentShowValue && (
|
||||||
|
<Field
|
||||||
|
name={props.name}
|
||||||
|
datafieldname={props.name}
|
||||||
|
label={props.label}
|
||||||
|
options={yesNo}
|
||||||
|
id={props.name}
|
||||||
|
className={"govuk-radios__input"}
|
||||||
|
validate={[required]}
|
||||||
|
errorMsg={t("newappeal:select-an-option-label")}
|
||||||
|
component={RenderYesNo}
|
||||||
|
inline={_.has(props, "inline") ? props.inline : "true"}
|
||||||
|
requiredDocumentLabel={props.requiredDocumentLabel}
|
||||||
|
requiredDocumentValue={props.requiredDocumentValue}
|
||||||
|
setDocumentsList={props.setDocumentsList}
|
||||||
|
documentList={props.documentList}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Field
|
||||||
|
name={props.name}
|
||||||
|
datafieldname={props.name}
|
||||||
|
label={props.label}
|
||||||
|
options={yesNo}
|
||||||
|
id={props.name}
|
||||||
|
className={"govuk-radios__input"}
|
||||||
|
validate={[required]}
|
||||||
|
errorMsg={t("newappeal:select-an-option-label")}
|
||||||
|
component={RenderYesNo}
|
||||||
|
inline={_.has(props, "inline") ? props.inline : "true"}
|
||||||
|
requiredDocumentLabel={props.requiredDocumentLabel}
|
||||||
|
requiredDocumentValue={props.requiredDocumentValue}
|
||||||
|
setDocumentsList={props.setDocumentsList}
|
||||||
|
documentList={props.documentList}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -13,16 +13,19 @@ import { getFieldTranslation } from "./helpers/translationHelpers";
|
|||||||
import { RenderRichMultiline } from "./fields/renderRichMultiline";
|
import { RenderRichMultiline } from "./fields/renderRichMultiline";
|
||||||
import { RenderTextfield } from "./fields/renderTextfield";
|
import { RenderTextfield } from "./fields/renderTextfield";
|
||||||
import { RenderMultiline } from "./fields/renderMultiline";
|
import { RenderMultiline } from "./fields/renderMultiline";
|
||||||
import { RenderDatePicker } from "./fields/renderDatePicker";
|
|
||||||
import { RenderYesNo } from "./fields/renderYesNo";
|
|
||||||
import { RenderRadio } from "./fields/renderRadio";
|
import { RenderRadio } from "./fields/renderRadio";
|
||||||
import { RenderCheckBox } from "./fields/renderCheckBox";
|
|
||||||
import { PickList } from "./fields/pickListField";
|
import { PickList } from "./fields/pickListField";
|
||||||
|
import { CheckBoxfield } from "./fields/checkBoxField";
|
||||||
|
import { DateFieldPicker } from "./fields/dateFieldPicker";
|
||||||
|
import { YesNofield } from "./fields/yesNoField";
|
||||||
import { RenderDecimalField } from "./fields/renderDecimalField";
|
import { RenderDecimalField } from "./fields/renderDecimalField";
|
||||||
import { RenderFileUpload } from "./fields/renderFileUpload";
|
import { RenderFileUpload } from "./fields/renderFileUpload";
|
||||||
export { RenderSubFields } from "./fields/renderSubFields";
|
export { RenderSubFields } from "./fields/renderSubFields";
|
||||||
export { FieldArrayForm } from "./fields/fieldArrayForm";
|
export { FieldArrayForm } from "./fields/fieldArrayForm";
|
||||||
export { PickList };
|
export { PickList };
|
||||||
|
export { CheckBoxfield };
|
||||||
|
export { DateFieldPicker };
|
||||||
|
export { YesNofield };
|
||||||
|
|
||||||
const getValidationMessages = (t) => ({
|
const getValidationMessages = (t) => ({
|
||||||
requiredMessage: t("newappeal:is-required-label"),
|
requiredMessage: t("newappeal:is-required-label"),
|
||||||
@@ -407,99 +410,6 @@ export function RichMultiLinefield(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DateFieldPicker(props) {
|
|
||||||
const {
|
|
||||||
name,
|
|
||||||
label,
|
|
||||||
parentField,
|
|
||||||
form,
|
|
||||||
formProps,
|
|
||||||
parentFieldShowOnValue,
|
|
||||||
validation
|
|
||||||
} = props;
|
|
||||||
let dateStart = props.dateStart;
|
|
||||||
let dateEnd = props.dateEnd;
|
|
||||||
let { t } = useTranslation();
|
|
||||||
var showIfHasParentShowValue = isVisibleByEquality({
|
|
||||||
parentField,
|
|
||||||
form,
|
|
||||||
formProps,
|
|
||||||
parentFieldShowOnValue
|
|
||||||
});
|
|
||||||
|
|
||||||
const { requiredMessage, emojiNotAllowedMessage, invalidPostcodeMessage } =
|
|
||||||
getValidationMessages(t);
|
|
||||||
|
|
||||||
// a and b are javascript Date objects
|
|
||||||
function dateDiffInDays(a, b) {
|
|
||||||
const _MS_PER_DAY = 1000 * 60 * 60 * 24;
|
|
||||||
// Discard the time and time-zone information.
|
|
||||||
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
|
|
||||||
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
|
|
||||||
|
|
||||||
return Math.floor((utc2 - utc1) / _MS_PER_DAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
dateStart =
|
|
||||||
showIfHasParentShowValue && name == "pinswg_dateoflpadecision"
|
|
||||||
? "-" +
|
|
||||||
(dateDiffInDays(
|
|
||||||
new Date(formProps[form].values["pinswg_dateofapplication"]),
|
|
||||||
new Date()
|
|
||||||
) -
|
|
||||||
1) +
|
|
||||||
"d"
|
|
||||||
: dateStart;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="govuk-form-group">
|
|
||||||
{parentField != false ? (
|
|
||||||
showIfHasParentShowValue && (
|
|
||||||
<Field
|
|
||||||
name={name}
|
|
||||||
id={name}
|
|
||||||
label={label}
|
|
||||||
component={RenderDatePicker}
|
|
||||||
validate={(value) =>
|
|
||||||
validateField(
|
|
||||||
value,
|
|
||||||
validation,
|
|
||||||
requiredMessage,
|
|
||||||
emojiNotAllowedMessage,
|
|
||||||
invalidPostcodeMessage
|
|
||||||
)
|
|
||||||
} // Use the external validate function
|
|
||||||
errorMsg={t("newappeal:select-a-date-label")}
|
|
||||||
dateStart={dateStart}
|
|
||||||
dateEnd={dateEnd}
|
|
||||||
hint={props.hint}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<Field
|
|
||||||
name={name}
|
|
||||||
id={name}
|
|
||||||
label={label}
|
|
||||||
component={RenderDatePicker}
|
|
||||||
validate={(value) =>
|
|
||||||
validateField(
|
|
||||||
value,
|
|
||||||
validation,
|
|
||||||
requiredMessage,
|
|
||||||
emojiNotAllowedMessage,
|
|
||||||
invalidPostcodeMessage
|
|
||||||
)
|
|
||||||
} // Use the external validate function
|
|
||||||
errorMsg={t("newappeal:select-a-date-label")}
|
|
||||||
dateStart={dateStart}
|
|
||||||
dateEnd={dateEnd}
|
|
||||||
hint={props.hint}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function DateField(props) {
|
export function DateField(props) {
|
||||||
const { name, label } = props;
|
const { name, label } = props;
|
||||||
|
|
||||||
@@ -579,75 +489,6 @@ export function DateField(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function YesNofield(props) {
|
|
||||||
const router = useRouter();
|
|
||||||
let { t } = useTranslation();
|
|
||||||
|
|
||||||
const {
|
|
||||||
name,
|
|
||||||
label,
|
|
||||||
inline,
|
|
||||||
form,
|
|
||||||
formProps,
|
|
||||||
validation,
|
|
||||||
parentFieldShowOnValue,
|
|
||||||
parentField
|
|
||||||
} = props;
|
|
||||||
const yesNo = router.locale == "cy" ? ["Ydw", "Na"] : ["Yes", "No"];
|
|
||||||
const required = (value) => (value ? undefined : "Required");
|
|
||||||
var showIfHasParentShowValue = isVisibleByInclusion({
|
|
||||||
parentField,
|
|
||||||
form,
|
|
||||||
formProps,
|
|
||||||
parentFieldShowOnValue
|
|
||||||
});
|
|
||||||
|
|
||||||
(showIfHasParentShowValue == parentField) != false &&
|
|
||||||
showIfHasParentShowValue;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{parentField != false ? (
|
|
||||||
showIfHasParentShowValue && (
|
|
||||||
<Field
|
|
||||||
name={props.name}
|
|
||||||
datafieldname={props.name}
|
|
||||||
label={props.label}
|
|
||||||
options={yesNo}
|
|
||||||
id={props.name}
|
|
||||||
className={"govuk-radios__input"}
|
|
||||||
validate={[required]}
|
|
||||||
errorMsg={t("newappeal:select-an-option-label")}
|
|
||||||
component={RenderYesNo}
|
|
||||||
inline={_.has(props, "inline") ? props.inline : "true"}
|
|
||||||
requiredDocumentLabel={props.requiredDocumentLabel}
|
|
||||||
requiredDocumentValue={props.requiredDocumentValue}
|
|
||||||
setDocumentsList={props.setDocumentsList}
|
|
||||||
documentList={props.documentList}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<Field
|
|
||||||
name={props.name}
|
|
||||||
datafieldname={props.name}
|
|
||||||
label={props.label}
|
|
||||||
options={yesNo}
|
|
||||||
id={props.name}
|
|
||||||
className={"govuk-radios__input"}
|
|
||||||
validate={[required]}
|
|
||||||
errorMsg={t("newappeal:select-an-option-label")}
|
|
||||||
component={RenderYesNo}
|
|
||||||
inline={_.has(props, "inline") ? props.inline : "true"}
|
|
||||||
requiredDocumentLabel={props.requiredDocumentLabel}
|
|
||||||
requiredDocumentValue={props.requiredDocumentValue}
|
|
||||||
setDocumentsList={props.setDocumentsList}
|
|
||||||
documentList={props.documentList}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Radiofield(props) {
|
export function Radiofield(props) {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
@@ -742,27 +583,6 @@ export function Radiofield(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CheckBoxfield(props) {
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
let { t } = useTranslation();
|
|
||||||
const fieldOptions =
|
|
||||||
router.locale == "cy" ? ["Ydw", "Na", "2323"] : ["Yes", "No", "23232"];
|
|
||||||
return (
|
|
||||||
<Field
|
|
||||||
name={props.name}
|
|
||||||
datafieldname={props.datafieldname}
|
|
||||||
label={props.label}
|
|
||||||
options={fieldOptions}
|
|
||||||
id={props.id}
|
|
||||||
className={props.className}
|
|
||||||
//validate={[required]}
|
|
||||||
errorMsg={t("newappeal:select-an-option-label")}
|
|
||||||
component={RenderCheckBox}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function NumericField(props) {
|
export function NumericField(props) {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -3642,3 +3642,31 @@ Validation:
|
|||||||
Follow-ups:
|
Follow-ups:
|
||||||
|
|
||||||
- Continue bounded no-behavior-change slices only (e.g., extract one additional low-risk wrapper such as `CheckBoxfield`).
|
- Continue bounded no-behavior-change slices only (e.g., extract one additional low-risk wrapper such as `CheckBoxfield`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CL-103: 22500 wrapper extraction bundle (`CheckBoxfield`, `DateFieldPicker`, `YesNofield`)
|
||||||
|
|
||||||
|
date: 2026-04-08
|
||||||
|
author: Cline
|
||||||
|
scope: `components/elements/index.js`, `components/elements/fields/{checkBoxField,dateFieldPicker,yesNoField}.js`
|
||||||
|
type: change
|
||||||
|
rationale: Execute the requested bundled wrapper slice by extracting wrappers 1/2/3 in one commit while keeping behavior unchanged.
|
||||||
|
impact: No intended behavior change; keeps EN/CY output, visibility logic, and accessibility structure intact while reducing `components/elements/index.js` size.
|
||||||
|
status: completed
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
|
||||||
|
- Added `components/elements/fields/checkBoxField.js` and moved `CheckBoxfield` wrapper.
|
||||||
|
- Added `components/elements/fields/dateFieldPicker.js` and moved `DateFieldPicker` wrapper logic.
|
||||||
|
- Added `components/elements/fields/yesNoField.js` and moved `YesNofield` wrapper logic.
|
||||||
|
- Updated `components/elements/index.js` to import/export these wrappers from field modules.
|
||||||
|
- Removed inline implementations of `CheckBoxfield`, `DateFieldPicker`, and `YesNofield` from `index.js`.
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
|
||||||
|
- `npx eslint components/elements/index.js components/elements/fields/checkBoxField.js components/elements/fields/dateFieldPicker.js components/elements/fields/yesNoField.js` -> pass
|
||||||
|
|
||||||
|
Follow-ups:
|
||||||
|
|
||||||
|
- Remaining wrappers can continue as bounded slices (`Radiofield`, `NumericField`, `DecimalField`) if required.
|
||||||
|
|||||||
Reference in New Issue
Block a user