@defra/forms-model 3.0.466 → 3.0.467
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.
- package/dist/module/__stubs__/components.js +151 -39
- package/dist/module/__stubs__/components.js.map +1 -1
- package/dist/module/__stubs__/pages.js +10 -19
- package/dist/module/__stubs__/pages.js.map +1 -1
- package/dist/module/form/form-definition/index.js +15 -1
- package/dist/module/form/form-definition/index.js.map +1 -1
- package/dist/types/__stubs__/components.d.ts +19 -7
- package/dist/types/__stubs__/components.d.ts.map +1 -1
- package/dist/types/__stubs__/pages.d.ts.map +1 -1
- package/dist/types/form/form-definition/index.d.ts +4 -1
- package/dist/types/form/form-definition/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/schemas/form-definition-v2-schema.json +527 -149
- package/schemas/page-schema-v2.json +527 -149
- package/src/__stubs__/components.ts +190 -44
- package/src/__stubs__/pages.ts +10 -18
- package/src/form/form-definition/index.ts +52 -6
@@ -3,10 +3,22 @@ import {
|
|
3
3
|
type AutocompleteFieldComponent,
|
4
4
|
type CheckboxesFieldComponent,
|
5
5
|
type DatePartsFieldComponent,
|
6
|
+
type DetailsComponent,
|
7
|
+
type EmailAddressFieldComponent,
|
6
8
|
type FileUploadFieldComponent,
|
9
|
+
type HtmlComponent,
|
10
|
+
type InsetTextComponent,
|
11
|
+
type ListComponent,
|
12
|
+
type MarkdownComponent,
|
13
|
+
type MonthYearFieldComponent,
|
14
|
+
type MultilineTextFieldComponent,
|
7
15
|
type NumberFieldComponent,
|
8
16
|
type RadiosFieldComponent,
|
9
|
-
type
|
17
|
+
type SelectFieldComponent,
|
18
|
+
type TelephoneNumberFieldComponent,
|
19
|
+
type TextFieldComponent,
|
20
|
+
type UkAddressFieldComponent,
|
21
|
+
type YesNoFieldComponent
|
10
22
|
} from '~/src/components/types.js'
|
11
23
|
import { type Item, type List } from '~/src/form/form-definition/types.js'
|
12
24
|
|
@@ -17,19 +29,169 @@ import { type Item, type List } from '~/src/form/form-definition/types.js'
|
|
17
29
|
export function buildTextFieldComponent(
|
18
30
|
partialTextField: Partial<TextFieldComponent> = {}
|
19
31
|
): TextFieldComponent {
|
20
|
-
|
32
|
+
return {
|
21
33
|
id: '407dd0d7-cce9-4f43-8e1f-7d89cb698875',
|
22
34
|
name: 'TextField',
|
23
35
|
title: 'Text field',
|
24
|
-
type: ComponentType.TextField,
|
25
36
|
hint: '',
|
26
37
|
options: {},
|
27
|
-
schema: {}
|
38
|
+
schema: {},
|
39
|
+
...partialTextField,
|
40
|
+
type: ComponentType.TextField
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
export function buildMultilineTextFieldComponent(
|
45
|
+
partialMultilineTextField: Partial<MultilineTextFieldComponent> = {}
|
46
|
+
): MultilineTextFieldComponent {
|
47
|
+
return {
|
48
|
+
id: '72671f23-552e-4504-a06a-693e240880d5',
|
49
|
+
name: 'MuTeCo',
|
50
|
+
options: {},
|
51
|
+
schema: {},
|
52
|
+
title: 'Multiline TextField Component',
|
53
|
+
...partialMultilineTextField,
|
54
|
+
type: ComponentType.MultilineTextField
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
export function buildYesNoFieldComponent(
|
59
|
+
partialYesNoField: Partial<YesNoFieldComponent> = {}
|
60
|
+
): YesNoFieldComponent {
|
61
|
+
return {
|
62
|
+
title: 'YesNo Field Component',
|
63
|
+
id: 'be7f849c-47d8-4f1f-ba15-ab939dc70914',
|
64
|
+
name: 'YesNoFieldComponent',
|
65
|
+
options: {},
|
66
|
+
...partialYesNoField,
|
67
|
+
type: ComponentType.YesNoField
|
68
|
+
}
|
69
|
+
}
|
70
|
+
export function buildMonthYearFieldComponent(
|
71
|
+
partialMonthYearField: Partial<MonthYearFieldComponent> = {}
|
72
|
+
): MonthYearFieldComponent {
|
73
|
+
return {
|
74
|
+
id: 'd4e99aca-6d13-4c1a-a623-9e9e5b27d46d',
|
75
|
+
title: 'MonthYearFieldComponent',
|
76
|
+
name: 'MonthYearFieldComponent',
|
77
|
+
options: {},
|
78
|
+
...partialMonthYearField,
|
79
|
+
type: ComponentType.MonthYearField
|
80
|
+
}
|
81
|
+
}
|
82
|
+
export function buildSelectFieldComponent(
|
83
|
+
partialSelectField: Partial<SelectFieldComponent> = {}
|
84
|
+
): SelectFieldComponent {
|
85
|
+
return {
|
86
|
+
id: '7f219cf6-3e16-4549-b8df-789506682147',
|
87
|
+
list: '',
|
88
|
+
name: '',
|
89
|
+
options: {},
|
90
|
+
title: '',
|
91
|
+
...partialSelectField,
|
92
|
+
type: ComponentType.SelectField
|
93
|
+
}
|
94
|
+
}
|
95
|
+
export function buildUkAddressFieldComponent(
|
96
|
+
partialUkAddressField: Partial<UkAddressFieldComponent> = {}
|
97
|
+
): UkAddressFieldComponent {
|
98
|
+
return {
|
99
|
+
id: 'a7cb7440-9095-44cd-9136-2914232722c8',
|
100
|
+
title: 'UkAddressFieldComponent',
|
101
|
+
name: 'UkAddressFieldComponent',
|
102
|
+
options: {},
|
103
|
+
...partialUkAddressField,
|
104
|
+
type: ComponentType.UkAddressField
|
105
|
+
}
|
106
|
+
}
|
107
|
+
export function buildTelephoneNumberFieldComponent(
|
108
|
+
partialTelephoneNumberField: Partial<TelephoneNumberFieldComponent> = {}
|
109
|
+
): TelephoneNumberFieldComponent {
|
110
|
+
return {
|
111
|
+
id: '69907916-beac-4faa-b469-656dad5edced',
|
112
|
+
title: 'TelephoneNumberFieldComponent',
|
113
|
+
name: 'TelephoneNumberFieldComponent',
|
114
|
+
options: {},
|
115
|
+
...partialTelephoneNumberField,
|
116
|
+
type: ComponentType.TelephoneNumberField
|
28
117
|
}
|
118
|
+
}
|
119
|
+
export function buildEmailAddressFieldComponent(
|
120
|
+
partialEmailAddressField: Partial<EmailAddressFieldComponent> = {}
|
121
|
+
): EmailAddressFieldComponent {
|
122
|
+
return {
|
123
|
+
id: '9dcf0781-bf34-48c8-b13b-d13050dc34d9',
|
124
|
+
title: 'EmailAddressFieldComponent',
|
125
|
+
name: 'EmailAddressFieldComponent',
|
126
|
+
options: {},
|
127
|
+
...partialEmailAddressField,
|
128
|
+
type: ComponentType.EmailAddressField
|
129
|
+
}
|
130
|
+
}
|
29
131
|
|
132
|
+
export function buildHtmlComponent(
|
133
|
+
partialHtml: Partial<HtmlComponent> = {}
|
134
|
+
): HtmlComponent {
|
135
|
+
return {
|
136
|
+
id: 'bac683ce-149e-4740-95aa-8289b35bc327',
|
137
|
+
title: 'HtmlComponent',
|
138
|
+
name: 'HtmlComponent',
|
139
|
+
options: {},
|
140
|
+
content: '',
|
141
|
+
...partialHtml,
|
142
|
+
type: ComponentType.Html
|
143
|
+
}
|
144
|
+
}
|
145
|
+
export function buildInsetTextComponent(
|
146
|
+
partialInsetText: Partial<InsetTextComponent> = {}
|
147
|
+
): InsetTextComponent {
|
148
|
+
return {
|
149
|
+
id: '6b717151-1e86-42b2-97a9-2201b0676e47',
|
150
|
+
title: 'InsetText Component',
|
151
|
+
name: 'InsetTextComponent',
|
152
|
+
content: '',
|
153
|
+
options: {},
|
154
|
+
...partialInsetText,
|
155
|
+
type: ComponentType.InsetText
|
156
|
+
}
|
157
|
+
}
|
158
|
+
export function buildDetailsComponent(
|
159
|
+
partialDetails: Partial<DetailsComponent> = {}
|
160
|
+
): DetailsComponent {
|
161
|
+
return {
|
162
|
+
id: '245d54df-bb1e-488e-82f6-8f1e42c197e6',
|
163
|
+
title: 'Details Component',
|
164
|
+
name: 'DetailsComponent',
|
165
|
+
content: '',
|
166
|
+
options: {},
|
167
|
+
...partialDetails,
|
168
|
+
type: ComponentType.Details
|
169
|
+
}
|
170
|
+
}
|
171
|
+
export function buildListComponent(
|
172
|
+
partialList: Partial<ListComponent> = {}
|
173
|
+
): ListComponent {
|
30
174
|
return {
|
31
|
-
|
32
|
-
|
175
|
+
id: '62f17168-c2ef-4978-bd42-bdaa5704e25f',
|
176
|
+
title: 'List Component',
|
177
|
+
name: 'ListComponent',
|
178
|
+
list: '',
|
179
|
+
options: {},
|
180
|
+
...partialList,
|
181
|
+
type: ComponentType.List
|
182
|
+
}
|
183
|
+
}
|
184
|
+
export function buildMarkdownComponent(
|
185
|
+
partialMarkdown: Partial<MarkdownComponent> = {}
|
186
|
+
): MarkdownComponent {
|
187
|
+
return {
|
188
|
+
id: '4a2dc88c-be1a-4277-aff8-04220de2e778',
|
189
|
+
title: 'Markdown Component',
|
190
|
+
name: 'MarkdownComponent',
|
191
|
+
options: {},
|
192
|
+
content: '',
|
193
|
+
...partialMarkdown,
|
194
|
+
type: ComponentType.Markdown
|
33
195
|
}
|
34
196
|
}
|
35
197
|
|
@@ -38,19 +200,15 @@ export function buildTextFieldComponent(
|
|
38
200
|
* @returns {FileUploadFieldComponent}
|
39
201
|
*/
|
40
202
|
export function buildFileUploadComponent(
|
41
|
-
partialFileUploadField: Partial<FileUploadFieldComponent>
|
203
|
+
partialFileUploadField: Partial<FileUploadFieldComponent> = {}
|
42
204
|
): FileUploadFieldComponent {
|
43
|
-
|
205
|
+
return {
|
44
206
|
name: 'FileUploadField',
|
45
|
-
type: ComponentType.FileUploadField,
|
46
207
|
title: 'File Upload Field',
|
47
208
|
options: {},
|
48
|
-
schema: {}
|
49
|
-
|
50
|
-
|
51
|
-
return {
|
52
|
-
...fileUploadFieldComponent,
|
53
|
-
...partialFileUploadField
|
209
|
+
schema: {},
|
210
|
+
...partialFileUploadField,
|
211
|
+
type: ComponentType.FileUploadField
|
54
212
|
}
|
55
213
|
}
|
56
214
|
|
@@ -60,19 +218,15 @@ export function buildFileUploadComponent(
|
|
60
218
|
* @returns {AutocompleteFieldComponent}
|
61
219
|
*/
|
62
220
|
export function buildAutoCompleteComponent(
|
63
|
-
partialAutoCompleteField: Partial<AutocompleteFieldComponent>
|
221
|
+
partialAutoCompleteField: Partial<AutocompleteFieldComponent> = {}
|
64
222
|
): AutocompleteFieldComponent {
|
65
|
-
|
223
|
+
return {
|
66
224
|
name: 'AutoCompleteField',
|
67
225
|
title: 'What languages do you speak?',
|
68
|
-
type: ComponentType.AutocompleteField,
|
69
226
|
list: 'AutoCompleteList',
|
70
|
-
options: {}
|
71
|
-
|
72
|
-
|
73
|
-
return {
|
74
|
-
...autocompleteComponent,
|
75
|
-
...partialAutoCompleteField
|
227
|
+
options: {},
|
228
|
+
...partialAutoCompleteField,
|
229
|
+
type: ComponentType.AutocompleteField
|
76
230
|
}
|
77
231
|
}
|
78
232
|
|
@@ -83,17 +237,13 @@ export function buildAutoCompleteComponent(
|
|
83
237
|
export function buildRadioComponent(
|
84
238
|
partialListComponent: Partial<RadiosFieldComponent> = {}
|
85
239
|
): RadiosFieldComponent {
|
86
|
-
|
240
|
+
return {
|
87
241
|
name: 'RadioField',
|
88
242
|
title: 'Which country do you live in?',
|
89
|
-
type: ComponentType.RadiosField,
|
90
243
|
list: 'RadioList',
|
91
|
-
options: {}
|
92
|
-
|
93
|
-
|
94
|
-
return {
|
95
|
-
...radioFieldComponent,
|
96
|
-
...partialListComponent
|
244
|
+
options: {},
|
245
|
+
...partialListComponent,
|
246
|
+
type: ComponentType.RadiosField
|
97
247
|
}
|
98
248
|
}
|
99
249
|
|
@@ -102,19 +252,15 @@ export function buildRadioComponent(
|
|
102
252
|
* @returns {CheckboxesFieldComponent}
|
103
253
|
*/
|
104
254
|
export function buildCheckboxComponent(
|
105
|
-
partialListComponent: Partial<CheckboxesFieldComponent>
|
255
|
+
partialListComponent: Partial<CheckboxesFieldComponent> = {}
|
106
256
|
): CheckboxesFieldComponent {
|
107
|
-
|
257
|
+
return {
|
108
258
|
name: 'FellowshipOfTheRing',
|
109
259
|
title: 'Which are your favourite characters from the fellowship?',
|
110
|
-
type: ComponentType.CheckboxesField,
|
111
260
|
list: 'CheckboxList',
|
112
|
-
options: {}
|
113
|
-
|
114
|
-
|
115
|
-
return {
|
116
|
-
...checkboxesFieldComponent,
|
117
|
-
...partialListComponent
|
261
|
+
options: {},
|
262
|
+
...partialListComponent,
|
263
|
+
type: ComponentType.CheckboxesField
|
118
264
|
}
|
119
265
|
}
|
120
266
|
|
@@ -171,7 +317,7 @@ export function buildList(partialList: Partial<List> = {}): List {
|
|
171
317
|
}
|
172
318
|
|
173
319
|
export function buildNumberFieldComponent(
|
174
|
-
partialComponent: Partial<NumberFieldComponent>
|
320
|
+
partialComponent: Partial<NumberFieldComponent> = {}
|
175
321
|
): NumberFieldComponent {
|
176
322
|
return {
|
177
323
|
name: 'year',
|
@@ -184,7 +330,7 @@ export function buildNumberFieldComponent(
|
|
184
330
|
}
|
185
331
|
|
186
332
|
export function buildDateComponent(
|
187
|
-
partialComponent: Partial<DatePartsFieldComponent>
|
333
|
+
partialComponent: Partial<DatePartsFieldComponent> = {}
|
188
334
|
): DatePartsFieldComponent {
|
189
335
|
return {
|
190
336
|
name: 'bcdefg',
|
@@ -196,7 +342,7 @@ export function buildDateComponent(
|
|
196
342
|
}
|
197
343
|
|
198
344
|
export function buildRadiosComponent(
|
199
|
-
partialComponent: Partial<RadiosFieldComponent>
|
345
|
+
partialComponent: Partial<RadiosFieldComponent> = {}
|
200
346
|
): RadiosFieldComponent {
|
201
347
|
return {
|
202
348
|
name: 'cdefgh',
|
package/src/__stubs__/pages.ts
CHANGED
@@ -33,13 +33,13 @@ export function buildQuestionPage(
|
|
33
33
|
export function buildSummaryPage(
|
34
34
|
partialSummaryPage: Partial<PageSummary> = {}
|
35
35
|
): PageSummary {
|
36
|
-
|
36
|
+
return {
|
37
37
|
id: '449a45f6-4541-4a46-91bd-8b8931b07b50',
|
38
38
|
title: 'Summary page',
|
39
|
+
...partialSummaryPage,
|
39
40
|
path: ControllerPath.Summary,
|
40
41
|
controller: ControllerType.Summary
|
41
42
|
}
|
42
|
-
return { ...pageSummary, ...partialSummaryPage }
|
43
43
|
}
|
44
44
|
|
45
45
|
/**
|
@@ -50,7 +50,7 @@ export function buildSummaryPage(
|
|
50
50
|
export function buildFileUploadPage(
|
51
51
|
partialFileUploadPage: Partial<PageFileUpload> = {}
|
52
52
|
): PageFileUpload {
|
53
|
-
|
53
|
+
return {
|
54
54
|
id: '85e5c8da-88f5-4009-a821-7d7de1364318',
|
55
55
|
title: '',
|
56
56
|
path: '/supporting-evidence',
|
@@ -69,13 +69,9 @@ export function buildFileUploadPage(
|
|
69
69
|
id: '4189b8a1-1a04-4f74-a7a0-dd23012a0ee0'
|
70
70
|
})
|
71
71
|
],
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
return {
|
77
|
-
...fileUploadPage,
|
78
|
-
...partialFileUploadPage
|
72
|
+
next: [],
|
73
|
+
...partialFileUploadPage,
|
74
|
+
controller: ControllerType.FileUpload
|
79
75
|
}
|
80
76
|
}
|
81
77
|
|
@@ -87,7 +83,7 @@ export function buildFileUploadPage(
|
|
87
83
|
export function buildRepeaterPage(
|
88
84
|
partialRepeaterPage: Partial<PageRepeat> = {}
|
89
85
|
): PageRepeat {
|
90
|
-
|
86
|
+
return {
|
91
87
|
title: 'Repeater Page',
|
92
88
|
path: '/repeater-page',
|
93
89
|
components: [
|
@@ -104,15 +100,11 @@ export function buildRepeaterPage(
|
|
104
100
|
],
|
105
101
|
next: [],
|
106
102
|
id: '32888028-61db-40fc-b255-80bc67829d31',
|
107
|
-
controller: ControllerType.Repeat,
|
108
103
|
repeat: {
|
109
104
|
options: { name: 'fawfed', title: 'Simple question responses' },
|
110
105
|
schema: { min: 1, max: 3 }
|
111
|
-
}
|
112
|
-
|
113
|
-
|
114
|
-
return {
|
115
|
-
...repeaterPage,
|
116
|
-
...partialRepeaterPage
|
106
|
+
},
|
107
|
+
...partialRepeaterPage,
|
108
|
+
controller: ControllerType.Repeat
|
117
109
|
}
|
118
110
|
}
|
@@ -2,7 +2,11 @@ import Joi, { type LanguageMessages } from 'joi'
|
|
2
2
|
import { v4 as uuidV4 } from 'uuid'
|
3
3
|
|
4
4
|
import { ComponentType } from '~/src/components/enums.js'
|
5
|
-
import {
|
5
|
+
import {
|
6
|
+
type ComponentDef,
|
7
|
+
type ContentComponentsDef,
|
8
|
+
type FileUploadFieldComponent
|
9
|
+
} from '~/src/components/types.js'
|
6
10
|
import {
|
7
11
|
type ConditionData,
|
8
12
|
type ConditionDataV2,
|
@@ -34,6 +38,7 @@ import {
|
|
34
38
|
type RepeatSchema,
|
35
39
|
type Section
|
36
40
|
} from '~/src/form/form-definition/types.js'
|
41
|
+
import { ControllerType } from '~/src/pages/enums.js'
|
37
42
|
import { hasComponents } from '~/src/pages/helpers.js'
|
38
43
|
|
39
44
|
const idSchemaOptional = Joi.string().uuid()
|
@@ -449,6 +454,26 @@ export const componentSchemaV2 = componentSchema
|
|
449
454
|
})
|
450
455
|
.description('Component schema for V2 forms')
|
451
456
|
|
457
|
+
export const fileUploadComponentSchema = componentSchemaV2.keys({
|
458
|
+
type: Joi.string<ComponentType.FileUploadField>()
|
459
|
+
.trim()
|
460
|
+
.valid(ComponentType.FileUploadField)
|
461
|
+
.required()
|
462
|
+
.description('Component that can only be a FileUploadField')
|
463
|
+
})
|
464
|
+
|
465
|
+
export const contentComponentSchema = componentSchemaV2.keys({
|
466
|
+
type: Joi.string<ComponentType>()
|
467
|
+
.trim()
|
468
|
+
.valid(ComponentType.Details)
|
469
|
+
.valid(ComponentType.Html)
|
470
|
+
.valid(ComponentType.Markdown)
|
471
|
+
.valid(ComponentType.InsetText)
|
472
|
+
.valid(ComponentType.List)
|
473
|
+
.required()
|
474
|
+
.description('Content only component type (Details, Html, Markdown, etc.)')
|
475
|
+
})
|
476
|
+
|
452
477
|
const nextSchema = Joi.object<Link>()
|
453
478
|
.description('Navigation link defining where to go after completing a page')
|
454
479
|
.keys({
|
@@ -549,6 +574,19 @@ const eventsSchema = Joi.object<Events>()
|
|
549
574
|
.description('Event handler triggered when the page data is saved')
|
550
575
|
})
|
551
576
|
|
577
|
+
export const pageUploadComponentsSchema = Joi.array<
|
578
|
+
FileUploadFieldComponent | ContentComponentsDef
|
579
|
+
>()
|
580
|
+
.items(
|
581
|
+
fileUploadComponentSchema.required(),
|
582
|
+
contentComponentSchema.optional()
|
583
|
+
)
|
584
|
+
.unique('name')
|
585
|
+
.unique('id')
|
586
|
+
.min(1)
|
587
|
+
.max(2)
|
588
|
+
.description('Components allowed on Page Upload schema')
|
589
|
+
|
552
590
|
/**
|
553
591
|
* `/status` is a special route for providing a user's application status.
|
554
592
|
* It should not be configured via the designer.
|
@@ -619,11 +657,19 @@ export const pageSchemaV2 = pageSchema
|
|
619
657
|
.description(
|
620
658
|
'Page title displayed at the top of the page (with support for empty titles in V2)'
|
621
659
|
),
|
622
|
-
components: Joi.
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
660
|
+
components: Joi.when('controller', {
|
661
|
+
switch: [
|
662
|
+
{
|
663
|
+
is: Joi.string().trim().valid(ControllerType.FileUpload).required(),
|
664
|
+
then: pageUploadComponentsSchema
|
665
|
+
}
|
666
|
+
],
|
667
|
+
otherwise: Joi.array<ComponentDef>()
|
668
|
+
.items(componentSchemaV2)
|
669
|
+
.unique('name')
|
670
|
+
.unique('id')
|
671
|
+
.description('Components schema for V2 forms')
|
672
|
+
}),
|
627
673
|
condition: Joi.string()
|
628
674
|
.trim()
|
629
675
|
.valid(conditionIdRef)
|