@remoteoss/json-schema-form 0.1.0-beta.0
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/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/dist/index.cjs +1207 -0
- package/dist/index.js +1176 -0
- package/dist/standalone.js +12580 -0
- package/package.json +79 -0
- package/src/tests/createHeadlessForm.customValidations.test.jsx +799 -0
- package/src/tests/createHeadlessForm.test.js +3343 -0
- package/src/tests/helpers.custom.js +223 -0
- package/src/tests/helpers.js +1983 -0
- package/src/tests/internals.helpers.test.js +175 -0
- package/src/tests/utils.test.jsx +32 -0
|
@@ -0,0 +1,1983 @@
|
|
|
1
|
+
// -------------------------------------
|
|
2
|
+
// ----------- Inputs Schema -----------
|
|
3
|
+
// -------------------------------------
|
|
4
|
+
|
|
5
|
+
export const mockTextInput = {
|
|
6
|
+
title: 'ID number',
|
|
7
|
+
description: 'The number of your national identification (max 10 digits)',
|
|
8
|
+
maxLength: 10,
|
|
9
|
+
'x-jsf-presentation': {
|
|
10
|
+
inputType: 'text',
|
|
11
|
+
maskSecret: 2,
|
|
12
|
+
},
|
|
13
|
+
type: 'string',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const mockTextInputDeprecated = {
|
|
17
|
+
title: 'ID number',
|
|
18
|
+
description: 'The number of your national identification (max 10 digits)',
|
|
19
|
+
maxLength: 10,
|
|
20
|
+
presentation: {
|
|
21
|
+
inputType: 'text',
|
|
22
|
+
maskSecret: 2,
|
|
23
|
+
},
|
|
24
|
+
type: 'string',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const mockTextareaInput = {
|
|
28
|
+
title: 'Comment',
|
|
29
|
+
description: 'Explain how was the organization of the event.',
|
|
30
|
+
'x-jsf-presentation': {
|
|
31
|
+
inputType: 'textarea',
|
|
32
|
+
placeholder: 'Leave your comment...',
|
|
33
|
+
},
|
|
34
|
+
maximum: 250,
|
|
35
|
+
type: 'string',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const mockNumberInput = {
|
|
39
|
+
title: 'Tabs',
|
|
40
|
+
description: 'How many open tabs do you have?',
|
|
41
|
+
'x-jsf-presentation': {
|
|
42
|
+
inputType: 'number',
|
|
43
|
+
},
|
|
44
|
+
minimum: 1,
|
|
45
|
+
maximum: 10,
|
|
46
|
+
type: 'number',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const mockNumberInputWithPercentage = {
|
|
50
|
+
title: 'Shares',
|
|
51
|
+
description: 'What % of shares do you own?',
|
|
52
|
+
'x-jsf-presentation': {
|
|
53
|
+
inputType: 'number',
|
|
54
|
+
percentage: true,
|
|
55
|
+
},
|
|
56
|
+
minimum: 1,
|
|
57
|
+
maximum: 100,
|
|
58
|
+
type: 'number',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const mockNumberInputWithPercentageAndCustomRange = {
|
|
62
|
+
...mockNumberInputWithPercentage,
|
|
63
|
+
minimum: 50,
|
|
64
|
+
maximum: 70,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const mockTextPatternInput = {
|
|
68
|
+
...mockTextInput,
|
|
69
|
+
maxLength: 11,
|
|
70
|
+
pattern: '^[0-9]{3}-[0-9]{2}-(?!0{4})[0-9]{4}$',
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const mockTextMaxLengthInput = {
|
|
74
|
+
...mockTextInput,
|
|
75
|
+
maxLength: 10,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const mockRadioInputDeprecated = {
|
|
79
|
+
title: 'Has siblings',
|
|
80
|
+
description: 'Do you have any siblings?',
|
|
81
|
+
enum: ['yes', 'no'],
|
|
82
|
+
'x-jsf-presentation': {
|
|
83
|
+
inputType: 'radio',
|
|
84
|
+
options: [
|
|
85
|
+
{
|
|
86
|
+
label: 'Yes',
|
|
87
|
+
value: 'yes',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
label: 'No',
|
|
91
|
+
value: 'no',
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const mockRadioInput = {
|
|
98
|
+
title: 'Has siblings',
|
|
99
|
+
description: 'Do you have any siblings?',
|
|
100
|
+
oneOf: [
|
|
101
|
+
{
|
|
102
|
+
const: 'yes',
|
|
103
|
+
title: 'Yes',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
const: 'no',
|
|
107
|
+
title: 'No',
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
'x-jsf-presentation': {
|
|
111
|
+
inputType: 'radio',
|
|
112
|
+
},
|
|
113
|
+
type: 'string',
|
|
114
|
+
};
|
|
115
|
+
export const mockRadioInputOptional = {
|
|
116
|
+
title: 'Has car',
|
|
117
|
+
description: 'Do you have a car? (optional field, check oneOf)',
|
|
118
|
+
oneOf: [
|
|
119
|
+
{
|
|
120
|
+
const: null, // The option is excluded from the jsf options.
|
|
121
|
+
title: 'N/A',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
const: 'yes',
|
|
125
|
+
title: 'Yes',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
const: 'no',
|
|
129
|
+
title: 'No',
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
'x-jsf-presentation': {
|
|
133
|
+
inputType: 'radio',
|
|
134
|
+
},
|
|
135
|
+
type: ['string', 'null'],
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const mockRadioCardExpandableInput = {
|
|
139
|
+
title: 'Experience level',
|
|
140
|
+
description:
|
|
141
|
+
'Please select the experience level that aligns with this role based on the job description (not the employees overall experience)',
|
|
142
|
+
oneOf: [
|
|
143
|
+
{
|
|
144
|
+
const: 'junior',
|
|
145
|
+
title: 'Junior level',
|
|
146
|
+
description:
|
|
147
|
+
'Entry level employees who perform tasks under the supervision of a more experienced employee.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
const: 'mid',
|
|
151
|
+
title: 'Mid level',
|
|
152
|
+
description:
|
|
153
|
+
'Employees who perform tasks with a good degree of autonomy and/or with coordination and control functions.',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
const: 'senior',
|
|
157
|
+
title: 'Senior level',
|
|
158
|
+
description:
|
|
159
|
+
'Employees who perform tasks with a high degree of autonomy and/or with coordination and control functions.',
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
'x-jsf-presentation': {
|
|
163
|
+
inputType: 'radio',
|
|
164
|
+
variant: 'card-expandable',
|
|
165
|
+
},
|
|
166
|
+
type: 'string',
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const mockRadioCardInput = {
|
|
170
|
+
title: 'Payment method',
|
|
171
|
+
description: 'Chose how you want to be paid',
|
|
172
|
+
oneOf: [
|
|
173
|
+
{
|
|
174
|
+
const: 'cc',
|
|
175
|
+
title: 'Credit Card',
|
|
176
|
+
description: 'Plastic money, which is still money',
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
const: 'cash',
|
|
180
|
+
title: 'Cash',
|
|
181
|
+
description: 'Rules Everything Around Me',
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
'x-jsf-presentation': {
|
|
185
|
+
inputType: 'radio',
|
|
186
|
+
variant: 'card',
|
|
187
|
+
},
|
|
188
|
+
type: 'string',
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export const mockSelectInputSoloDeprecated = {
|
|
192
|
+
title: 'Benefits (solo)',
|
|
193
|
+
description: 'Life Insurance',
|
|
194
|
+
items: {
|
|
195
|
+
enum: ['Medical Insurance, Health Insurance', 'Travel Bonus'],
|
|
196
|
+
},
|
|
197
|
+
'x-jsf-presentation': {
|
|
198
|
+
inputType: 'select',
|
|
199
|
+
options: [
|
|
200
|
+
{
|
|
201
|
+
label: 'Medical Insurance',
|
|
202
|
+
value: 'Medical Insurance',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
label: 'Health Insurance',
|
|
206
|
+
value: 'Health Insurance',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
label: 'Travel Bonus',
|
|
210
|
+
value: 'Travel Bonus',
|
|
211
|
+
disabled: true,
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
placeholder: 'Select...',
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export const mockSelectInputMultipleDeprecated = {
|
|
219
|
+
...mockSelectInputSoloDeprecated,
|
|
220
|
+
title: 'Benefits (multiple)',
|
|
221
|
+
type: 'array',
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export const mockSelectInputSolo = {
|
|
225
|
+
title: 'Browsers (solo)',
|
|
226
|
+
description: 'This solo select also includes a disabled option.',
|
|
227
|
+
type: 'string',
|
|
228
|
+
oneOf: [
|
|
229
|
+
{
|
|
230
|
+
const: 'chr',
|
|
231
|
+
title: 'Chrome',
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
const: 'ff',
|
|
235
|
+
title: 'Firefox',
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
const: 'ie',
|
|
239
|
+
title: 'Internet Explorer',
|
|
240
|
+
disabled: true,
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
'x-jsf-presentation': {
|
|
244
|
+
inputType: 'select',
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export const mockSelectInputMultiple = {
|
|
249
|
+
title: 'Browsers (multiple)',
|
|
250
|
+
description: 'This multi-select also includes a disabled option.',
|
|
251
|
+
type: 'array',
|
|
252
|
+
uniqueItems: true,
|
|
253
|
+
items: {
|
|
254
|
+
anyOf: [
|
|
255
|
+
{
|
|
256
|
+
const: 'chr',
|
|
257
|
+
title: 'Chrome',
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
const: 'ff',
|
|
261
|
+
title: 'Firefox',
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
value: 'ie',
|
|
265
|
+
label: 'Internet Explorer',
|
|
266
|
+
disabled: true,
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
'x-jsf-presentation': {
|
|
271
|
+
inputType: 'select',
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
export const mockSelectInputMultipleOptional = {
|
|
276
|
+
...mockSelectInputMultiple,
|
|
277
|
+
title: 'Browsers (multiple) (optional)',
|
|
278
|
+
description: 'This optional multi-select also includes a disabled option.',
|
|
279
|
+
type: ['array', 'null'],
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
export const mockDateInput = {
|
|
283
|
+
'x-jsf-presentation': {
|
|
284
|
+
inputType: 'date',
|
|
285
|
+
maxDate: '2022-03-01',
|
|
286
|
+
minDate: '1922-03-01',
|
|
287
|
+
},
|
|
288
|
+
title: 'Birthdate',
|
|
289
|
+
type: 'string',
|
|
290
|
+
format: 'date',
|
|
291
|
+
maxLength: 10,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
export const mockFileInput = {
|
|
295
|
+
description: 'File Input Description',
|
|
296
|
+
'x-jsf-presentation': {
|
|
297
|
+
inputType: 'file',
|
|
298
|
+
accept: '.png,.jpg,.jpeg,.pdf',
|
|
299
|
+
maxFileSize: 20480,
|
|
300
|
+
fileDownload: 'http://some.domain.com/file-name.pdf',
|
|
301
|
+
fileName: 'My File',
|
|
302
|
+
},
|
|
303
|
+
title: 'File Input',
|
|
304
|
+
type: 'string',
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
export const mockFileInputWithSkippable = {
|
|
308
|
+
...mockFileInput,
|
|
309
|
+
'x-jsf-presentation': {
|
|
310
|
+
...mockFileInput['x-jsf-presentation'],
|
|
311
|
+
skippableLabel: 'This document does not apply to my profile.',
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
export const mockFileInputWithAllowLaterUpload = {
|
|
316
|
+
...mockFileInput,
|
|
317
|
+
title: 'File skippable',
|
|
318
|
+
'x-jsf-presentation': {
|
|
319
|
+
...mockFileInput['x-jsf-presentation'],
|
|
320
|
+
skippableLabel: "I don't have this document yet.",
|
|
321
|
+
description:
|
|
322
|
+
'File input, with attribute "allowLaterUpload". This tells the API to mark the file as skipped so that it is asked again later in the process.',
|
|
323
|
+
allowLaterUpload: true,
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
export const mockFieldset = {
|
|
328
|
+
title: 'Fieldset title',
|
|
329
|
+
description: 'Fieldset description',
|
|
330
|
+
'x-jsf-presentation': {
|
|
331
|
+
inputType: 'fieldset',
|
|
332
|
+
},
|
|
333
|
+
properties: {
|
|
334
|
+
id_number: mockTextInput,
|
|
335
|
+
tabs: mockNumberInput,
|
|
336
|
+
},
|
|
337
|
+
required: ['id_number'],
|
|
338
|
+
type: 'object',
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
export const mockFocusedFieldset = {
|
|
342
|
+
title: 'Focused fieldset title',
|
|
343
|
+
description: 'Focused fieldset description',
|
|
344
|
+
'x-jsf-presentation': {
|
|
345
|
+
inputType: 'fieldset',
|
|
346
|
+
variant: 'focused',
|
|
347
|
+
},
|
|
348
|
+
properties: {
|
|
349
|
+
id_number: mockTextInput,
|
|
350
|
+
tabs: mockNumberInput,
|
|
351
|
+
},
|
|
352
|
+
required: ['id_number'],
|
|
353
|
+
type: 'object',
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
export const mockNestedFieldset = {
|
|
357
|
+
title: 'Nested fieldset title',
|
|
358
|
+
description: 'Nested fieldset description',
|
|
359
|
+
'x-jsf-presentation': {
|
|
360
|
+
inputType: 'fieldset',
|
|
361
|
+
},
|
|
362
|
+
properties: {
|
|
363
|
+
innerFieldset: mockFieldset,
|
|
364
|
+
},
|
|
365
|
+
type: 'object',
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
export const mockGroupArrayInput = {
|
|
369
|
+
items: {
|
|
370
|
+
properties: {
|
|
371
|
+
birthdate: {
|
|
372
|
+
description: 'Enter your child’s date of birth',
|
|
373
|
+
format: 'date',
|
|
374
|
+
'x-jsf-presentation': {
|
|
375
|
+
inputType: 'date',
|
|
376
|
+
},
|
|
377
|
+
title: 'Child Birthdate',
|
|
378
|
+
type: 'string',
|
|
379
|
+
maxLength: 255,
|
|
380
|
+
},
|
|
381
|
+
full_name: {
|
|
382
|
+
description: 'Enter your child’s full name',
|
|
383
|
+
'x-jsf-presentation': {
|
|
384
|
+
inputType: 'text',
|
|
385
|
+
},
|
|
386
|
+
title: 'Child Full Name',
|
|
387
|
+
type: 'string',
|
|
388
|
+
maxLength: 255,
|
|
389
|
+
},
|
|
390
|
+
sex: {
|
|
391
|
+
description:
|
|
392
|
+
'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
|
|
393
|
+
enum: ['female', 'male'],
|
|
394
|
+
'x-jsf-presentation': {
|
|
395
|
+
inputType: 'radio',
|
|
396
|
+
options: [
|
|
397
|
+
{
|
|
398
|
+
label: 'Male',
|
|
399
|
+
value: 'male',
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
label: 'Female',
|
|
403
|
+
value: 'female',
|
|
404
|
+
},
|
|
405
|
+
],
|
|
406
|
+
},
|
|
407
|
+
title: 'Child Sex',
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
'x-jsf-order': ['full_name', 'birthdate', 'sex'],
|
|
411
|
+
required: ['full_name', 'birthdate', 'sex'],
|
|
412
|
+
type: 'object',
|
|
413
|
+
},
|
|
414
|
+
'x-jsf-presentation': {
|
|
415
|
+
inputType: 'group-array',
|
|
416
|
+
addFieldText: 'Add new field',
|
|
417
|
+
},
|
|
418
|
+
title: 'Child details',
|
|
419
|
+
description: 'Add the dependents you claim below',
|
|
420
|
+
type: 'array',
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const simpleGroupArrayInput = {
|
|
424
|
+
items: {
|
|
425
|
+
properties: {
|
|
426
|
+
full_name: {
|
|
427
|
+
description: 'Enter your child’s full name',
|
|
428
|
+
'x-jsf-presentation': {
|
|
429
|
+
inputType: 'text',
|
|
430
|
+
},
|
|
431
|
+
title: 'Child Full Name',
|
|
432
|
+
type: 'string',
|
|
433
|
+
maxLength: 255,
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
required: ['full_name'],
|
|
437
|
+
type: 'object',
|
|
438
|
+
},
|
|
439
|
+
'x-jsf-presentation': {
|
|
440
|
+
inputType: 'group-array',
|
|
441
|
+
},
|
|
442
|
+
title: 'Child names',
|
|
443
|
+
description: 'Add the dependents names',
|
|
444
|
+
type: 'array',
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
export const mockOptionalGroupArrayInput = {
|
|
448
|
+
...mockGroupArrayInput,
|
|
449
|
+
title: 'Child details (optional)',
|
|
450
|
+
description:
|
|
451
|
+
'This is an optional group-array. For a better UX, this Component asks a Yes/No question before allowing to add new field entries.',
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
export const mockEmailInput = {
|
|
455
|
+
title: 'Email address',
|
|
456
|
+
description: 'Enter your email address',
|
|
457
|
+
maxLength: 255,
|
|
458
|
+
format: 'email',
|
|
459
|
+
'x-jsf-presentation': {
|
|
460
|
+
inputType: 'email',
|
|
461
|
+
},
|
|
462
|
+
type: 'string',
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
export const mockCheckboxInput = {
|
|
466
|
+
const: 'Permanent',
|
|
467
|
+
description: 'I acknowledge that all employees in France will be hired on indefinite contracts.',
|
|
468
|
+
'x-jsf-presentation': {
|
|
469
|
+
inputType: 'checkbox',
|
|
470
|
+
},
|
|
471
|
+
title: 'Contract duration',
|
|
472
|
+
type: 'string',
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Compose a schema with lower chance of human error
|
|
477
|
+
* @param {Object} schema version
|
|
478
|
+
* @returns {Object} A JSON schema
|
|
479
|
+
* @example
|
|
480
|
+
* JSONSchemaBuilder().addInput({
|
|
481
|
+
id_number: mockTextInput,
|
|
482
|
+
})
|
|
483
|
+
.build();
|
|
484
|
+
*/
|
|
485
|
+
export function JSONSchemaBuilder() {
|
|
486
|
+
return {
|
|
487
|
+
addInput: function addInput(input) {
|
|
488
|
+
this.properties = {
|
|
489
|
+
...this.properties,
|
|
490
|
+
...input,
|
|
491
|
+
};
|
|
492
|
+
return this;
|
|
493
|
+
},
|
|
494
|
+
setRequiredFields: function setRequiredFields(required) {
|
|
495
|
+
this.requiredFields = required;
|
|
496
|
+
return this;
|
|
497
|
+
},
|
|
498
|
+
setOrder: function setOrder(order) {
|
|
499
|
+
this['x-jsf-order'] = order;
|
|
500
|
+
return this;
|
|
501
|
+
},
|
|
502
|
+
addAnyOf: function addAnyOf(items) {
|
|
503
|
+
this.anyOf = items;
|
|
504
|
+
|
|
505
|
+
return this;
|
|
506
|
+
},
|
|
507
|
+
addAllOf: function addAllOf(items) {
|
|
508
|
+
this.allOf = items;
|
|
509
|
+
|
|
510
|
+
return this;
|
|
511
|
+
},
|
|
512
|
+
addCondition: function addCondition(ifCondition, thenBranch, elseBranch) {
|
|
513
|
+
this.if = ifCondition;
|
|
514
|
+
this.then = thenBranch;
|
|
515
|
+
this.else = elseBranch;
|
|
516
|
+
return this;
|
|
517
|
+
},
|
|
518
|
+
build: function build() {
|
|
519
|
+
return {
|
|
520
|
+
type: 'object',
|
|
521
|
+
additionalProperties: false,
|
|
522
|
+
properties: this.properties,
|
|
523
|
+
...(this['x-jsf-order'] ? { 'x-jsf-order': this['x-jsf-order'] } : {}),
|
|
524
|
+
required: this.requiredFields || [],
|
|
525
|
+
anyOf: this.anyOf,
|
|
526
|
+
allOf: this.allOf,
|
|
527
|
+
if: this.if,
|
|
528
|
+
then: this.then,
|
|
529
|
+
else: this.else,
|
|
530
|
+
};
|
|
531
|
+
},
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// -------------------------------------
|
|
536
|
+
// --------- Schemas pre-built ---------
|
|
537
|
+
// -------------------------------------
|
|
538
|
+
|
|
539
|
+
export const schemaWithoutInputTypes = {
|
|
540
|
+
properties: {
|
|
541
|
+
a_string: {
|
|
542
|
+
title: 'A string -> text',
|
|
543
|
+
type: 'string',
|
|
544
|
+
},
|
|
545
|
+
a_string_oneOf: {
|
|
546
|
+
title: 'A string with oneOf -> radio',
|
|
547
|
+
type: 'string',
|
|
548
|
+
oneOf: [
|
|
549
|
+
{ const: 'yes', title: 'Yes' },
|
|
550
|
+
{ const: 'no', title: 'No' },
|
|
551
|
+
],
|
|
552
|
+
},
|
|
553
|
+
a_string_email: {
|
|
554
|
+
title: 'A string with format:email -> email',
|
|
555
|
+
type: 'string',
|
|
556
|
+
format: 'email',
|
|
557
|
+
},
|
|
558
|
+
a_string_date: {
|
|
559
|
+
title: 'A string with format:email -> date',
|
|
560
|
+
type: 'string',
|
|
561
|
+
format: 'date',
|
|
562
|
+
},
|
|
563
|
+
a_string_file: {
|
|
564
|
+
title: 'A string with format:data-url -> file',
|
|
565
|
+
type: 'string',
|
|
566
|
+
format: 'data-url',
|
|
567
|
+
},
|
|
568
|
+
a_number: {
|
|
569
|
+
title: 'A number -> number',
|
|
570
|
+
type: 'number',
|
|
571
|
+
},
|
|
572
|
+
a_integer: {
|
|
573
|
+
title: 'A integer -> number',
|
|
574
|
+
type: 'integer',
|
|
575
|
+
},
|
|
576
|
+
a_boolean: {
|
|
577
|
+
title: 'A boolean -> checkbox',
|
|
578
|
+
type: 'boolean',
|
|
579
|
+
},
|
|
580
|
+
a_object: {
|
|
581
|
+
title: 'An object -> fieldset',
|
|
582
|
+
type: 'object',
|
|
583
|
+
properties: {
|
|
584
|
+
foo: { type: 'string' },
|
|
585
|
+
bar: { type: 'string' },
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
a_array_items: {
|
|
589
|
+
title: 'An array items.anyOf -> select',
|
|
590
|
+
type: 'array',
|
|
591
|
+
items: {
|
|
592
|
+
anyOf: [
|
|
593
|
+
{
|
|
594
|
+
const: 'chr',
|
|
595
|
+
title: 'Chrome',
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
const: 'ff',
|
|
599
|
+
title: 'Firefox',
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
value: 'ie',
|
|
603
|
+
label: 'Internet Explorer',
|
|
604
|
+
},
|
|
605
|
+
],
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
a_array_properties: {
|
|
609
|
+
title: 'An array items.properties -> group-array',
|
|
610
|
+
items: {
|
|
611
|
+
properties: {
|
|
612
|
+
role: { title: 'Role', type: 'string' },
|
|
613
|
+
years: { title: 'Years', type: 'number' },
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
type: 'array',
|
|
617
|
+
},
|
|
618
|
+
a_void: {
|
|
619
|
+
title: 'A void -> text',
|
|
620
|
+
description: 'Given no type, returns text',
|
|
621
|
+
},
|
|
622
|
+
},
|
|
623
|
+
required: ['a_array_properties'],
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
export const schemaWithoutTypes = {
|
|
627
|
+
properties: {
|
|
628
|
+
default: {
|
|
629
|
+
title: 'Default -> text',
|
|
630
|
+
},
|
|
631
|
+
with_oneOf: {
|
|
632
|
+
title: 'With oneOf -> radio',
|
|
633
|
+
oneOf: [
|
|
634
|
+
{ const: 'yes', title: 'Yes' },
|
|
635
|
+
{ const: 'no', title: 'No' },
|
|
636
|
+
],
|
|
637
|
+
},
|
|
638
|
+
with_email: {
|
|
639
|
+
title: 'With format:email -> email',
|
|
640
|
+
format: 'email',
|
|
641
|
+
},
|
|
642
|
+
with_object: {
|
|
643
|
+
title: 'With properties -> fieldset',
|
|
644
|
+
properties: {
|
|
645
|
+
foo: {},
|
|
646
|
+
bar: {},
|
|
647
|
+
},
|
|
648
|
+
},
|
|
649
|
+
with_items_anyOf: {
|
|
650
|
+
title: 'With items.anyOf -> select',
|
|
651
|
+
items: {
|
|
652
|
+
anyOf: [
|
|
653
|
+
{
|
|
654
|
+
const: 'chr',
|
|
655
|
+
title: 'Chrome',
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
const: 'ff',
|
|
659
|
+
title: 'Firefox',
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
value: 'ie',
|
|
663
|
+
label: 'Internet Explorer',
|
|
664
|
+
},
|
|
665
|
+
],
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
with_items_properties: {
|
|
669
|
+
title: 'With items.properties -> group-array',
|
|
670
|
+
items: {
|
|
671
|
+
properties: {
|
|
672
|
+
role: { title: 'Role' },
|
|
673
|
+
years: { title: 'Years' },
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
export const schemaInputTypeText = JSONSchemaBuilder()
|
|
681
|
+
.addInput({
|
|
682
|
+
id_number: mockTextInput,
|
|
683
|
+
})
|
|
684
|
+
.setRequiredFields(['id_number'])
|
|
685
|
+
.build();
|
|
686
|
+
|
|
687
|
+
export const schemaInputWithStatement = JSONSchemaBuilder()
|
|
688
|
+
.addInput({
|
|
689
|
+
bonus: {
|
|
690
|
+
title: 'Bonus',
|
|
691
|
+
'x-jsf-presentation': {
|
|
692
|
+
inputType: 'text',
|
|
693
|
+
statement: {
|
|
694
|
+
description: 'This is a custom statement message.',
|
|
695
|
+
inputType: 'statement',
|
|
696
|
+
severity: 'info',
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
})
|
|
701
|
+
.addInput({
|
|
702
|
+
a_or_b: {
|
|
703
|
+
title: 'A dropdown',
|
|
704
|
+
description: 'Some options to chose from',
|
|
705
|
+
items: {
|
|
706
|
+
enum: ['A', 'B'],
|
|
707
|
+
},
|
|
708
|
+
'x-jsf-presentation': {
|
|
709
|
+
inputType: 'select',
|
|
710
|
+
options: [
|
|
711
|
+
{
|
|
712
|
+
label: 'A',
|
|
713
|
+
value: 'A',
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
label: 'B',
|
|
717
|
+
value: 'B',
|
|
718
|
+
},
|
|
719
|
+
],
|
|
720
|
+
placeholder: 'Select...',
|
|
721
|
+
statement: {
|
|
722
|
+
description: 'This is another statement message, but more severe.',
|
|
723
|
+
inputType: 'statement',
|
|
724
|
+
severity: 'warning',
|
|
725
|
+
},
|
|
726
|
+
},
|
|
727
|
+
},
|
|
728
|
+
})
|
|
729
|
+
.build();
|
|
730
|
+
|
|
731
|
+
export const schemaInputWithStatementDeprecated = JSONSchemaBuilder()
|
|
732
|
+
.addInput({
|
|
733
|
+
bonus: {
|
|
734
|
+
title: 'Bonus',
|
|
735
|
+
presentation: {
|
|
736
|
+
inputType: 'text',
|
|
737
|
+
statement: {
|
|
738
|
+
description: 'This is a custom statement message.',
|
|
739
|
+
inputType: 'statement',
|
|
740
|
+
severity: 'info',
|
|
741
|
+
},
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
})
|
|
745
|
+
.addInput({
|
|
746
|
+
a_or_b: {
|
|
747
|
+
title: 'A dropdown',
|
|
748
|
+
description: 'Some options to chose from',
|
|
749
|
+
items: {
|
|
750
|
+
enum: ['A', 'B'],
|
|
751
|
+
},
|
|
752
|
+
presentation: {
|
|
753
|
+
inputType: 'select',
|
|
754
|
+
options: [
|
|
755
|
+
{
|
|
756
|
+
label: 'A',
|
|
757
|
+
value: 'A',
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
label: 'B',
|
|
761
|
+
value: 'B',
|
|
762
|
+
},
|
|
763
|
+
],
|
|
764
|
+
placeholder: 'Select...',
|
|
765
|
+
statement: {
|
|
766
|
+
description: 'This is another statement message, but more severe.',
|
|
767
|
+
inputType: 'statement',
|
|
768
|
+
severity: 'warning',
|
|
769
|
+
},
|
|
770
|
+
},
|
|
771
|
+
},
|
|
772
|
+
})
|
|
773
|
+
.build();
|
|
774
|
+
|
|
775
|
+
export const schemaInputWithExtra = JSONSchemaBuilder()
|
|
776
|
+
.addInput({
|
|
777
|
+
bonus: {
|
|
778
|
+
title: 'Bonus',
|
|
779
|
+
'x-jsf-presentation': {
|
|
780
|
+
inputType: 'text',
|
|
781
|
+
description: 'Remote lives around <strong>core values</strong> across the company.',
|
|
782
|
+
extra: `They are:
|
|
783
|
+
<ul>
|
|
784
|
+
<li>Kindness</li>
|
|
785
|
+
<li>Ownership</li>
|
|
786
|
+
<li>Excellence</li>
|
|
787
|
+
<li>Transparency</li>
|
|
788
|
+
<li>Ambition</li>
|
|
789
|
+
</ul>
|
|
790
|
+
<p>You can read more at <a href="https://www.notion.so/remotecom/Handbook-a3439c6ccaac4d5f8c7515c357345c11" target="_blank">our public handbook</a>. They are also referred as <em>KOETA</em>.</p>
|
|
791
|
+
`,
|
|
792
|
+
},
|
|
793
|
+
},
|
|
794
|
+
})
|
|
795
|
+
.build();
|
|
796
|
+
|
|
797
|
+
export const schemaInputWithCustomDescription = JSONSchemaBuilder()
|
|
798
|
+
.addInput({
|
|
799
|
+
other: {
|
|
800
|
+
title: 'Other',
|
|
801
|
+
'x-jsf-presentation': {
|
|
802
|
+
inputType: 'text',
|
|
803
|
+
description: 'Some other information might still be <strong>relevant</strong> for you.',
|
|
804
|
+
},
|
|
805
|
+
type: 'string',
|
|
806
|
+
},
|
|
807
|
+
})
|
|
808
|
+
.build();
|
|
809
|
+
|
|
810
|
+
export const schemaInputDeprecated = JSONSchemaBuilder()
|
|
811
|
+
.addInput({
|
|
812
|
+
age_empty: {
|
|
813
|
+
title: 'Age (Empty) (Deprecated)',
|
|
814
|
+
'x-jsf-presentation': {
|
|
815
|
+
inputType: 'number',
|
|
816
|
+
description: 'What is your age?',
|
|
817
|
+
deprecated: {
|
|
818
|
+
description: 'Field deprecated empty.',
|
|
819
|
+
},
|
|
820
|
+
},
|
|
821
|
+
deprecated: true,
|
|
822
|
+
readOnly: true,
|
|
823
|
+
type: 'number',
|
|
824
|
+
},
|
|
825
|
+
})
|
|
826
|
+
.addInput({
|
|
827
|
+
age_filled: {
|
|
828
|
+
title: 'Age (Filled) (Deprecated)',
|
|
829
|
+
'x-jsf-presentation': {
|
|
830
|
+
inputType: 'number',
|
|
831
|
+
description: 'What is your age?',
|
|
832
|
+
deprecated: {
|
|
833
|
+
description: 'Field deprecated and readOnly with a default value.',
|
|
834
|
+
},
|
|
835
|
+
},
|
|
836
|
+
default: 18,
|
|
837
|
+
deprecated: true,
|
|
838
|
+
readOnly: true,
|
|
839
|
+
type: 'number',
|
|
840
|
+
},
|
|
841
|
+
})
|
|
842
|
+
.addInput({
|
|
843
|
+
age_editable: {
|
|
844
|
+
title: 'Age (Editable) (Deprecated)',
|
|
845
|
+
'x-jsf-presentation': {
|
|
846
|
+
inputType: 'number',
|
|
847
|
+
description: 'What is your age?',
|
|
848
|
+
deprecated: {
|
|
849
|
+
description: 'Field deprecated but editable.',
|
|
850
|
+
},
|
|
851
|
+
},
|
|
852
|
+
deprecated: true,
|
|
853
|
+
type: 'number',
|
|
854
|
+
},
|
|
855
|
+
})
|
|
856
|
+
.build();
|
|
857
|
+
|
|
858
|
+
/** @deprecated */
|
|
859
|
+
export const schemaInputTypeRadioDeprecated = JSONSchemaBuilder()
|
|
860
|
+
.addInput({
|
|
861
|
+
has_siblings: mockRadioInputDeprecated,
|
|
862
|
+
})
|
|
863
|
+
.setRequiredFields(['has_siblings'])
|
|
864
|
+
.build();
|
|
865
|
+
export const schemaInputTypeRadio = JSONSchemaBuilder()
|
|
866
|
+
.addInput({
|
|
867
|
+
has_siblings: mockRadioInput,
|
|
868
|
+
})
|
|
869
|
+
.setRequiredFields(['has_siblings'])
|
|
870
|
+
.build();
|
|
871
|
+
|
|
872
|
+
export const schemaInputTypeRadioRequiredAndOptional = JSONSchemaBuilder()
|
|
873
|
+
.addInput({
|
|
874
|
+
has_siblings: mockRadioInput,
|
|
875
|
+
has_car: mockRadioInputOptional,
|
|
876
|
+
})
|
|
877
|
+
.setRequiredFields(['has_siblings'])
|
|
878
|
+
.build();
|
|
879
|
+
|
|
880
|
+
export const schemaInputTypeRadioCard = JSONSchemaBuilder()
|
|
881
|
+
.addInput({
|
|
882
|
+
experience_level: mockRadioCardExpandableInput,
|
|
883
|
+
payment_method: mockRadioCardInput,
|
|
884
|
+
})
|
|
885
|
+
.setRequiredFields(['experience_level'])
|
|
886
|
+
.build();
|
|
887
|
+
|
|
888
|
+
/** @deprecated */
|
|
889
|
+
export const schemaInputTypeSelectSoloDeprecated = JSONSchemaBuilder()
|
|
890
|
+
.addInput({
|
|
891
|
+
benefits: mockSelectInputSoloDeprecated,
|
|
892
|
+
})
|
|
893
|
+
.setRequiredFields(['benefits'])
|
|
894
|
+
.build();
|
|
895
|
+
export const schemaInputTypeSelectSolo = JSONSchemaBuilder()
|
|
896
|
+
.addInput({
|
|
897
|
+
browsers: mockSelectInputSolo,
|
|
898
|
+
})
|
|
899
|
+
.setRequiredFields(['browsers'])
|
|
900
|
+
.build();
|
|
901
|
+
|
|
902
|
+
/** @deprecated */
|
|
903
|
+
export const schemaInputTypeSelectMultipleDeprecated = JSONSchemaBuilder()
|
|
904
|
+
.addInput({
|
|
905
|
+
benefits_multi: mockSelectInputMultipleDeprecated,
|
|
906
|
+
})
|
|
907
|
+
.setRequiredFields(['benefits_multi'])
|
|
908
|
+
.build();
|
|
909
|
+
export const schemaInputTypeSelectMultiple = JSONSchemaBuilder()
|
|
910
|
+
.addInput({
|
|
911
|
+
browsers_multi: mockSelectInputMultiple,
|
|
912
|
+
})
|
|
913
|
+
.setRequiredFields(['browsers_multi'])
|
|
914
|
+
.build();
|
|
915
|
+
|
|
916
|
+
export const schemaInputTypeSelectMultipleOptional = JSONSchemaBuilder()
|
|
917
|
+
.addInput({
|
|
918
|
+
browsers_multi_optional: mockSelectInputMultipleOptional,
|
|
919
|
+
})
|
|
920
|
+
.build();
|
|
921
|
+
|
|
922
|
+
export const schemaInputTypeNumber = JSONSchemaBuilder()
|
|
923
|
+
.addInput({
|
|
924
|
+
tabs: mockNumberInput,
|
|
925
|
+
})
|
|
926
|
+
.setRequiredFields(['tabs'])
|
|
927
|
+
.build();
|
|
928
|
+
|
|
929
|
+
export const schemaInputTypeNumberWithPercentage = JSONSchemaBuilder()
|
|
930
|
+
.addInput({
|
|
931
|
+
shares: mockNumberInputWithPercentage,
|
|
932
|
+
})
|
|
933
|
+
.setRequiredFields(['shares'])
|
|
934
|
+
.build();
|
|
935
|
+
|
|
936
|
+
export const schemaInputTypeDate = JSONSchemaBuilder()
|
|
937
|
+
.addInput({
|
|
938
|
+
birthdate: mockDateInput,
|
|
939
|
+
})
|
|
940
|
+
.setRequiredFields(['birthdate'])
|
|
941
|
+
.build();
|
|
942
|
+
|
|
943
|
+
export const schemaInputTypeEmail = JSONSchemaBuilder()
|
|
944
|
+
.addInput({
|
|
945
|
+
email_address: mockEmailInput,
|
|
946
|
+
})
|
|
947
|
+
.setRequiredFields(['email_address'])
|
|
948
|
+
.build();
|
|
949
|
+
|
|
950
|
+
export const schemaInputTypeFile = JSONSchemaBuilder()
|
|
951
|
+
.addInput({
|
|
952
|
+
a_file: mockFileInput,
|
|
953
|
+
})
|
|
954
|
+
.setRequiredFields(['a_file'])
|
|
955
|
+
.build();
|
|
956
|
+
|
|
957
|
+
export const schemaInputTypeFileWithSkippable = JSONSchemaBuilder()
|
|
958
|
+
.addInput({
|
|
959
|
+
b_file: mockFileInputWithSkippable,
|
|
960
|
+
})
|
|
961
|
+
.build();
|
|
962
|
+
|
|
963
|
+
export const schemaInputTypeFieldset = JSONSchemaBuilder()
|
|
964
|
+
.addInput({
|
|
965
|
+
a_fieldset: mockFieldset,
|
|
966
|
+
})
|
|
967
|
+
.setRequiredFields(['a_fieldset'])
|
|
968
|
+
.build();
|
|
969
|
+
|
|
970
|
+
export const schemaInputTypeFocusedFieldset = JSONSchemaBuilder()
|
|
971
|
+
.addInput({
|
|
972
|
+
focused_fieldset: mockFocusedFieldset,
|
|
973
|
+
})
|
|
974
|
+
.setRequiredFields(['focused_fieldset'])
|
|
975
|
+
.build();
|
|
976
|
+
|
|
977
|
+
export const schemaInputTypeGroupArray = JSONSchemaBuilder()
|
|
978
|
+
.addInput({
|
|
979
|
+
dependent_details: mockGroupArrayInput,
|
|
980
|
+
optional_dependent_details: mockOptionalGroupArrayInput,
|
|
981
|
+
})
|
|
982
|
+
.setRequiredFields(['dependent_details'])
|
|
983
|
+
.build();
|
|
984
|
+
|
|
985
|
+
export const schemaInputTypeCheckbox = JSONSchemaBuilder()
|
|
986
|
+
.addInput({
|
|
987
|
+
contract_duration: mockCheckboxInput,
|
|
988
|
+
contract_duration_checked: {
|
|
989
|
+
...mockCheckboxInput,
|
|
990
|
+
title: 'Checkbox (checked by default)',
|
|
991
|
+
default: 'Permanent',
|
|
992
|
+
},
|
|
993
|
+
})
|
|
994
|
+
.setRequiredFields(['contract_duration'])
|
|
995
|
+
.build();
|
|
996
|
+
|
|
997
|
+
export const schemaInputTypeCheckboxBooleans = JSONSchemaBuilder()
|
|
998
|
+
.addInput({
|
|
999
|
+
boolean_empty: {
|
|
1000
|
+
title: 'It is christmas',
|
|
1001
|
+
description: 'This one is optional.',
|
|
1002
|
+
type: 'boolean',
|
|
1003
|
+
'x-jsf-presentation': {
|
|
1004
|
+
inputType: 'checkbox',
|
|
1005
|
+
},
|
|
1006
|
+
},
|
|
1007
|
+
boolean_required: {
|
|
1008
|
+
title: 'Is it rainy (required)',
|
|
1009
|
+
description: 'This one is required. Is must have const: true to work properly.',
|
|
1010
|
+
type: 'boolean',
|
|
1011
|
+
const: true, // Must be explicit that `true` (checked) is the only accepted value.
|
|
1012
|
+
'x-jsf-presentation': {
|
|
1013
|
+
inputType: 'checkbox',
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
1016
|
+
boolean_checked: {
|
|
1017
|
+
title: 'It is sunny (Default checked)',
|
|
1018
|
+
description: 'This is checked by default thanks to `default: true`.',
|
|
1019
|
+
type: 'boolean',
|
|
1020
|
+
default: true,
|
|
1021
|
+
'x-jsf-presentation': {
|
|
1022
|
+
inputType: 'checkbox',
|
|
1023
|
+
},
|
|
1024
|
+
},
|
|
1025
|
+
})
|
|
1026
|
+
.setRequiredFields(['boolean_required'])
|
|
1027
|
+
.build();
|
|
1028
|
+
|
|
1029
|
+
export const schemaCustomErrorMessageByField = {
|
|
1030
|
+
properties: {
|
|
1031
|
+
tabs: {
|
|
1032
|
+
title: 'Tabs',
|
|
1033
|
+
description: 'How many open tabs do you have?',
|
|
1034
|
+
'x-jsf-presentation': {
|
|
1035
|
+
inputType: 'number',
|
|
1036
|
+
position: 0,
|
|
1037
|
+
},
|
|
1038
|
+
minimum: 1,
|
|
1039
|
+
maximum: 99,
|
|
1040
|
+
type: 'number',
|
|
1041
|
+
'x-jsf-errorMessage': {
|
|
1042
|
+
required: 'This is required.',
|
|
1043
|
+
minimum: 'You must have at least 1 open tab.',
|
|
1044
|
+
maximum: 'Your browser does not support more than 99 tabs.',
|
|
1045
|
+
},
|
|
1046
|
+
},
|
|
1047
|
+
},
|
|
1048
|
+
required: ['tabs'],
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
// The custom error message is below at jsfConfigForErrorMessageSpecificity
|
|
1052
|
+
export const schemaForErrorMessageSpecificity = {
|
|
1053
|
+
properties: {
|
|
1054
|
+
weekday: {
|
|
1055
|
+
title: 'Weekday',
|
|
1056
|
+
description: "This text field has the traditional error message. 'Required field'",
|
|
1057
|
+
type: 'string',
|
|
1058
|
+
presentation: { inputType: 'text' },
|
|
1059
|
+
},
|
|
1060
|
+
day: {
|
|
1061
|
+
title: 'Day',
|
|
1062
|
+
type: 'number',
|
|
1063
|
+
description:
|
|
1064
|
+
'The remaining fields are numbers and were customized to say "This cannot be empty." instead of "Required field".',
|
|
1065
|
+
|
|
1066
|
+
maximum: 31,
|
|
1067
|
+
presentation: { inputType: 'number' },
|
|
1068
|
+
},
|
|
1069
|
+
month: {
|
|
1070
|
+
title: 'Month',
|
|
1071
|
+
type: 'number',
|
|
1072
|
+
minimum: 1,
|
|
1073
|
+
maximum: 12,
|
|
1074
|
+
presentation: { inputType: 'number' },
|
|
1075
|
+
},
|
|
1076
|
+
year: {
|
|
1077
|
+
title: 'Year',
|
|
1078
|
+
description:
|
|
1079
|
+
"This number field has a custom error message declared in the json schema, which has a higher specificity than the one declared in createHeadlessForm's configuration.",
|
|
1080
|
+
type: 'number',
|
|
1081
|
+
presentation: { inputType: 'number' },
|
|
1082
|
+
'x-jsf-errorMessage': {
|
|
1083
|
+
required: 'The year is mandatory.',
|
|
1084
|
+
},
|
|
1085
|
+
minimum: 1900,
|
|
1086
|
+
maximum: 2023,
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
required: ['weekday', 'day', 'month', 'year'],
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
export const jsfConfigForErrorMessageSpecificity = {
|
|
1093
|
+
inputTypes: {
|
|
1094
|
+
number: {
|
|
1095
|
+
errorMessage: {
|
|
1096
|
+
required: 'This cannot be empty.',
|
|
1097
|
+
},
|
|
1098
|
+
},
|
|
1099
|
+
},
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
export const schemaWithPositionDeprecated = JSONSchemaBuilder()
|
|
1103
|
+
.addInput({
|
|
1104
|
+
age: {
|
|
1105
|
+
title: 'age',
|
|
1106
|
+
'x-jsf-presentation': { inputType: 'number', position: 1 },
|
|
1107
|
+
},
|
|
1108
|
+
street: {
|
|
1109
|
+
title: 'street',
|
|
1110
|
+
'x-jsf-presentation': { inputType: 'fieldset', position: 2 },
|
|
1111
|
+
properties: {
|
|
1112
|
+
line_one: {
|
|
1113
|
+
title: 'Street',
|
|
1114
|
+
'x-jsf-presentation': { inputType: 'text', position: 0 },
|
|
1115
|
+
},
|
|
1116
|
+
postal_code: {
|
|
1117
|
+
title: 'Postal code',
|
|
1118
|
+
'x-jsf-presentation': { inputType: 'text', position: 2 },
|
|
1119
|
+
},
|
|
1120
|
+
number: {
|
|
1121
|
+
title: 'Number',
|
|
1122
|
+
'x-jsf-presentation': { inputType: 'number', position: 1 },
|
|
1123
|
+
},
|
|
1124
|
+
},
|
|
1125
|
+
},
|
|
1126
|
+
username: {
|
|
1127
|
+
title: 'Username',
|
|
1128
|
+
'x-jsf-presentation': { inputType: 'text', position: 0 },
|
|
1129
|
+
},
|
|
1130
|
+
})
|
|
1131
|
+
.build();
|
|
1132
|
+
|
|
1133
|
+
export const schemaWithOrderKeyword = JSONSchemaBuilder()
|
|
1134
|
+
.addInput({
|
|
1135
|
+
age: {
|
|
1136
|
+
title: 'Age',
|
|
1137
|
+
'x-jsf-presentation': { inputType: 'number' },
|
|
1138
|
+
},
|
|
1139
|
+
street: {
|
|
1140
|
+
title: 'Street',
|
|
1141
|
+
'x-jsf-presentation': { inputType: 'fieldset' },
|
|
1142
|
+
properties: {
|
|
1143
|
+
line_one: {
|
|
1144
|
+
title: 'Street',
|
|
1145
|
+
'x-jsf-presentation': { inputType: 'text' },
|
|
1146
|
+
},
|
|
1147
|
+
postal_code: {
|
|
1148
|
+
title: 'Postal code',
|
|
1149
|
+
'x-jsf-presentation': { inputType: 'text' },
|
|
1150
|
+
},
|
|
1151
|
+
number: {
|
|
1152
|
+
title: 'Number',
|
|
1153
|
+
'x-jsf-presentation': { inputType: 'number' },
|
|
1154
|
+
},
|
|
1155
|
+
},
|
|
1156
|
+
'x-jsf-order': ['line_one', 'number', 'postal_code'],
|
|
1157
|
+
},
|
|
1158
|
+
username: {
|
|
1159
|
+
title: 'Username',
|
|
1160
|
+
'x-jsf-presentation': { inputType: 'text' },
|
|
1161
|
+
},
|
|
1162
|
+
})
|
|
1163
|
+
.setOrder(['username', 'age', 'street'])
|
|
1164
|
+
.build();
|
|
1165
|
+
|
|
1166
|
+
export const schemaDynamicValidationConst = JSONSchemaBuilder()
|
|
1167
|
+
.addInput({
|
|
1168
|
+
a_fieldset: mockFieldset,
|
|
1169
|
+
a_group_array: simpleGroupArrayInput,
|
|
1170
|
+
validate_tabs: {
|
|
1171
|
+
title: 'Should "Tabs" value be required?',
|
|
1172
|
+
description: 'Toggle this radio for changing the validation of the fieldset bellow',
|
|
1173
|
+
oneOf: [
|
|
1174
|
+
{
|
|
1175
|
+
title: 'Yes',
|
|
1176
|
+
value: 'yes',
|
|
1177
|
+
},
|
|
1178
|
+
{
|
|
1179
|
+
title: 'No',
|
|
1180
|
+
value: 'no',
|
|
1181
|
+
},
|
|
1182
|
+
],
|
|
1183
|
+
'x-jsf-presentation': {
|
|
1184
|
+
inputType: 'radio',
|
|
1185
|
+
},
|
|
1186
|
+
},
|
|
1187
|
+
mandatory_group_array: {
|
|
1188
|
+
title: 'Add required group array field',
|
|
1189
|
+
description: 'Toggle this radio for displaying a mandatory group array field',
|
|
1190
|
+
oneOf: [
|
|
1191
|
+
{
|
|
1192
|
+
title: 'Yes',
|
|
1193
|
+
value: 'yes',
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
title: 'No',
|
|
1197
|
+
value: 'no',
|
|
1198
|
+
},
|
|
1199
|
+
],
|
|
1200
|
+
'x-jsf-presentation': {
|
|
1201
|
+
inputType: 'radio',
|
|
1202
|
+
},
|
|
1203
|
+
},
|
|
1204
|
+
})
|
|
1205
|
+
.addAllOf([
|
|
1206
|
+
{
|
|
1207
|
+
if: {
|
|
1208
|
+
properties: {
|
|
1209
|
+
mandatory_group_array: {
|
|
1210
|
+
const: 'yes',
|
|
1211
|
+
},
|
|
1212
|
+
},
|
|
1213
|
+
required: ['mandatory_group_array'],
|
|
1214
|
+
},
|
|
1215
|
+
then: {
|
|
1216
|
+
required: ['a_group_array'],
|
|
1217
|
+
},
|
|
1218
|
+
else: {
|
|
1219
|
+
properties: {
|
|
1220
|
+
a_group_array: false,
|
|
1221
|
+
},
|
|
1222
|
+
},
|
|
1223
|
+
},
|
|
1224
|
+
])
|
|
1225
|
+
.addCondition(
|
|
1226
|
+
{
|
|
1227
|
+
properties: {
|
|
1228
|
+
validate_tabs: {
|
|
1229
|
+
const: 'yes',
|
|
1230
|
+
},
|
|
1231
|
+
},
|
|
1232
|
+
required: ['validate_tabs'],
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
properties: {
|
|
1236
|
+
a_fieldset: {
|
|
1237
|
+
required: ['id_number', 'tabs'],
|
|
1238
|
+
},
|
|
1239
|
+
},
|
|
1240
|
+
}
|
|
1241
|
+
)
|
|
1242
|
+
.setRequiredFields(['a_fieldset', 'validate_tabs', 'mandatory_group_array'])
|
|
1243
|
+
.setOrder(['validate_tabs', 'a_fieldset', 'mandatory_group_array', 'a_group_array'])
|
|
1244
|
+
.build();
|
|
1245
|
+
|
|
1246
|
+
export const schemaDynamicValidationMinimumMaximum = JSONSchemaBuilder()
|
|
1247
|
+
.addInput({
|
|
1248
|
+
a_number: mockNumberInput,
|
|
1249
|
+
a_conditional_text: mockTextInput,
|
|
1250
|
+
})
|
|
1251
|
+
.addCondition(
|
|
1252
|
+
{
|
|
1253
|
+
properties: {
|
|
1254
|
+
a_number: {
|
|
1255
|
+
minimum: 1,
|
|
1256
|
+
},
|
|
1257
|
+
},
|
|
1258
|
+
required: ['a_number'],
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
if: {
|
|
1262
|
+
properties: {
|
|
1263
|
+
a_number: {
|
|
1264
|
+
maximum: 10,
|
|
1265
|
+
},
|
|
1266
|
+
},
|
|
1267
|
+
required: ['a_number'],
|
|
1268
|
+
},
|
|
1269
|
+
then: {
|
|
1270
|
+
required: [],
|
|
1271
|
+
},
|
|
1272
|
+
else: {
|
|
1273
|
+
required: ['a_conditional_text'],
|
|
1274
|
+
},
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
required: ['a_conditional_text'],
|
|
1278
|
+
}
|
|
1279
|
+
)
|
|
1280
|
+
.build();
|
|
1281
|
+
|
|
1282
|
+
export const schemaDynamicValidationMinLengthMaxLength = JSONSchemaBuilder()
|
|
1283
|
+
.addInput({
|
|
1284
|
+
a_text: mockTextInput,
|
|
1285
|
+
a_conditional_text: mockTextInput,
|
|
1286
|
+
})
|
|
1287
|
+
.addCondition(
|
|
1288
|
+
// if a_text is between 3 and 5 chars, a_conditional_text is optional.
|
|
1289
|
+
{
|
|
1290
|
+
properties: {
|
|
1291
|
+
a_text: {
|
|
1292
|
+
minLength: 3,
|
|
1293
|
+
maxLength: 5,
|
|
1294
|
+
},
|
|
1295
|
+
},
|
|
1296
|
+
required: ['a_text'],
|
|
1297
|
+
},
|
|
1298
|
+
{
|
|
1299
|
+
required: [],
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
required: ['a_conditional_text'],
|
|
1303
|
+
}
|
|
1304
|
+
)
|
|
1305
|
+
.build();
|
|
1306
|
+
|
|
1307
|
+
export const schemaDynamicValidationContains = JSONSchemaBuilder()
|
|
1308
|
+
.addInput({
|
|
1309
|
+
a_fieldset: mockFieldset,
|
|
1310
|
+
validate_fieldset: {
|
|
1311
|
+
title: 'Fieldset validation',
|
|
1312
|
+
type: 'array',
|
|
1313
|
+
description: 'Select what fieldset fields are required',
|
|
1314
|
+
items: {
|
|
1315
|
+
enum: ['all', 'id_number'],
|
|
1316
|
+
},
|
|
1317
|
+
'x-jsf-presentation': {
|
|
1318
|
+
inputType: 'select',
|
|
1319
|
+
options: [
|
|
1320
|
+
{
|
|
1321
|
+
label: 'All',
|
|
1322
|
+
value: 'all',
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
label: 'ID Number',
|
|
1326
|
+
value: 'id_number',
|
|
1327
|
+
},
|
|
1328
|
+
],
|
|
1329
|
+
placeholder: 'Select...',
|
|
1330
|
+
},
|
|
1331
|
+
},
|
|
1332
|
+
})
|
|
1333
|
+
.addCondition(
|
|
1334
|
+
{
|
|
1335
|
+
properties: {
|
|
1336
|
+
validate_fieldset: {
|
|
1337
|
+
contains: {
|
|
1338
|
+
pattern: '^all$',
|
|
1339
|
+
},
|
|
1340
|
+
},
|
|
1341
|
+
},
|
|
1342
|
+
required: ['validate_fieldset'],
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
properties: {
|
|
1346
|
+
a_fieldset: {
|
|
1347
|
+
required: ['id_number', 'tabs'],
|
|
1348
|
+
},
|
|
1349
|
+
},
|
|
1350
|
+
}
|
|
1351
|
+
)
|
|
1352
|
+
.setRequiredFields(['a_fieldset', 'validate_fieldset'])
|
|
1353
|
+
.setOrder(['validate_fieldset', 'a_fieldset'])
|
|
1354
|
+
.build();
|
|
1355
|
+
|
|
1356
|
+
export const schemaAnyOfValidation = JSONSchemaBuilder()
|
|
1357
|
+
.addInput({
|
|
1358
|
+
field_a: {
|
|
1359
|
+
...mockTextInput,
|
|
1360
|
+
title: 'Field A',
|
|
1361
|
+
description: 'Field A is needed if B and C are empty',
|
|
1362
|
+
},
|
|
1363
|
+
field_b: {
|
|
1364
|
+
...mockTextInput,
|
|
1365
|
+
title: 'Field B',
|
|
1366
|
+
description: 'Field B is needed if A is empty and C is not empty',
|
|
1367
|
+
},
|
|
1368
|
+
field_c: {
|
|
1369
|
+
...mockTextInput,
|
|
1370
|
+
title: 'Field C',
|
|
1371
|
+
description: 'Field C is needed if A is empty and B is not empty',
|
|
1372
|
+
},
|
|
1373
|
+
})
|
|
1374
|
+
.addAnyOf([
|
|
1375
|
+
{
|
|
1376
|
+
required: ['field_a'],
|
|
1377
|
+
},
|
|
1378
|
+
{
|
|
1379
|
+
required: ['field_b', 'field_c'],
|
|
1380
|
+
},
|
|
1381
|
+
])
|
|
1382
|
+
.build();
|
|
1383
|
+
|
|
1384
|
+
export const schemaWithConditionalPresentationProperties = JSONSchemaBuilder()
|
|
1385
|
+
.addInput({
|
|
1386
|
+
mock_radio: mockRadioInput,
|
|
1387
|
+
})
|
|
1388
|
+
.addAllOf([
|
|
1389
|
+
{
|
|
1390
|
+
if: {
|
|
1391
|
+
properties: {
|
|
1392
|
+
mock_radio: {
|
|
1393
|
+
const: 'no',
|
|
1394
|
+
},
|
|
1395
|
+
},
|
|
1396
|
+
required: ['mock_radio'],
|
|
1397
|
+
},
|
|
1398
|
+
then: {
|
|
1399
|
+
properties: {
|
|
1400
|
+
mock_radio: {
|
|
1401
|
+
'x-jsf-presentation': {
|
|
1402
|
+
statement: {
|
|
1403
|
+
description: '<a href="">conditional statement markup</a>',
|
|
1404
|
+
severity: 'info',
|
|
1405
|
+
},
|
|
1406
|
+
},
|
|
1407
|
+
},
|
|
1408
|
+
},
|
|
1409
|
+
},
|
|
1410
|
+
else: {
|
|
1411
|
+
properties: {
|
|
1412
|
+
'x-jsf-presentation': {
|
|
1413
|
+
mock_radio: null,
|
|
1414
|
+
},
|
|
1415
|
+
},
|
|
1416
|
+
},
|
|
1417
|
+
},
|
|
1418
|
+
])
|
|
1419
|
+
.setRequiredFields(['mock_radio'])
|
|
1420
|
+
.build();
|
|
1421
|
+
|
|
1422
|
+
export const schemaWithConditionalReadOnlyProperty = JSONSchemaBuilder()
|
|
1423
|
+
.addInput({ field_a: mockRadioInput })
|
|
1424
|
+
.addInput({ field_b: mockTextInput })
|
|
1425
|
+
.addAllOf([
|
|
1426
|
+
{
|
|
1427
|
+
if: {
|
|
1428
|
+
properties: {
|
|
1429
|
+
field_a: {
|
|
1430
|
+
const: 'yes',
|
|
1431
|
+
},
|
|
1432
|
+
},
|
|
1433
|
+
required: ['field_a'],
|
|
1434
|
+
},
|
|
1435
|
+
then: {
|
|
1436
|
+
properties: {
|
|
1437
|
+
field_b: {
|
|
1438
|
+
readOnly: false,
|
|
1439
|
+
},
|
|
1440
|
+
},
|
|
1441
|
+
required: ['field_b'],
|
|
1442
|
+
},
|
|
1443
|
+
else: {
|
|
1444
|
+
if: {
|
|
1445
|
+
properties: {
|
|
1446
|
+
field_a: {
|
|
1447
|
+
const: 'no',
|
|
1448
|
+
},
|
|
1449
|
+
},
|
|
1450
|
+
required: ['field_a'],
|
|
1451
|
+
},
|
|
1452
|
+
then: {
|
|
1453
|
+
properties: {
|
|
1454
|
+
field_b: {
|
|
1455
|
+
readOnly: true,
|
|
1456
|
+
},
|
|
1457
|
+
},
|
|
1458
|
+
required: ['field_b'],
|
|
1459
|
+
},
|
|
1460
|
+
else: {
|
|
1461
|
+
properties: {
|
|
1462
|
+
field_b: false,
|
|
1463
|
+
},
|
|
1464
|
+
},
|
|
1465
|
+
},
|
|
1466
|
+
},
|
|
1467
|
+
])
|
|
1468
|
+
.setRequiredFields(['field_a'])
|
|
1469
|
+
.build();
|
|
1470
|
+
|
|
1471
|
+
export const schemaWithConditionalAcknowledgementProperty = JSONSchemaBuilder()
|
|
1472
|
+
.addInput({ field_a: mockRadioInput })
|
|
1473
|
+
.addInput({ field_b: mockCheckboxInput })
|
|
1474
|
+
.addAllOf([
|
|
1475
|
+
{
|
|
1476
|
+
if: {
|
|
1477
|
+
properties: {
|
|
1478
|
+
field_a: {
|
|
1479
|
+
const: 'yes',
|
|
1480
|
+
},
|
|
1481
|
+
},
|
|
1482
|
+
required: ['field_a'],
|
|
1483
|
+
},
|
|
1484
|
+
then: {
|
|
1485
|
+
required: ['field_b'],
|
|
1486
|
+
},
|
|
1487
|
+
else: {
|
|
1488
|
+
properties: {
|
|
1489
|
+
field_b: false,
|
|
1490
|
+
},
|
|
1491
|
+
},
|
|
1492
|
+
},
|
|
1493
|
+
])
|
|
1494
|
+
.setRequiredFields(['field_a'])
|
|
1495
|
+
.build();
|
|
1496
|
+
|
|
1497
|
+
// Note: The second conditional (field_a_wrong) is incorrect,
|
|
1498
|
+
// it's used to test/catch the scenario where devs forget to add the if.required[]
|
|
1499
|
+
export const schemaWithWrongConditional = JSONSchemaBuilder()
|
|
1500
|
+
.addInput({ field_a: mockRadioInput })
|
|
1501
|
+
.addInput({ field_b: mockTextInput })
|
|
1502
|
+
.addInput({ field_a_wrong: mockRadioInput })
|
|
1503
|
+
.addInput({ field_b_wrong: mockTextInput })
|
|
1504
|
+
.addAllOf([
|
|
1505
|
+
{
|
|
1506
|
+
if: {
|
|
1507
|
+
properties: {
|
|
1508
|
+
field_a: {
|
|
1509
|
+
const: 'yes',
|
|
1510
|
+
},
|
|
1511
|
+
},
|
|
1512
|
+
required: ['field_a'],
|
|
1513
|
+
},
|
|
1514
|
+
then: {
|
|
1515
|
+
required: ['field_b'],
|
|
1516
|
+
},
|
|
1517
|
+
else: {
|
|
1518
|
+
properties: {
|
|
1519
|
+
field_b: false,
|
|
1520
|
+
},
|
|
1521
|
+
},
|
|
1522
|
+
},
|
|
1523
|
+
{
|
|
1524
|
+
if: {
|
|
1525
|
+
properties: {
|
|
1526
|
+
field_a_wrong: {
|
|
1527
|
+
const: 'yes',
|
|
1528
|
+
},
|
|
1529
|
+
},
|
|
1530
|
+
// it's missing this "required" keyword, for field_b_wrong to be visible.
|
|
1531
|
+
// required: ['field_a_wrong'],
|
|
1532
|
+
},
|
|
1533
|
+
then: {
|
|
1534
|
+
required: ['field_b_wrong'],
|
|
1535
|
+
},
|
|
1536
|
+
else: {
|
|
1537
|
+
properties: {
|
|
1538
|
+
field_b_wrong: false,
|
|
1539
|
+
},
|
|
1540
|
+
},
|
|
1541
|
+
},
|
|
1542
|
+
])
|
|
1543
|
+
.setRequiredFields(['field_a', 'field_a_wrong'])
|
|
1544
|
+
.build();
|
|
1545
|
+
|
|
1546
|
+
export const schemaFieldsetScopedCondition = {
|
|
1547
|
+
additionalProperties: false,
|
|
1548
|
+
properties: {
|
|
1549
|
+
child: {
|
|
1550
|
+
type: 'object',
|
|
1551
|
+
title: 'Child details',
|
|
1552
|
+
description:
|
|
1553
|
+
'In the JSON Schema, you will notice the if/then/else is inside the property, not in the root.',
|
|
1554
|
+
'x-jsf-presentation': {
|
|
1555
|
+
inputType: 'fieldset',
|
|
1556
|
+
},
|
|
1557
|
+
properties: {
|
|
1558
|
+
has_child: {
|
|
1559
|
+
description: 'If yes, it will show its age.',
|
|
1560
|
+
maximum: 100,
|
|
1561
|
+
'x-jsf-presentation': {
|
|
1562
|
+
inputType: 'radio',
|
|
1563
|
+
options: [
|
|
1564
|
+
{
|
|
1565
|
+
label: 'Yes',
|
|
1566
|
+
value: 'yes',
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
label: 'No',
|
|
1570
|
+
value: 'no',
|
|
1571
|
+
},
|
|
1572
|
+
],
|
|
1573
|
+
},
|
|
1574
|
+
title: 'Do you have a child?',
|
|
1575
|
+
type: 'number',
|
|
1576
|
+
},
|
|
1577
|
+
age: {
|
|
1578
|
+
description: 'This age is required, but the "age" at the root level is still optional.',
|
|
1579
|
+
'x-jsf-presentation': {
|
|
1580
|
+
inputType: 'number',
|
|
1581
|
+
},
|
|
1582
|
+
title: 'Age',
|
|
1583
|
+
type: 'number',
|
|
1584
|
+
},
|
|
1585
|
+
passport_id: {
|
|
1586
|
+
description: 'Passport ID is optional',
|
|
1587
|
+
'x-jsf-presentation': {
|
|
1588
|
+
inputType: 'text',
|
|
1589
|
+
},
|
|
1590
|
+
title: 'Passport ID',
|
|
1591
|
+
type: 'string',
|
|
1592
|
+
},
|
|
1593
|
+
},
|
|
1594
|
+
required: ['has_child'],
|
|
1595
|
+
allOf: [
|
|
1596
|
+
{
|
|
1597
|
+
if: {
|
|
1598
|
+
properties: {
|
|
1599
|
+
has_child: {
|
|
1600
|
+
const: 'yes',
|
|
1601
|
+
},
|
|
1602
|
+
},
|
|
1603
|
+
required: ['has_child'],
|
|
1604
|
+
},
|
|
1605
|
+
then: {
|
|
1606
|
+
required: ['age'],
|
|
1607
|
+
},
|
|
1608
|
+
else: {
|
|
1609
|
+
properties: {
|
|
1610
|
+
age: false,
|
|
1611
|
+
passport_id: false,
|
|
1612
|
+
},
|
|
1613
|
+
},
|
|
1614
|
+
},
|
|
1615
|
+
],
|
|
1616
|
+
},
|
|
1617
|
+
age: {
|
|
1618
|
+
type: 'number',
|
|
1619
|
+
title: 'Age',
|
|
1620
|
+
'x-jsf-presentation': {
|
|
1621
|
+
inputType: 'number',
|
|
1622
|
+
description: 'This field is optional, always.',
|
|
1623
|
+
},
|
|
1624
|
+
},
|
|
1625
|
+
},
|
|
1626
|
+
required: ['child'],
|
|
1627
|
+
type: 'object',
|
|
1628
|
+
};
|
|
1629
|
+
|
|
1630
|
+
export const schemaWorkSchedule = {
|
|
1631
|
+
type: 'object',
|
|
1632
|
+
properties: {
|
|
1633
|
+
employee_schedule: {
|
|
1634
|
+
title: 'Employee Schedule',
|
|
1635
|
+
'x-jsf-presentation': {
|
|
1636
|
+
inputType: 'fieldset',
|
|
1637
|
+
position: 0,
|
|
1638
|
+
},
|
|
1639
|
+
properties: {
|
|
1640
|
+
schedule_type: {
|
|
1641
|
+
type: 'string',
|
|
1642
|
+
title: 'Employee Schedule Type',
|
|
1643
|
+
oneOf: [
|
|
1644
|
+
{ const: 'flexible', title: "Employee's hours are flexible" },
|
|
1645
|
+
{
|
|
1646
|
+
const: 'core_business_hours',
|
|
1647
|
+
title: "Employee works employer's core business hours",
|
|
1648
|
+
},
|
|
1649
|
+
{ const: 'fixed_hours', title: 'Employee works fixed hours' },
|
|
1650
|
+
],
|
|
1651
|
+
'x-jsf-presentation': {
|
|
1652
|
+
inputType: 'select',
|
|
1653
|
+
position: 0,
|
|
1654
|
+
},
|
|
1655
|
+
},
|
|
1656
|
+
daily_schedule: {
|
|
1657
|
+
type: 'array',
|
|
1658
|
+
items: {
|
|
1659
|
+
type: 'object',
|
|
1660
|
+
properties: {
|
|
1661
|
+
day: {
|
|
1662
|
+
type: 'string',
|
|
1663
|
+
enum: [
|
|
1664
|
+
'monday',
|
|
1665
|
+
'tuesday',
|
|
1666
|
+
'wednesday',
|
|
1667
|
+
'thursday',
|
|
1668
|
+
'friday',
|
|
1669
|
+
'saturday',
|
|
1670
|
+
'sunday',
|
|
1671
|
+
],
|
|
1672
|
+
},
|
|
1673
|
+
start_time: {
|
|
1674
|
+
type: 'string',
|
|
1675
|
+
pattern: '^([01]\\d|2[0-3]):([0-5]\\d)$',
|
|
1676
|
+
},
|
|
1677
|
+
end_time: {
|
|
1678
|
+
type: 'string',
|
|
1679
|
+
pattern: '^([01]\\d|2[0-3]):([0-5]\\d)$',
|
|
1680
|
+
},
|
|
1681
|
+
hours: {
|
|
1682
|
+
type: 'number',
|
|
1683
|
+
minimum: 0,
|
|
1684
|
+
},
|
|
1685
|
+
break_duration_minutes: {
|
|
1686
|
+
type: 'integer',
|
|
1687
|
+
minimum: 0,
|
|
1688
|
+
},
|
|
1689
|
+
},
|
|
1690
|
+
required: ['day', 'start_time', 'end_time', 'hours', 'break_duration_minutes'],
|
|
1691
|
+
},
|
|
1692
|
+
'x-jsf-presentation': {
|
|
1693
|
+
position: 1,
|
|
1694
|
+
inputType: 'work-schedule',
|
|
1695
|
+
},
|
|
1696
|
+
default: [],
|
|
1697
|
+
},
|
|
1698
|
+
work_hours_per_week: {
|
|
1699
|
+
type: 'number',
|
|
1700
|
+
title: 'Work Hours Per Week',
|
|
1701
|
+
maximum: 50,
|
|
1702
|
+
minimum: 1,
|
|
1703
|
+
'x-jsf-errorMessage': {
|
|
1704
|
+
minimum: 'You must enter work hours to equal more than 0.',
|
|
1705
|
+
},
|
|
1706
|
+
'x-jsf-presentation': {
|
|
1707
|
+
inputType: 'number',
|
|
1708
|
+
position: 2,
|
|
1709
|
+
},
|
|
1710
|
+
},
|
|
1711
|
+
exclude_breaks_in_work_hours: {
|
|
1712
|
+
const: true,
|
|
1713
|
+
readOnly: true,
|
|
1714
|
+
'x-jsf-presentation': {
|
|
1715
|
+
inputType: 'hidden',
|
|
1716
|
+
},
|
|
1717
|
+
type: 'boolean',
|
|
1718
|
+
},
|
|
1719
|
+
},
|
|
1720
|
+
allOf: [
|
|
1721
|
+
{
|
|
1722
|
+
if: {
|
|
1723
|
+
properties: {
|
|
1724
|
+
schedule_type: {
|
|
1725
|
+
enum: ['flexible', 'core_business_hours', 'fixed_hours'],
|
|
1726
|
+
},
|
|
1727
|
+
},
|
|
1728
|
+
required: ['schedule_type'],
|
|
1729
|
+
},
|
|
1730
|
+
then: {
|
|
1731
|
+
required: ['work_hours_per_week'],
|
|
1732
|
+
},
|
|
1733
|
+
else: {
|
|
1734
|
+
properties: {
|
|
1735
|
+
work_hours_per_week: false,
|
|
1736
|
+
},
|
|
1737
|
+
},
|
|
1738
|
+
},
|
|
1739
|
+
{
|
|
1740
|
+
if: {
|
|
1741
|
+
properties: {
|
|
1742
|
+
schedule_type: {
|
|
1743
|
+
enum: ['core_business_hours', 'fixed_hours'],
|
|
1744
|
+
},
|
|
1745
|
+
},
|
|
1746
|
+
required: ['schedule_type'],
|
|
1747
|
+
},
|
|
1748
|
+
then: {
|
|
1749
|
+
required: ['daily_schedule'],
|
|
1750
|
+
},
|
|
1751
|
+
else: {
|
|
1752
|
+
properties: {
|
|
1753
|
+
daily_schedule: false,
|
|
1754
|
+
},
|
|
1755
|
+
},
|
|
1756
|
+
},
|
|
1757
|
+
{
|
|
1758
|
+
if: {
|
|
1759
|
+
properties: {
|
|
1760
|
+
schedule_type: {
|
|
1761
|
+
const: 'flexible',
|
|
1762
|
+
},
|
|
1763
|
+
},
|
|
1764
|
+
required: ['schedule_type'],
|
|
1765
|
+
},
|
|
1766
|
+
then: {
|
|
1767
|
+
required: ['work_hours_per_week'],
|
|
1768
|
+
properties: {
|
|
1769
|
+
work_hours_per_week: {
|
|
1770
|
+
readOnly: false,
|
|
1771
|
+
},
|
|
1772
|
+
},
|
|
1773
|
+
},
|
|
1774
|
+
},
|
|
1775
|
+
{
|
|
1776
|
+
if: {
|
|
1777
|
+
properties: {
|
|
1778
|
+
schedule_type: {
|
|
1779
|
+
const: 'core_business_hours',
|
|
1780
|
+
},
|
|
1781
|
+
},
|
|
1782
|
+
required: ['schedule_type'],
|
|
1783
|
+
},
|
|
1784
|
+
then: {
|
|
1785
|
+
required: ['work_hours_per_week'],
|
|
1786
|
+
properties: {
|
|
1787
|
+
daily_schedule: {
|
|
1788
|
+
title: 'Core business hours',
|
|
1789
|
+
default: [
|
|
1790
|
+
{
|
|
1791
|
+
day: 'monday',
|
|
1792
|
+
start_time: '10:00',
|
|
1793
|
+
end_time: '17:30',
|
|
1794
|
+
hours: 8.5,
|
|
1795
|
+
break_duration_minutes: 60,
|
|
1796
|
+
},
|
|
1797
|
+
{
|
|
1798
|
+
day: 'wednesday',
|
|
1799
|
+
start_time: '10:00',
|
|
1800
|
+
end_time: '17:30',
|
|
1801
|
+
hours: 7.5,
|
|
1802
|
+
break_duration_minutes: 45,
|
|
1803
|
+
},
|
|
1804
|
+
{
|
|
1805
|
+
day: 'friday',
|
|
1806
|
+
start_time: '09:00',
|
|
1807
|
+
end_time: '17:30',
|
|
1808
|
+
hours: 8.5,
|
|
1809
|
+
break_duration_minutes: 45,
|
|
1810
|
+
},
|
|
1811
|
+
],
|
|
1812
|
+
},
|
|
1813
|
+
work_hours_per_week: {
|
|
1814
|
+
readOnly: false,
|
|
1815
|
+
},
|
|
1816
|
+
},
|
|
1817
|
+
},
|
|
1818
|
+
},
|
|
1819
|
+
{
|
|
1820
|
+
if: {
|
|
1821
|
+
properties: {
|
|
1822
|
+
schedule_type: {
|
|
1823
|
+
const: 'fixed_hours',
|
|
1824
|
+
},
|
|
1825
|
+
},
|
|
1826
|
+
required: ['schedule_type'],
|
|
1827
|
+
},
|
|
1828
|
+
then: {
|
|
1829
|
+
properties: {
|
|
1830
|
+
daily_schedule: {
|
|
1831
|
+
title: 'Work hours',
|
|
1832
|
+
default: [
|
|
1833
|
+
{
|
|
1834
|
+
day: 'monday',
|
|
1835
|
+
start_time: '10:00',
|
|
1836
|
+
end_time: '17:30',
|
|
1837
|
+
hours: 8.5,
|
|
1838
|
+
break_duration_minutes: 60,
|
|
1839
|
+
},
|
|
1840
|
+
{
|
|
1841
|
+
day: 'wednesday',
|
|
1842
|
+
start_time: '10:00',
|
|
1843
|
+
end_time: '17:30',
|
|
1844
|
+
hours: 7.5,
|
|
1845
|
+
break_duration_minutes: 45,
|
|
1846
|
+
},
|
|
1847
|
+
{
|
|
1848
|
+
day: 'saturday',
|
|
1849
|
+
start_time: '09:00',
|
|
1850
|
+
end_time: '17:30',
|
|
1851
|
+
hours: 8.5,
|
|
1852
|
+
break_duration_minutes: 45,
|
|
1853
|
+
},
|
|
1854
|
+
],
|
|
1855
|
+
},
|
|
1856
|
+
work_hours_per_week: {
|
|
1857
|
+
readOnly: true,
|
|
1858
|
+
},
|
|
1859
|
+
},
|
|
1860
|
+
},
|
|
1861
|
+
},
|
|
1862
|
+
],
|
|
1863
|
+
required: ['schedule_type'],
|
|
1864
|
+
type: 'object',
|
|
1865
|
+
},
|
|
1866
|
+
},
|
|
1867
|
+
required: ['employee_schedule'],
|
|
1868
|
+
allOf: [],
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1871
|
+
export const schemaWithCustomValidations = {
|
|
1872
|
+
properties: {
|
|
1873
|
+
work_hours_per_week: {
|
|
1874
|
+
title: 'Work hours per week',
|
|
1875
|
+
'x-jsf-presentation': {
|
|
1876
|
+
inputType: 'number',
|
|
1877
|
+
},
|
|
1878
|
+
minimum: 1,
|
|
1879
|
+
maximum: 40,
|
|
1880
|
+
type: 'number',
|
|
1881
|
+
},
|
|
1882
|
+
available_pto: {
|
|
1883
|
+
'x-jsf-presentation': {
|
|
1884
|
+
inputType: 'number',
|
|
1885
|
+
},
|
|
1886
|
+
title: 'Number of paid time off days',
|
|
1887
|
+
type: 'number',
|
|
1888
|
+
},
|
|
1889
|
+
},
|
|
1890
|
+
'x-jsf-order': ['work_hours_per_week', 'available_pto'],
|
|
1891
|
+
required: ['work_hours_per_week', 'available_pto'],
|
|
1892
|
+
};
|
|
1893
|
+
|
|
1894
|
+
export const schemaWithCustomValidationsAndConditionals = {
|
|
1895
|
+
properties: {
|
|
1896
|
+
work_schedule: {
|
|
1897
|
+
oneOf: [
|
|
1898
|
+
{ const: 'full_time', title: 'Full-time' },
|
|
1899
|
+
{ const: 'part_time', title: 'Part-time' },
|
|
1900
|
+
],
|
|
1901
|
+
'x-jsf-presentation': {
|
|
1902
|
+
inputType: 'radio',
|
|
1903
|
+
},
|
|
1904
|
+
type: 'string',
|
|
1905
|
+
title: 'Type of employee',
|
|
1906
|
+
},
|
|
1907
|
+
work_hours_per_week: {
|
|
1908
|
+
title: 'Work hours per week',
|
|
1909
|
+
description: 'Please indicate the number of hours the employee will work per week.',
|
|
1910
|
+
'x-jsf-presentation': {
|
|
1911
|
+
inputType: 'number',
|
|
1912
|
+
},
|
|
1913
|
+
minimum: 1,
|
|
1914
|
+
maximum: 40,
|
|
1915
|
+
type: 'number',
|
|
1916
|
+
},
|
|
1917
|
+
annual_gross_salary: {
|
|
1918
|
+
title: 'Annual gross salary',
|
|
1919
|
+
'x-jsf-presentation': {
|
|
1920
|
+
inputType: 'money',
|
|
1921
|
+
currency: 'EUR',
|
|
1922
|
+
},
|
|
1923
|
+
$comment: 'The minimum is dynamically calculated with jsf.',
|
|
1924
|
+
type: ['integer', 'null'],
|
|
1925
|
+
},
|
|
1926
|
+
hourly_gross_salary: {
|
|
1927
|
+
title: 'Hourly gross salary',
|
|
1928
|
+
'x-jsf-presentation': {
|
|
1929
|
+
inputType: 'money',
|
|
1930
|
+
currency: 'EUR',
|
|
1931
|
+
},
|
|
1932
|
+
$comment: 'The minimum is dynamically calculated with jsf.',
|
|
1933
|
+
type: ['integer', 'null'],
|
|
1934
|
+
},
|
|
1935
|
+
},
|
|
1936
|
+
'x-jsf-order': [
|
|
1937
|
+
'work_schedule',
|
|
1938
|
+
'work_hours_per_week',
|
|
1939
|
+
'annual_gross_salary',
|
|
1940
|
+
'hourly_gross_salary',
|
|
1941
|
+
],
|
|
1942
|
+
required: ['work_schedule', 'work_hours_per_week'],
|
|
1943
|
+
allOf: [
|
|
1944
|
+
{
|
|
1945
|
+
if: {
|
|
1946
|
+
properties: {
|
|
1947
|
+
work_schedule: {
|
|
1948
|
+
const: 'full_time',
|
|
1949
|
+
},
|
|
1950
|
+
},
|
|
1951
|
+
required: ['work_schedule'],
|
|
1952
|
+
},
|
|
1953
|
+
then: {
|
|
1954
|
+
properties: {
|
|
1955
|
+
work_hours_per_week: {
|
|
1956
|
+
minimum: 36,
|
|
1957
|
+
maximum: 40,
|
|
1958
|
+
'x-jsf-errorMessage': {
|
|
1959
|
+
minimum: 'Must be at least 36 hours per week.',
|
|
1960
|
+
maximum: 'Must be no more than 40 hours per week.',
|
|
1961
|
+
},
|
|
1962
|
+
},
|
|
1963
|
+
hourly_gross_salary: false,
|
|
1964
|
+
},
|
|
1965
|
+
required: ['annual_gross_salary'],
|
|
1966
|
+
},
|
|
1967
|
+
else: {
|
|
1968
|
+
required: ['hourly_gross_salary'],
|
|
1969
|
+
properties: {
|
|
1970
|
+
annual_gross_salary: false,
|
|
1971
|
+
work_hours_per_week: {
|
|
1972
|
+
minimum: 1,
|
|
1973
|
+
maximum: 35,
|
|
1974
|
+
'x-jsf-errorMessage': {
|
|
1975
|
+
minimum: 'Must be at least 1 hour per week.',
|
|
1976
|
+
maximum: 'Must be no more than 35 hours per week.',
|
|
1977
|
+
},
|
|
1978
|
+
},
|
|
1979
|
+
},
|
|
1980
|
+
},
|
|
1981
|
+
},
|
|
1982
|
+
],
|
|
1983
|
+
};
|