@defra/forms-engine-plugin 4.0.20 → 4.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,9 @@
11
11
  "name": "textField",
12
12
  "title": "Text field",
13
13
  "hint": "Help text",
14
- "options": {},
14
+ "options": {
15
+ "required": false
16
+ },
15
17
  "schema": {}
16
18
  },
17
19
  {
@@ -19,49 +21,63 @@
19
21
  "name": "multilineTextField",
20
22
  "title": "Multiline text field",
21
23
  "hint": "Help text",
22
- "options": {},
24
+ "options": {
25
+ "required": false
26
+ },
23
27
  "schema": {}
24
28
  },
25
29
  {
26
30
  "type": "NumberField",
27
31
  "name": "numberField",
28
32
  "title": "Number field",
29
- "options": {},
33
+ "options": {
34
+ "required": false
35
+ },
30
36
  "schema": {}
31
37
  },
32
38
  {
33
39
  "type": "DatePartsField",
34
40
  "name": "datePartsField",
35
41
  "title": "Date parts field",
36
- "options": {},
42
+ "options": {
43
+ "required": false
44
+ },
37
45
  "schema": {}
38
46
  },
39
47
  {
40
48
  "type": "YesNoField",
41
49
  "name": "yesNoField",
42
50
  "title": "Yes/No field",
43
- "options": {},
51
+ "options": {
52
+ "required": false
53
+ },
44
54
  "schema": {}
45
55
  },
46
56
  {
47
57
  "type": "EmailAddressField",
48
58
  "name": "emailAddressField",
49
59
  "title": "Email address field",
50
- "options": {},
60
+ "options": {
61
+ "required": false
62
+ },
51
63
  "schema": {}
52
64
  },
53
65
  {
54
66
  "type": "TelephoneNumberField",
55
67
  "name": "telephoneNumberField",
56
68
  "title": "Telephone number field",
57
- "options": {},
69
+ "options": {
70
+ "required": false
71
+ },
58
72
  "schema": {}
59
73
  },
60
74
  {
61
75
  "type": "UkAddressField",
62
76
  "name": "addressField",
63
77
  "title": "UK address field",
64
- "options": {},
78
+ "options": {
79
+ "required": false
80
+ },
65
81
  "schema": {}
66
82
  },
67
83
  {
@@ -69,7 +85,9 @@
69
85
  "name": "radiosField",
70
86
  "title": "Radios field",
71
87
  "list": "companyType",
72
- "options": {},
88
+ "options": {
89
+ "required": false
90
+ },
73
91
  "schema": {}
74
92
  },
75
93
  {
@@ -77,17 +95,21 @@
77
95
  "name": "selectField",
78
96
  "title": "Select field",
79
97
  "list": "country",
80
- "options": {},
98
+ "options": {
99
+ "required": false
100
+ },
81
101
  "schema": {}
82
102
  },
83
103
  {
84
- "options": {},
85
104
  "list": "horseBreed",
86
105
  "type": "CheckboxesField",
87
106
  "name": "checkboxesField",
88
107
  "title": "Checkboxes field",
89
108
  "hint": "Please help",
90
- "schema": {}
109
+ "schema": {},
110
+ "options": {
111
+ "required": false
112
+ }
91
113
  },
92
114
  {
93
115
  "type": "Html",
@@ -126,7 +148,10 @@
126
148
  "name": "declaration",
127
149
  "title": "Declaration",
128
150
  "content": "By submitting this form, I agree to:\n\n- Provide accurate and complete information\n- Comply with all applicable regulations\n- Accept responsibility for any false statements",
129
- "hint": "Please read and confirm the following terms"
151
+ "hint": "Please read and confirm the following terms",
152
+ "options": {
153
+ "required": false
154
+ }
130
155
  }
131
156
  ]
132
157
  },
@@ -21,9 +21,8 @@ export declare class DeclarationField extends FormComponent {
21
21
  text: string;
22
22
  } | undefined;
23
23
  fieldset: {
24
- legend: {
25
- text: string;
26
- };
24
+ attributes?: string | Record<string, string>;
25
+ legend?: import("./types.js").Label;
27
26
  };
28
27
  content: string;
