Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Fs 3060 add freetextfield to designer #387

Merged
merged 8 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions designer/client/ComponentTypeEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ListFieldEdit from "./components/FieldEditors/list-field-edit";
import SelectFieldEdit from "./components/FieldEditors/select-field-edit";
import { TextFieldEdit } from "./components/FieldEditors/text-field-edit";
import { MultilineTextFieldEdit } from "./multiline-text-field-edit";
import { FreeTextFieldEdit } from "./free-text-field-edit";
import { FileUploadFieldEdit } from "./file-upload-field-edit";
import { NumberFieldEdit } from "./components/FieldEditors/number-field-edit";
import { DateFieldEdit } from "./components/FieldEditors/date-field-edit";
Expand All @@ -17,6 +18,7 @@ const componentTypeEditors = {
EmailAddressField: TextFieldEdit,
TelephoneNumberField: TextFieldEdit,
MultilineTextField: MultilineTextFieldEdit,
FreeTextField: FreeTextFieldEdit,
NumberField: NumberFieldEdit,
AutocompleteField: ListFieldEdit,
SelectField: SelectFieldEdit,
Expand Down
9 changes: 9 additions & 0 deletions designer/client/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const componentTypes = {
DateTimePartsField,
MonthYearField,
MultilineTextField,
FreeTextField,
RadiosField,
CheckboxesField,
AutocompleteField: SelectField,
Expand Down Expand Up @@ -86,6 +87,14 @@ function MultilineTextField() {
);
}

function FreeTextField() {
return (
<ComponentField>
<span className="box tall thick-top-border" />
</ComponentField>
);
}

function NumberField() {
return (
<ComponentField>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ suite("ComponentCreateList", () => {
"Date time parts",
"Email address",
"File upload",
"Free text",
"Month year parts",
"Multiline text",
"Number",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,19 @@ exports[`ComponentCreateList should match snapshot 1`] = `
Allows users to upload files from the device they are using
</div>
</li>
<li>
<a
class="govuk-link"
href="#0"
>
Free text
</a>
<div
class="govuk-hint"
>
A text box with basic formatting options (bold text, bullet points) for users to enter multiple lines of text into, for example as 'Additional info'
</div>
</li>
<li>
<a
class="govuk-link"
Expand Down
38 changes: 38 additions & 0 deletions designer/client/free-text-field-edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { useContext } from "react";
import { ComponentContext } from "./reducers/component/componentReducer";
import { Actions } from "./reducers/component/types";
import { i18n } from "./i18n";

export function FreeTextFieldEdit({ context = ComponentContext }) {
const { state, dispatch } = useContext(context);
const { selectedComponent } = state;
const { options = {} } = selectedComponent;

return (
<div className="govuk-form-group">
<label
className="govuk-label govuk-label--s"
htmlFor="field-schema-maxwords"
>
{i18n("textFieldEditComponent.maxWordField.title")}
</label>
<span className="govuk-hint">
{i18n("textFieldEditComponent.maxWordField.helpText")}
</span>
<input
className="govuk-input govuk-input--width-3"
data-cast="number"
id="field-schema-maxwords"
name="schema.maxwords"
value={options.maxWords || ""}
type="number"
onChange={(e) =>
dispatch({
type: Actions.EDIT_OPTIONS_MAX_WORDS,
payload: e.target.value,
})
}
/>
</div>
);
}
2 changes: 2 additions & 0 deletions designer/client/i18n/translations/en.translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@
"MonthYearField_info": "Allows users to manually enter a Month and Year",
"MultilineTextField": "Multiline text",
"MultilineTextField_info": "A text box for users to enter multiple lines of text into, for example as 'Additional info'",
"FreeTextField": "Free text",
"FreeTextField_info": "A text box with basic formatting options (bold text, bullet points) for users to enter multiple lines of text into, for example as 'Additional info'",
"NumberField": "Number",
"NumberField_info": "A text box that users can only enter numbers into",
"Para": "Paragraph",
Expand Down
4 changes: 4 additions & 0 deletions designer/client/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ button.govuk-link {
height: 20px;
border: solid 2px #000;

&.thick-top-border {
border-top: 8px solid lightsteelblue;
}

&.tall {
height: 50px;
}
Expand Down
16 changes: 16 additions & 0 deletions designer/test/inline-condition-operators.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,22 @@ suite("Inline condition operators", () => {
},
],
},
FreeTextField: {
cases: [
{
operators: {
"has length": (field, value) =>
`length(${field}) == ${value.value}`,
is: (field, value) => `${field} == '${value.value}'`,
"is longer than": (field, value) =>
`length(${field}) > ${value.value}`,
"is not": (field, value) => `${field} != '${value.value}'`,
"is shorter than": (field, value) =>
`length(${field}) < ${value.value}`,
},
},
],
},
EmailAddressField: {
cases: [
{
Expand Down
9 changes: 9 additions & 0 deletions model/src/components/component-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ export const ComponentTypes: ComponentDef[] = [
options: {},
schema: {},
},
{
name: "FreeTextField",
type: "FreeTextField",
title: "Free text field",
subType: "field",
hint: "",
options: {},
schema: {},
},
{
name: "YesNoField",
type: "YesNoField",
Expand Down
1 change: 1 addition & 0 deletions model/src/conditions/condition-operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export const customOperators = {
),
TextField: withDefaults(textBasedFieldCustomisations),
MultilineTextField: withDefaults(textBasedFieldCustomisations),
FreeTextField: withDefaults(textBasedFieldCustomisations),
EmailAddressField: withDefaults(textBasedFieldCustomisations),
};

Expand Down
1 change: 1 addition & 0 deletions model/src/conditions/inline-condition-operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const customOperators = {
),
TextField: withDefaults(textBasedFieldCustomisations),
MultilineTextField: withDefaults(textBasedFieldCustomisations),
FreeTextField: withDefaults(textBasedFieldCustomisations),
EmailAddressField: withDefaults(textBasedFieldCustomisations),
};

Expand Down
50 changes: 50 additions & 0 deletions runner/src/server/forms/test-free-text-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"metadata": {},
"startPage": "/first-page",
"pages": [
{
"title": "First page",
"path": "/first-page",
"components": [
{
"name": "CClUon",
"options": {
"maxWords": "15"
},
"type": "FreeTextField",
"title": "My free text field",
"hint": "asdfasdfasdfasdf"
}
],
"next": [
{
"path": "/second-page"
}
]
},
{
"path": "/second-page",
"title": "Second page",
"components": [],
"next": [
{
"path": "/summary"
}
]
},
{
"title": "Summary",
"path": "/summary",
"controller": "./pages/summary.js",
"components": []
}
],
"lists": [],
"sections": [],
"conditions": [],
"fees": [],
"outputs": [],
"version": 2,
"skipSummary": false,
"markAsComplete": false
}
13 changes: 0 additions & 13 deletions runner/src/server/plugins/engine/components/FreeTextField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,6 @@ export class FreeTextField extends FormComponent {
}
this.formSchema = this.formSchema.ruleset;

if (def.schema.max) {
this.formSchema = this.formSchema.max(def.schema.max);
this.isCharacterOrWordCount = true;
}

if (def.schema.min) {
this.formSchema = this.formSchema.min(def.schema.min);
}

if (maxWords ?? false) {
this.formSchema = this.formSchema.custom((value, helpers) => {
if (inputIsOverWordCount(value, maxWords)) {
Expand Down Expand Up @@ -91,10 +82,6 @@ export class FreeTextField extends FormComponent {
) as FreeTextFieldViewModel;
viewModel.isCharacterOrWordCount = this.isCharacterOrWordCount;

if (schema.max ?? false) {
viewModel.maxlength = schema.max;
}

if (options.rows ?? false) {
viewModel.rows = options.rows;
}
Expand Down
63 changes: 63 additions & 0 deletions runner/test/cases/server/plugins/engine/FreeTextField.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as Code from "@hapi/code";
import * as Lab from "@hapi/lab";
import { FreeTextField } from "src/server/plugins/engine/components";
import { validationOptions } from "../../../../../src/server/plugins/engine/pageControllers/validationOptions";

const lab = Lab.script();
exports.lab = lab;
const { expect } = Code;
const { suite, test } = lab;

suite("Free text field", () => {
test("Should return correct view model when not configured with max words", () => {
const def = {
name: "myComponent",
title: "My component",
hint: "a hint",
options: {},
schema: {},
};
const freeTextField = new FreeTextField(def, {});
expect(freeTextField.getViewModel({})).to.contain({
isCharacterOrWordCount: false,
});
});
test("Should return correct view model when configured with max words", () => {
const def = {
name: "myComponent",
title: "My component",
hint: "a hint",
options: {
maxWords: 26,
},
schema: {},
};
const freeTextField = new FreeTextField(def, {});
expect(freeTextField.getViewModel({})).to.contain({
isCharacterOrWordCount: true,
maxWords: 26,
});
});

test("Should supply custom validation message if defined", () => {
const def = {
name: "myComponent",
title: "My component",
hint: "a hint",
options: {
required: false,
customValidationMessage: "This is a custom error",
maxWords: 2,
},
schema: {},
};
const freeTextField = new FreeTextField(def, {});
const { formSchema } = freeTextField;

expect(formSchema.validate("a").error).to.be.undefined();

expect(
formSchema.validate("too many words in here").error.message
).to.equal("This is a custom error");
});
});
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION=0.1.191
VERSION=0.1.194