@planning-inspectorate/dynamic-forms 3.16.0 → 3.17.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/README.md +112 -1
- package/package.json +1 -1
- package/src/components/address/question.d.ts +1 -9
- package/src/components/address/question.d.ts.map +1 -1
- package/src/components/address/question.js +6 -17
- package/src/components/checkbox/question.d.ts +1 -21
- package/src/components/checkbox/question.d.ts.map +1 -1
- package/src/components/checkbox/question.js +36 -49
- package/src/components/checkbox/question.test.js +170 -27
- package/src/components/date/question.d.ts +0 -8
- package/src/components/date/question.d.ts.map +1 -1
- package/src/components/date/question.js +6 -14
- package/src/components/date-period/question.d.ts +1 -5
- package/src/components/date-period/question.d.ts.map +1 -1
- package/src/components/date-period/question.js +1 -1
- package/src/components/date-time/question.d.ts +0 -8
- package/src/components/date-time/question.d.ts.map +1 -1
- package/src/components/date-time/question.js +4 -12
- package/src/components/manage-list/answer-summary-list.njk +1 -1
- package/src/components/manage-list/question.d.ts +1 -5
- package/src/components/manage-list/question.d.ts.map +1 -1
- package/src/components/manage-list/question.js +1 -1
- package/src/components/number-entry/question.d.ts +0 -28
- package/src/components/number-entry/question.d.ts.map +1 -1
- package/src/components/number-entry/question.js +3 -21
- package/src/components/radio/question.d.ts +1 -9
- package/src/components/radio/question.d.ts.map +1 -1
- package/src/components/radio/question.js +29 -46
- package/src/components/radio/question.test.js +139 -60
- package/src/components/select/question.d.ts +1 -15
- package/src/components/select/question.d.ts.map +1 -1
- package/src/components/select/question.js +4 -47
- package/src/components/single-line-input/question.d.ts +0 -4
- package/src/components/single-line-input/question.d.ts.map +1 -1
- package/src/components/single-line-input/question.js +1 -1
- package/src/components/text-entry/question.d.ts +0 -4
- package/src/components/text-entry/question.d.ts.map +1 -1
- package/src/components/text-entry/question.js +1 -1
- package/src/components/text-entry-redact/question.d.ts +2 -6
- package/src/components/text-entry-redact/question.d.ts.map +1 -1
- package/src/components/text-entry-redact/question.js +1 -1
- package/src/components/utils/question-has-answer.js +1 -1
- package/src/components/utils/question-utils.d.ts +19 -1
- package/src/components/utils/question-utils.d.ts.map +1 -1
- package/src/components/utils/question-utils.js +31 -2
- package/src/components/utils/question-utils.test.js +89 -2
- package/src/questions/options-question.d.ts +4 -4
- package/src/questions/options-question.d.ts.map +1 -1
- package/src/questions/options-question.js +27 -2
- package/src/questions/options-question.test.js +106 -0
- package/src/questions/question.d.ts +16 -1
- package/src/questions/question.d.ts.map +1 -1
- package/src/questions/question.js +64 -9
- package/src/questions/question.test.js +86 -0
- package/test/journey.js +2 -0
- package/test/questions.js +50 -0
- package/test/snapshots/check-your-answers-not-started.html +22 -0
- package/test/snapshots/check-your-answers-with-answers.html +22 -0
- package/test/snapshots/favourite-activity-reason.html +54 -0
- package/test/snapshots/travel-requirements.html +48 -0
- package/test/utils/question-test-utils.js +36 -6
- package/typedefs/question-types.d.ts +27 -0
|
@@ -457,4 +457,90 @@ describe('./src/dynamic-forms/question.js', () => {
|
|
|
457
457
|
assert.strictEqual(q.isRequired(), true);
|
|
458
458
|
});
|
|
459
459
|
});
|
|
460
|
+
|
|
461
|
+
describe('formatSummaryValue', () => {
|
|
462
|
+
it('should default to undefined', () => {
|
|
463
|
+
const question = getTestQuestion();
|
|
464
|
+
assert.strictEqual(question.formatSummaryValue, undefined);
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
it('should accept formatSummaryValue in constructor', () => {
|
|
468
|
+
const formatter = ({ formattedAnswer }) => `<em>${formattedAnswer}</em>`;
|
|
469
|
+
const question = new Question({
|
|
470
|
+
title: TITLE,
|
|
471
|
+
question: QUESTION_STRING,
|
|
472
|
+
viewFolder: TYPE,
|
|
473
|
+
fieldName: FIELDNAME,
|
|
474
|
+
formatSummaryValue: formatter
|
|
475
|
+
});
|
|
476
|
+
assert.strictEqual(question.formatSummaryValue, formatter);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
it('should apply custom formatting in formatAnswerForSummary when provided', () => {
|
|
480
|
+
const journey = {
|
|
481
|
+
getCurrentQuestionUrl: () => 'current'
|
|
482
|
+
};
|
|
483
|
+
const question = new Question({
|
|
484
|
+
title: TITLE,
|
|
485
|
+
question: QUESTION_STRING,
|
|
486
|
+
viewFolder: TYPE,
|
|
487
|
+
fieldName: FIELDNAME,
|
|
488
|
+
formatSummaryValue: ({ formattedAnswer }) => `<strong>${formattedAnswer}</strong>`
|
|
489
|
+
});
|
|
490
|
+
const result = question.formatAnswerForSummary('segment', journey, 'test answer');
|
|
491
|
+
assert.strictEqual(result[0].value, '<strong>Test answer</strong>');
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it('should use default formatting when formatSummaryValue is not provided', () => {
|
|
495
|
+
const journey = {
|
|
496
|
+
getCurrentQuestionUrl: () => 'current'
|
|
497
|
+
};
|
|
498
|
+
const question = getTestQuestion();
|
|
499
|
+
const result = question.formatAnswerForSummary('segment', journey, 'test answer');
|
|
500
|
+
assert.strictEqual(result[0].value, 'Test answer');
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it('should allow access to journey in formatter', () => {
|
|
504
|
+
const journey = {
|
|
505
|
+
getCurrentQuestionUrl: () => 'current',
|
|
506
|
+
response: { answers: { otherField: 'other value' } }
|
|
507
|
+
};
|
|
508
|
+
const question = new Question({
|
|
509
|
+
title: TITLE,
|
|
510
|
+
question: QUESTION_STRING,
|
|
511
|
+
viewFolder: TYPE,
|
|
512
|
+
fieldName: FIELDNAME,
|
|
513
|
+
formatSummaryValue: ({ formattedAnswer, journey }) => {
|
|
514
|
+
const extra = journey.response.answers.otherField;
|
|
515
|
+
return `${formattedAnswer} (${extra})`;
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
const result = question.formatAnswerForSummary('segment', journey, 'test');
|
|
519
|
+
assert.strictEqual(result[0].value, 'Test (other value)');
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
it('should pass all context properties to formatSummaryValue', () => {
|
|
523
|
+
const formatSummaryValue = mock.fn((ctx) => ctx.formattedAnswer);
|
|
524
|
+
const journey = {
|
|
525
|
+
id: 'test-journey',
|
|
526
|
+
getCurrentQuestionUrl: () => 'current'
|
|
527
|
+
};
|
|
528
|
+
const question = new Question({
|
|
529
|
+
title: TITLE,
|
|
530
|
+
question: QUESTION_STRING,
|
|
531
|
+
viewFolder: TYPE,
|
|
532
|
+
fieldName: FIELDNAME,
|
|
533
|
+
formatSummaryValue
|
|
534
|
+
});
|
|
535
|
+
question.formatAnswerForSummary('my-segment', journey, 'my-answer');
|
|
536
|
+
|
|
537
|
+
assert.strictEqual(formatSummaryValue.mock.callCount(), 1);
|
|
538
|
+
const receivedContext = formatSummaryValue.mock.calls[0].arguments[0];
|
|
539
|
+
assert.strictEqual(receivedContext.answer, 'my-answer');
|
|
540
|
+
assert.strictEqual(receivedContext.formattedAnswer, 'My-answer');
|
|
541
|
+
assert.strictEqual(receivedContext.question, question);
|
|
542
|
+
assert.strictEqual(receivedContext.journey, journey);
|
|
543
|
+
assert.strictEqual(receivedContext.sectionSegment, 'my-segment');
|
|
544
|
+
});
|
|
545
|
+
});
|
|
460
546
|
});
|
package/test/journey.js
CHANGED
|
@@ -30,6 +30,8 @@ export function createJourney(questions, response) {
|
|
|
30
30
|
.addQuestion(questions.hotelAddress)
|
|
31
31
|
.addQuestion(questions.luggageWeight)
|
|
32
32
|
.addQuestion(questions.contactEmail)
|
|
33
|
+
.addQuestion(questions.favouriteActivityReason)
|
|
34
|
+
.addQuestion(questions.travelRequirements)
|
|
33
35
|
.addQuestion(
|
|
34
36
|
questions.travelCompanions,
|
|
35
37
|
new ManageListSection().addQuestion(questions.travelCompanionName).addQuestion(questions.travelCompanionEmail)
|
package/test/questions.js
CHANGED
|
@@ -195,6 +195,54 @@ export const questionProps = {
|
|
|
195
195
|
question: 'Travel Companion Email',
|
|
196
196
|
fieldName: 'travelCompanionEmail',
|
|
197
197
|
url: 'travel-companion-email'
|
|
198
|
+
},
|
|
199
|
+
// Test questions for conditional reveal functionality
|
|
200
|
+
favouriteActivityReason: {
|
|
201
|
+
type: COMPONENT_TYPES.RADIO,
|
|
202
|
+
title: 'Favourite Activity Reason',
|
|
203
|
+
question: 'Why do you want to do your favourite activity?',
|
|
204
|
+
fieldName: 'favouriteActivityReason',
|
|
205
|
+
url: 'favourite-activity-reason',
|
|
206
|
+
label: 'Select a reason',
|
|
207
|
+
options: [
|
|
208
|
+
{
|
|
209
|
+
value: 'relaxation',
|
|
210
|
+
text: 'Relaxation',
|
|
211
|
+
conditional: {
|
|
212
|
+
question: 'How do you like to relax?',
|
|
213
|
+
type: 'text',
|
|
214
|
+
fieldName: 'relaxationDetails',
|
|
215
|
+
label: 'Details:'
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{ value: 'adventure', text: 'Adventure' },
|
|
219
|
+
{ value: 'culture', text: 'Culture' }
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
travelRequirements: {
|
|
223
|
+
type: COMPONENT_TYPES.CHECKBOX,
|
|
224
|
+
title: 'Travel Requirements',
|
|
225
|
+
question: 'What special requirements do you have?',
|
|
226
|
+
fieldName: 'travelRequirements',
|
|
227
|
+
url: 'travel-requirements',
|
|
228
|
+
label: 'Select all that apply',
|
|
229
|
+
options: [
|
|
230
|
+
{
|
|
231
|
+
value: 'dietary',
|
|
232
|
+
text: 'Dietary requirements',
|
|
233
|
+
conditional: {
|
|
234
|
+
question: 'Please describe your dietary requirements',
|
|
235
|
+
type: 'text',
|
|
236
|
+
fieldName: 'dietaryDetails',
|
|
237
|
+
label: 'Dietary details:'
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
value: 'mobility',
|
|
242
|
+
text: 'Mobility assistance'
|
|
243
|
+
},
|
|
244
|
+
{ value: 'medical', text: 'Medical needs' }
|
|
245
|
+
]
|
|
198
246
|
}
|
|
199
247
|
};
|
|
200
248
|
|
|
@@ -216,6 +264,8 @@ export const questionsInOrder = [
|
|
|
216
264
|
questionProps.hotelAddress,
|
|
217
265
|
questionProps.luggageWeight,
|
|
218
266
|
questionProps.contactEmail,
|
|
267
|
+
questionProps.favouriteActivityReason,
|
|
268
|
+
questionProps.travelRequirements,
|
|
219
269
|
questionProps.travelCompanions
|
|
220
270
|
];
|
|
221
271
|
|
|
@@ -196,6 +196,28 @@
|
|
|
196
196
|
<a class="govuk-link" href="questions/contact-email">Answer<span class="govuk-visually-hidden"> What is your email address for booking confirmations?</span></a>
|
|
197
197
|
</dd>
|
|
198
198
|
</div>
|
|
199
|
+
<div class="govuk-summary-list__row">
|
|
200
|
+
<dt class="govuk-summary-list__key">
|
|
201
|
+
Favourite Activity Reason
|
|
202
|
+
</dt>
|
|
203
|
+
<dd class="govuk-summary-list__value">
|
|
204
|
+
Not started
|
|
205
|
+
</dd>
|
|
206
|
+
<dd class="govuk-summary-list__actions">
|
|
207
|
+
<a class="govuk-link" href="questions/favourite-activity-reason">Answer<span class="govuk-visually-hidden"> Why do you want to do your favourite activity?</span></a>
|
|
208
|
+
</dd>
|
|
209
|
+
</div>
|
|
210
|
+
<div class="govuk-summary-list__row">
|
|
211
|
+
<dt class="govuk-summary-list__key">
|
|
212
|
+
Travel Requirements
|
|
213
|
+
</dt>
|
|
214
|
+
<dd class="govuk-summary-list__value">
|
|
215
|
+
Not started
|
|
216
|
+
</dd>
|
|
217
|
+
<dd class="govuk-summary-list__actions">
|
|
218
|
+
<a class="govuk-link" href="questions/travel-requirements">Answer<span class="govuk-visually-hidden"> What special requirements do you have?</span></a>
|
|
219
|
+
</dd>
|
|
220
|
+
</div>
|
|
199
221
|
<div class="govuk-summary-list__row">
|
|
200
222
|
<dt class="govuk-summary-list__key">
|
|
201
223
|
Travel Companions
|
|
@@ -196,6 +196,28 @@
|
|
|
196
196
|
<a class="govuk-link" href="questions/contact-email">Change<span class="govuk-visually-hidden"> What is your email address for booking confirmations?</span></a>
|
|
197
197
|
</dd>
|
|
198
198
|
</div>
|
|
199
|
+
<div class="govuk-summary-list__row">
|
|
200
|
+
<dt class="govuk-summary-list__key">
|
|
201
|
+
Favourite Activity Reason
|
|
202
|
+
</dt>
|
|
203
|
+
<dd class="govuk-summary-list__value">
|
|
204
|
+
Relaxation<br>Details: test conditional answer
|
|
205
|
+
</dd>
|
|
206
|
+
<dd class="govuk-summary-list__actions">
|
|
207
|
+
<a class="govuk-link" href="questions/favourite-activity-reason">Change<span class="govuk-visually-hidden"> Why do you want to do your favourite activity?</span></a>
|
|
208
|
+
</dd>
|
|
209
|
+
</div>
|
|
210
|
+
<div class="govuk-summary-list__row">
|
|
211
|
+
<dt class="govuk-summary-list__key">
|
|
212
|
+
Travel Requirements
|
|
213
|
+
</dt>
|
|
214
|
+
<dd class="govuk-summary-list__value">
|
|
215
|
+
Dietary requirements<br>Dietary details: test conditional answer
|
|
216
|
+
</dd>
|
|
217
|
+
<dd class="govuk-summary-list__actions">
|
|
218
|
+
<a class="govuk-link" href="questions/travel-requirements">Change<span class="govuk-visually-hidden"> What special requirements do you have?</span></a>
|
|
219
|
+
</dd>
|
|
220
|
+
</div>
|
|
199
221
|
<div class="govuk-summary-list__row">
|
|
200
222
|
<dt class="govuk-summary-list__key">
|
|
201
223
|
Travel Companions
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<div class="govuk-grid-row">
|
|
2
|
+
<div class="govuk-grid-column-two-thirds">
|
|
3
|
+
<form action="" method="post" novalidate>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
<fieldset class="govuk-fieldset">
|
|
7
|
+
<legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
|
|
8
|
+
<h1 class="govuk-fieldset__heading">
|
|
9
|
+
Why do you want to do your favourite activity?
|
|
10
|
+
</h1>
|
|
11
|
+
</legend>
|
|
12
|
+
|
|
13
|
+
<div class="govuk-form-group">
|
|
14
|
+
<div class="govuk-radios govuk-radios" data-module="govuk-radios">
|
|
15
|
+
<div class="govuk-radios__item">
|
|
16
|
+
<input class="govuk-radios__input" id="favouriteActivityReason" name="favouriteActivityReason" type="radio" value="relaxation" data-aria-controls="conditional-favouriteActivityReason" data-cy="answer-relaxation">
|
|
17
|
+
<label class="govuk-label govuk-radios__label" for="favouriteActivityReason">
|
|
18
|
+
Relaxation
|
|
19
|
+
</label>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="govuk-radios__conditional govuk-radios__conditional--hidden" id="conditional-favouriteActivityReason">
|
|
22
|
+
<div class="govuk-form-group">
|
|
23
|
+
<label class="govuk-label" for="favouriteActivityReason_relaxationDetails">
|
|
24
|
+
How do you like to relax?
|
|
25
|
+
</label>
|
|
26
|
+
<input class="govuk-input" id="favouriteActivityReason_relaxationDetails" name="favouriteActivityReason_relaxationDetails" type="text" value="">
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="govuk-radios__item">
|
|
30
|
+
<input class="govuk-radios__input" id="favouriteActivityReason-2" name="favouriteActivityReason" type="radio" value="adventure" data-cy="answer-adventure">
|
|
31
|
+
<label class="govuk-label govuk-radios__label" for="favouriteActivityReason-2">
|
|
32
|
+
Adventure
|
|
33
|
+
</label>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="govuk-radios__item">
|
|
36
|
+
<input class="govuk-radios__input" id="favouriteActivityReason-3" name="favouriteActivityReason" type="radio" value="culture" data-cy="answer-culture">
|
|
37
|
+
<label class="govuk-label govuk-radios__label" for="favouriteActivityReason-3">
|
|
38
|
+
Culture
|
|
39
|
+
</label>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
</fieldset>
|
|
47
|
+
|
|
48
|
+
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|
|
49
|
+
Continue
|
|
50
|
+
</button>
|
|
51
|
+
|
|
52
|
+
</form>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="govuk-grid-row">
|
|
2
|
+
<div class="govuk-grid-column-two-thirds">
|
|
3
|
+
<form action="" method="post" novalidate>
|
|
4
|
+
<div class="govuk-form-group">
|
|
5
|
+
<fieldset class="govuk-fieldset">
|
|
6
|
+
<legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
|
|
7
|
+
<h1 class="govuk-fieldset__heading">
|
|
8
|
+
What special requirements do you have?
|
|
9
|
+
</h1>
|
|
10
|
+
</legend>
|
|
11
|
+
<div class="govuk-checkboxes govuk-checkboxes" data-module="govuk-checkboxes">
|
|
12
|
+
<div class="govuk-checkboxes__item">
|
|
13
|
+
<input class="govuk-checkboxes__input" id="travelRequirements" name="travelRequirements" type="checkbox" value="dietary" data-aria-controls="conditional-travelRequirements" data-cy="answer-dietary">
|
|
14
|
+
<label class="govuk-label govuk-checkboxes__label" for="travelRequirements">
|
|
15
|
+
Dietary requirements
|
|
16
|
+
</label>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="govuk-checkboxes__conditional govuk-checkboxes__conditional--hidden" id="conditional-travelRequirements">
|
|
19
|
+
<div class="govuk-form-group">
|
|
20
|
+
<label class="govuk-label" for="travelRequirements_dietaryDetails">
|
|
21
|
+
Please describe your dietary requirements
|
|
22
|
+
</label>
|
|
23
|
+
<input class="govuk-input" id="travelRequirements_dietaryDetails" name="travelRequirements_dietaryDetails" type="text" value="">
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="govuk-checkboxes__item">
|
|
27
|
+
<input class="govuk-checkboxes__input" id="travelRequirements-2" name="travelRequirements" type="checkbox" value="mobility" data-cy="answer-mobility">
|
|
28
|
+
<label class="govuk-label govuk-checkboxes__label" for="travelRequirements-2">
|
|
29
|
+
Mobility assistance
|
|
30
|
+
</label>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="govuk-checkboxes__item">
|
|
33
|
+
<input class="govuk-checkboxes__input" id="travelRequirements-3" name="travelRequirements" type="checkbox" value="medical" data-cy="answer-medical">
|
|
34
|
+
<label class="govuk-label govuk-checkboxes__label" for="travelRequirements-3">
|
|
35
|
+
Medical needs
|
|
36
|
+
</label>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</fieldset>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|
|
43
|
+
Continue
|
|
44
|
+
</button>
|
|
45
|
+
|
|
46
|
+
</form>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
@@ -101,9 +101,24 @@ export function mockAnswerBody(q) {
|
|
|
101
101
|
switch (q.type) {
|
|
102
102
|
case COMPONENT_TYPES.BOOLEAN:
|
|
103
103
|
return { [q.fieldName]: BOOLEAN_OPTIONS.YES };
|
|
104
|
-
case COMPONENT_TYPES.CHECKBOX:
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
case COMPONENT_TYPES.CHECKBOX: {
|
|
105
|
+
const result = { [q.fieldName]: [q.options[0].value] };
|
|
106
|
+
// Include conditional field if present on the first option
|
|
107
|
+
if (q.options[0].conditional?.fieldName) {
|
|
108
|
+
const conditionalFieldName = `${q.fieldName}_${q.options[0].conditional.fieldName}`;
|
|
109
|
+
result[conditionalFieldName] = 'test conditional answer';
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
case COMPONENT_TYPES.RADIO: {
|
|
114
|
+
const result = { [q.fieldName]: q.options[0].value };
|
|
115
|
+
// Include conditional field if present on the first option
|
|
116
|
+
if (q.options[0].conditional?.fieldName) {
|
|
117
|
+
const conditionalFieldName = `${q.fieldName}_${q.options[0].conditional.fieldName}`;
|
|
118
|
+
result[conditionalFieldName] = 'test conditional answer';
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
107
122
|
case COMPONENT_TYPES.SELECT:
|
|
108
123
|
return { [q.fieldName]: q.options[0].value };
|
|
109
124
|
case COMPONENT_TYPES.NUMBER:
|
|
@@ -181,9 +196,24 @@ export function mockAnswer(q) {
|
|
|
181
196
|
switch (q.type) {
|
|
182
197
|
case COMPONENT_TYPES.BOOLEAN:
|
|
183
198
|
return BOOLEAN_OPTIONS.YES;
|
|
184
|
-
case COMPONENT_TYPES.CHECKBOX:
|
|
185
|
-
|
|
186
|
-
|
|
199
|
+
case COMPONENT_TYPES.CHECKBOX: {
|
|
200
|
+
const optionText = q.options[0].text;
|
|
201
|
+
// Include conditional value if present on the first option
|
|
202
|
+
if (q.options[0].conditional?.fieldName) {
|
|
203
|
+
const label = q.options[0].conditional.label ? `${q.options[0].conditional.label} ` : '';
|
|
204
|
+
return `${optionText}<br>${label}test conditional answer`;
|
|
205
|
+
}
|
|
206
|
+
return optionText;
|
|
207
|
+
}
|
|
208
|
+
case COMPONENT_TYPES.RADIO: {
|
|
209
|
+
const optionText = q.options[0].text;
|
|
210
|
+
// Include conditional value if present on the first option
|
|
211
|
+
if (q.options[0].conditional?.fieldName) {
|
|
212
|
+
const label = q.options[0].conditional.label ? `${q.options[0].conditional.label} ` : '';
|
|
213
|
+
return `${optionText}<br>${label}test conditional answer`;
|
|
214
|
+
}
|
|
215
|
+
return optionText;
|
|
216
|
+
}
|
|
187
217
|
case COMPONENT_TYPES.SELECT:
|
|
188
218
|
return q.options[0].text;
|
|
189
219
|
case COMPONENT_TYPES.NUMBER:
|
|
@@ -3,6 +3,29 @@ import type ManageListQuestion from '#src/components/manage-list/question.js';
|
|
|
3
3
|
import type BaseValidator from '#src/validator/base-validator.js';
|
|
4
4
|
import type { JourneyResponse } from '#src/journey/journey-response.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Context passed to the custom summary formatter
|
|
8
|
+
*/
|
|
9
|
+
export interface SummaryFormatterContext<TAnswer = unknown> {
|
|
10
|
+
/** The raw answer value */
|
|
11
|
+
answer: TAnswer;
|
|
12
|
+
/** The default display value */
|
|
13
|
+
formattedAnswer: string;
|
|
14
|
+
/** The question instance */
|
|
15
|
+
question: import('./question.js').Question;
|
|
16
|
+
/** The journey instance */
|
|
17
|
+
journey: import('../journey/journey.js').Journey;
|
|
18
|
+
/** The section segment */
|
|
19
|
+
sectionSegment: string;
|
|
20
|
+
/** The selected option objects (for options-based questions) */
|
|
21
|
+
selectedOptions?: import('./options-question.js').Option[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Custom function to format the summary display value
|
|
26
|
+
*/
|
|
27
|
+
export type SummaryValueFormatter<TAnswer = unknown> = (context: SummaryFormatterContext<TAnswer>) => string;
|
|
28
|
+
|
|
6
29
|
export interface QuestionParameters {
|
|
7
30
|
title: string;
|
|
8
31
|
question: string;
|
|
@@ -21,6 +44,10 @@ export interface QuestionParameters {
|
|
|
21
44
|
editable?: boolean;
|
|
22
45
|
// override the action link for this question
|
|
23
46
|
actionLink?: ActionLink;
|
|
47
|
+
// custom function to format the summary display value
|
|
48
|
+
formatSummaryValue?: SummaryValueFormatter;
|
|
49
|
+
// whether to capitalise the first letter of the answer in summary (defaults to true)
|
|
50
|
+
capitaliseAnswer?: boolean;
|
|
24
51
|
// static view data for this question
|
|
25
52
|
viewData?: {
|
|
26
53
|
/**
|