29
28
  items: {
@@ -62,22 +62,28 @@ export class DeclarationField extends FormComponent {
62
62
  getViewModel(payload, errors) {
63
63
  const defaultDeclarationConfirmationLabel = 'I confirm that I understand and accept this declaration';
64
64
  const {
65
- title,
66
65
  hint,
67
66
  content,
68
67
  declarationConfirmationLabel = defaultDeclarationConfirmationLabel
69
68
  } = this;
69
+ const viewModel = super.getViewModel(payload, errors);
70
+ let {
71
+ fieldset,
72
+ label
73
+ } = viewModel;
74
+ fieldset ??= {
75
+ legend: {
76
+ text: label.text,
77
+ classes: 'govuk-fieldset__legend--m'
78
+ }
79
+ };
70
80
  const isChecked = payload[this.name] === 'true' || payload[this.name] === true;
71
81
  return {
72
- ...super.getViewModel(payload, errors),
82
+ ...viewModel,
73
83
  hint: hint ? {
74
84
  text: hint
75
85
  } : undefined,
76
- fieldset: {
77
- legend: {
78
- text: title
79
- }
80
- },
86
+ fieldset,
81
87
  content,
82
88
  items: [{
83
89
  text: declarationConfirmationLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"DeclarationField.js","names":["joi","FormComponent","isFormValue","messageTemplate","DeclarationField","DEFAULT_DECLARATION_LABEL","constructor","def","props","options","content","checkboxSchema","string","valid","required","formSchema","array","items","strip","label","single","messages","declarationRequired","stateSchema","boolean","cast","declarationConfirmationLabel","getFormValueFromState","state","name","getFormDataFromState","getStateFromValidForm","payload","payloadValue","value","isValue","length","every","v","getContextValueFromFormValue","getFormValue","undefined","getDisplayStringFromFormValue","getViewModel","errors","defaultDeclarationConfirmationLabel","title","hint","isChecked","text","fieldset","legend","checked","Array","isArray","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","isBool"],"sources":["../../../../../src/server/plugins/engine/components/DeclarationField.ts"],"sourcesContent":["import { type DeclarationFieldComponent, type Item } from '@defra/forms-model'\nimport joi, {\n type ArraySchema,\n type BooleanSchema,\n type StringSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue\n} from '~/src/server/plugins/engine/types.js'\n\nexport class DeclarationField extends FormComponent {\n private readonly DEFAULT_DECLARATION_LABEL = 'I understand and agree'\n\n declare options: DeclarationFieldComponent['options']\n\n declare declarationConfirmationLabel: string\n\n declare formSchema: ArraySchema<StringSchema[]>\n declare stateSchema: BooleanSchema\n declare content: string\n\n constructor(\n def: DeclarationFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, content } = def\n\n let checkboxSchema = joi.string().valid('true')\n\n if (options.required !== false) {\n checkboxSchema = checkboxSchema.required()\n }\n\n const formSchema = joi\n .array()\n .items(checkboxSchema, joi.string().valid('unchecked').strip())\n .label(this.label)\n .single()\n .messages({\n 'any.required': messageTemplate.declarationRequired as string,\n 'any.unknown': messageTemplate.declarationRequired as string,\n 'array.includesRequiredUnknowns':\n messageTemplate.declarationRequired as string\n }) as ArraySchema<StringSchema[]>\n\n this.formSchema = formSchema\n this.stateSchema = joi.boolean().cast('string').label(this.label).required()\n\n this.options = options\n this.content = content\n this.declarationConfirmationLabel =\n options.declarationConfirmationLabel ?? this.DEFAULT_DECLARATION_LABEL\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return state[name] === true ? 'true' : 'false'\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { name } = this\n return { [name]: state[name] === true ? 'true' : 'false' }\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { name } = this\n const payloadValue = payload[name]\n const value =\n this.isValue(payloadValue) &&\n payloadValue.length > 0 &&\n payloadValue.every((v) => {\n return v === 'true'\n })\n\n return { [name]: value }\n }\n\n getContextValueFromFormValue(value: FormValue | FormPayload): boolean {\n return value === 'true'\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(value: FormValue | FormPayload): string {\n return value === 'true' ? this.declarationConfirmationLabel : 'Not provided'\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const defaultDeclarationConfirmationLabel =\n 'I confirm that I understand and accept this declaration'\n const {\n title,\n hint,\n content,\n declarationConfirmationLabel = defaultDeclarationConfirmationLabel\n } = this\n const isChecked =\n payload[this.name] === 'true' || payload[this.name] === true\n return {\n ...super.getViewModel(payload, errors),\n hint: hint ? { text: hint } : undefined,\n fieldset: {\n legend: {\n text: title\n }\n },\n content,\n items: [\n {\n text: declarationConfirmationLabel,\n value: 'true',\n checked: isChecked\n }\n ]\n }\n }\n\n isValue(value?: FormStateValue | FormState): value is Item['value'][] {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isFormValue)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return DeclarationField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.declarationRequired }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isBool(value?: FormStateValue | FormState): value is boolean {\n return isFormValue(value) && typeof value === 'boolean'\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"DeclarationField.js","names":["joi","FormComponent","isFormValue","messageTemplate","DeclarationField","DEFAULT_DECLARATION_LABEL","constructor","def","props","options","content","checkboxSchema","string","valid","required","formSchema","array","items","strip","label","single","messages","declarationRequired","stateSchema","boolean","cast","declarationConfirmationLabel","getFormValueFromState","state","name","getFormDataFromState","getStateFromValidForm","payload","payloadValue","value","isValue","length","every","v","getContextValueFromFormValue","getFormValue","undefined","getDisplayStringFromFormValue","getViewModel","errors","defaultDeclarationConfirmationLabel","hint","viewModel","fieldset","legend","text","classes","isChecked","checked","Array","isArray","getAllPossibleErrors","baseErrors","type","template","advancedSettingsErrors","isBool"],"sources":["../../../../../src/server/plugins/engine/components/DeclarationField.ts"],"sourcesContent":["import { type DeclarationFieldComponent, type Item } from '@defra/forms-model'\nimport joi, {\n type ArraySchema,\n type BooleanSchema,\n type StringSchema\n} from 'joi'\n\nimport {\n FormComponent,\n isFormValue\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n type ErrorMessageTemplateList,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue\n} from '~/src/server/plugins/engine/types.js'\n\nexport class DeclarationField extends FormComponent {\n private readonly DEFAULT_DECLARATION_LABEL = 'I understand and agree'\n\n declare options: DeclarationFieldComponent['options']\n\n declare declarationConfirmationLabel: string\n\n declare formSchema: ArraySchema<StringSchema[]>\n declare stateSchema: BooleanSchema\n declare content: string\n\n constructor(\n def: DeclarationFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, content } = def\n\n let checkboxSchema = joi.string().valid('true')\n\n if (options.required !== false) {\n checkboxSchema = checkboxSchema.required()\n }\n\n const formSchema = joi\n .array()\n .items(checkboxSchema, joi.string().valid('unchecked').strip())\n .label(this.label)\n .single()\n .messages({\n 'any.required': messageTemplate.declarationRequired as string,\n 'any.unknown': messageTemplate.declarationRequired as string,\n 'array.includesRequiredUnknowns':\n messageTemplate.declarationRequired as string\n }) as ArraySchema<StringSchema[]>\n\n this.formSchema = formSchema\n this.stateSchema = joi.boolean().cast('string').label(this.label).required()\n\n this.options = options\n this.content = content\n this.declarationConfirmationLabel =\n options.declarationConfirmationLabel ?? this.DEFAULT_DECLARATION_LABEL\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return state[name] === true ? 'true' : 'false'\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { name } = this\n return { [name]: state[name] === true ? 'true' : 'false' }\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { name } = this\n const payloadValue = payload[name]\n const value =\n this.isValue(payloadValue) &&\n payloadValue.length > 0 &&\n payloadValue.every((v) => {\n return v === 'true'\n })\n\n return { [name]: value }\n }\n\n getContextValueFromFormValue(value: FormValue | FormPayload): boolean {\n return value === 'true'\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(value: FormValue | FormPayload): string {\n return value === 'true' ? this.declarationConfirmationLabel : 'Not provided'\n }\n\n getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {\n const defaultDeclarationConfirmationLabel =\n 'I confirm that I understand and accept this declaration'\n const {\n hint,\n content,\n declarationConfirmationLabel = defaultDeclarationConfirmationLabel\n } = this\n\n const viewModel = super.getViewModel(payload, errors)\n let { fieldset, label } = viewModel\n\n fieldset ??= {\n legend: {\n text: label.text,\n classes: 'govuk-fieldset__legend--m'\n }\n }\n\n const isChecked =\n payload[this.name] === 'true' || payload[this.name] === true\n return {\n ...viewModel,\n hint: hint ? { text: hint } : undefined,\n fieldset,\n content,\n items: [\n {\n text: declarationConfirmationLabel,\n value: 'true',\n checked: isChecked\n }\n ]\n }\n }\n\n isValue(value?: FormStateValue | FormState): value is Item['value'][] {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isFormValue)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return DeclarationField.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'required', template: messageTemplate.declarationRequired }\n ],\n advancedSettingsErrors: []\n }\n }\n\n static isBool(value?: FormStateValue | FormState): value is boolean {\n return isFormValue(value) && typeof value === 'boolean'\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -41,10 +41,10 @@
41
41
  <form method="post" novalidate>
42
42
  <input type="hidden" name="crumb" value="{{ crumb }}">
43
43
 
44
- {{ componentList(components) }}
45
-
46
44
  {% block customPageContent %}{% endblock %}
47
45
 
46
+ {{ componentList(components) }}
47
+
48
48
  {% if declaration %}
49
49
  <h2 class="govuk-heading-m" id="declaration">Declaration</h2>
50
50
  <div class="govuk-body">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defra/forms-engine-plugin",
3
- "version": "4.0.20",
3
+ "version": "4.0.22",
4
4
  "description": "Defra forms engine",
5
5
  "type": "module",
6
6
  "files": [
@@ -11,7 +11,9 @@
11
11
  "name": "textField",
12
12
  "title": "Text field",
13
13
  "hint": "Help text",
14
- "options": {},
14
+ "options": {
15
+ "required": false
16
+ },
15
17
  "schema": {}
16
18
  },
17
19
  {
@@ -19,49 +21,63 @@
19
21
  "name": "multilineTextField",
20
22
  "title": "Multiline text field",
21
23
  "hint": "Help text",
22
- "options": {},
24
+ "options": {
25
+ "required": false
26
+ },
23
27
  "schema": {}
24
28
  },
25
29
  {
26
30
  "type": "NumberField",
27
31
  "name": "numberField",
28
32
  "title": "Number field",
29
- "options": {},
33
+ "options": {
34
+ "required": false
35
+ },
30
36
  "schema": {}
31
37
  },
32
38
  {
33
39
  "type": "DatePartsField",
34
40
  "name": "datePartsField",
35
41
  "title": "Date parts field",
36
- "options": {},
42
+ "options": {
43
+ "required": false
44
+ },
37
45
  "schema": {}
38
46
  },
39
47
  {
40
48
  "type": "YesNoField",
41
49
  "name": "yesNoField",
42
50
  "title": "Yes/No field",
43
- "options": {},
51
+ "options": {
52
+ "required": false
53
+ },
44
54
  "schema": {}
45
55
  },
46
56
  {
47
57
  "type": "EmailAddressField",
48
58
  "name": "emailAddressField",
49
59
  "title": "Email address field",
50
- "options": {},
60
+ "options": {
61
+ "required": false
62
+ },
51
63
  "schema": {}
52
64
  },
53
65
  {
54
66
  "type": "TelephoneNumberField",
55
67
  "name": "telephoneNumberField",
56
68
  "title": "Telephone number field",
57
- "options": {},
69
+ "options": {
70
+ "required": false
71
+ },
58
72
  "schema": {}
59
73
  },
60
74
  {
61
75
  "type": "UkAddressField",
62
76
  "name": "addressField",
63
77
  "title": "UK address field",
64
- "options": {},
78
+ "options": {
79
+ "required": false
80
+ },
65
81
  "schema": {}
66
82
  },
67
83
  {
@@ -69,7 +85,9 @@
69
85
  "name": "radiosField",
70
86
  "title": "Radios field",
71
87
  "list": "companyType",
72
- "options": {},
88
+ "options": {
89
+ "required": false
90
+ },
73
91
  "schema": {}
74
92
  },
75
93
  {
@@ -77,17 +95,21 @@
77
95
  "name": "selectField",
78
96
  "title": "Select field",
79
97
  "list": "country",
80
- "options": {},
98
+ "options": {
99
+ "required": false
100
+ },
81
101
  "schema": {}
82
102
  },
83
103
  {
84
- "options": {},
85
104
  "list": "horseBreed",
86
105
  "type": "CheckboxesField",
87
106
  "name": "checkboxesField",
88
107
  "title": "Checkboxes field",
89
108
  "hint": "Please help",
90
- "schema": {}
109
+ "schema": {},
110
+ "options": {
111
+ "required": false
112
+ }
91
113
  },
92
114
  {
93
115
  "type": "Html",
@@ -126,7 +148,10 @@
126
148
  "name": "declaration",
127
149
  "title": "Declaration",
128
150
  "content": "By submitting this form, I agree to:\n\n- Provide accurate and complete information\n- Comply with all applicable regulations\n- Accept responsibility for any false statements",
129
- "hint": "Please read and confirm the following terms"
151
+ "hint": "Please read and confirm the following terms",
152
+ "options": {
153
+ "required": false
154
+ }
130
155
  }
131
156
  ]
132
157
  },
@@ -250,7 +250,8 @@ describe('DeclarationField', () => {
250
250
  id: 'myComponent',
251
251
  fieldset: {
252
252
  legend: {
253
- text: 'Example Declaration Component'
253
+ text: 'Example Declaration Component',
254
+ classes: 'govuk-fieldset__legend--m'
254
255
  }
255
256
  },
256
257
  items: [
@@ -105,21 +105,27 @@ export class DeclarationField extends FormComponent {
105
105
  const defaultDeclarationConfirmationLabel =
106
106
  'I confirm that I understand and accept this declaration'
107
107
  const {
108
- title,
109
108
  hint,
110
109
  content,
111
110
  declarationConfirmationLabel = defaultDeclarationConfirmationLabel
112
111
  } = this
112
+
113
+ const viewModel = super.getViewModel(payload, errors)
114
+ let { fieldset, label } = viewModel
115
+
116
+ fieldset ??= {
117
+ legend: {
118
+ text: label.text,
119
+ classes: 'govuk-fieldset__legend--m'
120
+ }
121
+ }
122
+
113
123
  const isChecked =
114
124
  payload[this.name] === 'true' || payload[this.name] === true
115
125
  return {
116
- ...super.getViewModel(payload, errors),
126
+ ...viewModel,
117
127
  hint: hint ? { text: hint } : undefined,
118
- fieldset: {
119
- legend: {
120
- text: title
121
- }
122
- },
128
+ fieldset,
123
129
  content,
124
130
  items: [
125
131
  {
@@ -582,7 +582,8 @@ describe('QuestionPageController', () => {
582
582
  checkboxesMultiple: [],
583
583
  checkboxesSingleNumber: [],
584
584
  checkboxesMultipleNumber: [],
585
- fileUpload: null
585
+ fileUpload: null,
586
+ declaration: false
586
587
  })
587
588
 
588
589
  Object.assign(state, {
@@ -609,7 +610,8 @@ describe('QuestionPageController', () => {
609
610
  checkboxesSingle: ['Shetland'],
610
611
  checkboxesMultiple: ['Arabian', 'Shire', 'Race'],
611
612
  checkboxesSingleNumber: [1],
612
- checkboxesMultipleNumber: [0, 1]
613
+ checkboxesMultipleNumber: [0, 1],
614
+ declaration: true
613
615
  })
614
616
 
615
617
  request = buildFormContextRequest({
@@ -657,7 +659,8 @@ describe('QuestionPageController', () => {
657
659
  checkboxesMultiple: ['Arabian', 'Shire', 'Race'],
658
660
  checkboxesSingleNumber: [1],
659
661
  checkboxesMultipleNumber: [0, 1],
660
- fileUpload: null
662
+ fileUpload: null,
663
+ declaration: true
661
664
  })
662
665
 
663
666
  Object.assign(state, {
@@ -729,7 +732,8 @@ describe('QuestionPageController', () => {
729
732
  checkboxesMultiple: ['Arabian', 'Shire', 'Race'],
730
733
  checkboxesSingleNumber: [1],
731
734
  checkboxesMultipleNumber: [0, 1],
732
- fileUpload: ['fd5db541-179c-4107-a4d0-149d09672ffc']
735
+ fileUpload: ['fd5db541-179c-4107-a4d0-149d09672ffc'],
736
+ declaration: true
733
737
  })
734
738
  })
735
739
  })
@@ -41,10 +41,10 @@
41
41
  <form method="post" novalidate>
42
42
  <input type="hidden" name="crumb" value="{{ crumb }}">
43
43
 
44
- {{ componentList(components) }}
45
-
46
44
  {% block customPageContent %}{% endblock %}
47
45
 
46
+ {{ componentList(components) }}
47
+
48
48
  {% if declaration %}
49
49
  <h2 class="govuk-heading-m" id="declaration">Declaration</h2>
50
50
  <div class="govuk-body">