Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OOC-4396: update feedback page #224

Merged
merged 6 commits into from
Aug 2, 2024
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
4 changes: 4 additions & 0 deletions model/src/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ export interface MultilineTextFieldComponent extends TextFieldBase {
customValidationMessage?: string;
rows?: number;
maxWords?: number;
conditionalTextBox?: {
dependsOnFieldName?: string;
dependsOnFieldValue?: string;
};
};
schema: {
max?: number;
Expand Down
57 changes: 35 additions & 22 deletions runner/src/server/forms/ReportAnOutbreak.json
Original file line number Diff line number Diff line change
Expand Up @@ -1622,26 +1622,35 @@
},
{
"path": "/feedback-on-the-care-obra-tool",
"title": "Section 10 - Feedback on the Care OBRA Tool",
"title": "Section 10 - Give feedback on Report an outbreak",
"components": [
{
"name": "zTXeZb",
"options": {},
"type": "Para",
"content": "Please provide your feedback.",
"schema": {}
},
{
"name": "S10Q1",
"options": {
"required": true
},
"type": "CheckboxesField",
"title": "S10Q1. How would you describe this risk assessment tool?",
"title": "How would you describe this risk assessment tool?",
"nameHasError": false,
"list": "icNyDJ",
"schema": {},
"hint": "Please note that you can select more than one option"
"hint": "Select all that apply"
},
{
"name": "S10Q2",
"options": {
"required": false,
"optionalText": false,
"conditionalTextBox": {
"dependsOnFieldName": "S10Q1",
"dependsOnFieldValue": "Other (specify below)"
}
},
"type": "MultilineTextField",
"title": "Tell us about any difficulties or highlights you experienced, and how we could improve the service.",
"nameHasError": false,
"schema": {},
"hint": "Do not include any personal information here, for example patient or disease details"
}
],
"next": [
Expand Down Expand Up @@ -1923,13 +1932,25 @@
"name": "icNyDJ",
"type": "string",
"items": [
{
"text": "Useful resource",
"value": "Useful resource"
},
{
"text": "Easy to understand",
"value": "Easy to understand"
},
{
"text": "Easy to complete",
"value": "Easy to complete"
},
{
"text": "Useful resource",
"value": "Useful resource"
"text": "Quick to complete",
"value": "Quick to complete"
},
{
"text": "Some questions were unclear",
"value": "Some questions were unclear"
},
{
"text": "Not detailed enough",
Expand All @@ -1939,21 +1960,13 @@
"text": "Too detailed",
"value": "Too detailed"
},
{
"text": "Quick to complete",
"value": "Quick to complete"
},
{
"text": "Too time consuming",
"value": "Too time consuming"
},
{
"text": "Easy to understand",
"value": "Easy to understand"
},
{
"text": "Some questions were unclear",
"value": "Some questions were unclear"
"text": "Other (specify below)",
"value": "Other (specify below)"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export class CheckboxesField extends SelectionControlField {
let schema = joi.array().single().label(def.title);

if (options.required === false) {
// null or empty string is valid for optional fields
schema = schema
.empty(null)
.items(joi[this.listType]().allow(...this.values, ""));
Expand Down Expand Up @@ -51,7 +50,10 @@ export class CheckboxesField extends SelectionControlField {

getViewModel(formData: FormData, errors: FormSubmissionErrors) {
const viewModel = super.getViewModel(formData, errors);
let formDataItems = (formData[this.name] ?? "").split(",");
let formDataItems = (Array.isArray(formData[this.name])
? formData[this.name].join(",")
: formData[this.name] ?? ""
).split(",");
viewModel.items = (viewModel.items ?? []).map((item) => ({
...item,
checked: !!formDataItems.find((i) => `${item.value}` === i),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { FormComponent } from "./FormComponent";
import { FormData, FormSubmissionErrors } from "../types";
import { FormData, FormPayload, FormSubmissionErrors } from "../types";
import Joi, { Schema, StringSchema } from "joi";
import { MultilineTextFieldComponent } from "@xgovformbuilder/model";
import { FormModel } from "server/plugins/engine/models";
import { MultilineTextFieldViewModel } from "server/plugins/engine/components/types";
import * as helpers from "./helpers";

function inputIsOverWordCount(input, maxWords) {
/**
Expand All @@ -20,6 +21,8 @@ export class MultilineTextField extends FormComponent {
schema: MultilineTextFieldComponent["schema"];
customValidationMessage?: string;
isCharacterOrWordCount: boolean = false;
dependsOnFieldName;
dependsOnFieldValue;

constructor(def: MultilineTextFieldComponent, model: FormModel) {
super(def, model);
Expand All @@ -28,6 +31,10 @@ export class MultilineTextField extends FormComponent {
this.schema = schema;
let componentSchema = Joi.string().label(def.title).required();

componentSchema = componentSchema.custom(
helpers.getCustomCheckboxValidator()
);

if (options.required === false) {
componentSchema = componentSchema.allow("").allow(null);
}
Expand Down Expand Up @@ -63,6 +70,11 @@ export class MultilineTextField extends FormComponent {
);
}

if (options.conditionalTextBox) {
this.dependsOnFieldName = options.conditionalTextBox.dependsOnFieldName;
this.dependsOnFieldValue = options.conditionalTextBox.dependsOnFieldValue;
}

this.formSchema = componentSchema;
}

Expand All @@ -74,6 +86,20 @@ export class MultilineTextField extends FormComponent {
return { [this.name]: this.formSchema as Schema };
}

getStateValueFromValidForm(payload: FormPayload) {
const checkboxSelection = payload[this.dependsOnFieldName];
const textBoxValue = payload[this.name];

if (
checkboxSelection.includes(this.dependsOnFieldValue) &&
textBoxValue === ""
) {
return "empty";
}

return textBoxValue;
}

getViewModel(
formData: FormData,
errors: FormSubmissionErrors
Expand Down
11 changes: 11 additions & 0 deletions runner/src/server/plugins/engine/components/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,17 @@ export function customTextCheckboxValidator(fieldName: string) {
};
}

export function getCustomCheckboxValidator() {
return (value, helpers: joi.CustomHelpers) => {
if (value === "empty") {
return helpers.error("textbox.conditionalFeedback", {
label: helpers.state.key,
});
}
return value;
};
}

export function internationalPhoneValidator(
value: string,
_helpers: joi.CustomHelpers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ const messageTemplate = {
dateDayYear: "{{#label}} must include a day and a year",
dateDayMonth: "{{#label}} must include a day and a month",
dateYear4digits: "The year must include 4 numbers",
dateChronological: "The date that symptoms started in the {{#compLabel}} must be the same as or after the date that symptoms started in the first case",
dateChronological:
"The date that symptoms started in the {{#compLabel}} must be the same as or after the date that symptoms started in the first case",
cqc:
"Enter your CQC location ID or select 'My setting is not registered with the CQC'",
cqcRegex: "Enter a valid CQC Location ID",
conditionalFeedback:
"Give details of any difficulties or highlights you experienced, or how we could improve the service",
};

export const messages: ValidationOptions["messages"] = {
Expand Down Expand Up @@ -69,7 +72,9 @@ export const messages: ValidationOptions["messages"] = {
"date.dayYear": messageTemplate.dateDayYear,
"date.dayMonth": messageTemplate.dateDayMonth,
"date.year4digits": messageTemplate.dateYear4digits,
"date.chronological": messageTemplate.dateChronological
"date.chronological": messageTemplate.dateChronological,

"textbox.conditionalFeedback": messageTemplate.conditionalFeedback,
};

export const validationOptions: ValidationOptions = {
Expand Down