@planning-inspectorate/dynamic-forms 3.18.1 → 3.19.1
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/package.json +1 -1
- package/src/components/date-period/question.d.ts +8 -6
- package/src/components/date-period/question.d.ts.map +1 -1
- package/src/components/date-period/question.js +18 -22
- package/src/components/date-period/question.test.js +87 -27
- package/src/components/manage-list/question.d.ts +2 -6
- package/src/components/manage-list/question.d.ts.map +1 -1
- package/src/components/manage-list/question.js +18 -22
- package/src/components/manage-list/question.test.js +35 -11
- package/src/questions/question.d.ts +4 -4
- package/src/questions/question.d.ts.map +1 -1
- package/src/questions/question.js +2 -2
- package/src/validator/conditional-required-validator.d.ts +0 -4
- package/src/validator/conditional-required-validator.d.ts.map +1 -1
- package/src/validator/conditional-required-validator.js +0 -5
- package/src/validator/confirmation-checkbox-validator.d.ts +0 -4
- package/src/validator/confirmation-checkbox-validator.d.ts.map +1 -1
- package/src/validator/confirmation-checkbox-validator.js +0 -5
- package/test/questions.test.js +2 -2
package/package.json
CHANGED
|
@@ -26,13 +26,15 @@ export class DatePeriodQuestion extends Question {
|
|
|
26
26
|
[x: string]: any;
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Formats the start/end date period for display in the summary.
|
|
30
|
+
*
|
|
31
|
+
* @param {{start?: string|Date, end?: string|Date}} answer
|
|
32
|
+
* @returns {string}
|
|
30
33
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}[];
|
|
34
|
+
formatAnswer(answer: {
|
|
35
|
+
start?: string | Date;
|
|
36
|
+
end?: string | Date;
|
|
37
|
+
}): string;
|
|
36
38
|
}
|
|
37
39
|
export default DatePeriodQuestion;
|
|
38
40
|
import { Question } from '#question';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAOA;;;GAGG;AACH;IACC;;OAEG;IACH,mGAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAuB1E;IAPA,mBAA4B;IAC5B;;;MAAsD;IAEtD,8BAA0B;IAC1B,4BAAsB;IACtB,kEAA+D;IAC/D,gEAA2D;IAkB5D;;;;;OAKG,CACH,mBAJW,OAAO,SAAS,EAAE,OAAO,mBACzB,OAAO,mBAAmB,EAAE,eAAe,GACzC,OAAO,CAAE,MAAM,CAAC,CAgC5B;IAED;;MAuCC;IAWD
|
|
1
|
+
{"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAOA;;;GAGG;AACH;IACC;;OAEG;IACH,mGAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAuB1E;IAPA,mBAA4B;IAC5B;;;MAAsD;IAEtD,8BAA0B;IAC1B,4BAAsB;IACtB,kEAA+D;IAC/D,gEAA2D;IAkB5D;;;;;OAKG,CACH,mBAJW,OAAO,SAAS,EAAE,OAAO,mBACzB,OAAO,mBAAmB,EAAE,eAAe,GACzC,OAAO,CAAE,MAAM,CAAC,CAgC5B;IAED;;MAuCC;IAWD;;;;;OAKG;IACH,qBAHW;QAAC,KAAK,CAAC,EAAE,MAAM,GAAC,IAAI,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,GAAC,IAAI,CAAA;KAAC,GACtC,MAAM,CAoBlB;CACD;;yBArKwB,WAAW"}
|
|
@@ -140,33 +140,29 @@ export class DatePeriodQuestion extends Question {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
|
-
*
|
|
143
|
+
* Formats the start/end date period for display in the summary.
|
|
144
|
+
*
|
|
145
|
+
* @param {{start?: string|Date, end?: string|Date}} answer
|
|
146
|
+
* @returns {string}
|
|
144
147
|
*/
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
formatAnswer(answer) {
|
|
149
|
+
if (!answer) {
|
|
150
|
+
return this.notStartedText;
|
|
151
|
+
}
|
|
147
152
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
formattedAnswer += `${this.labels.start}: ${start}`;
|
|
154
|
-
if (end) {
|
|
155
|
-
formattedAnswer += `\n`;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
153
|
+
const start = answer.start && formatDateForDisplay(answer.start, { format: this.dateFormat });
|
|
154
|
+
const end = answer.end && formatDateForDisplay(answer.end, { format: this.dateFormat });
|
|
155
|
+
let formattedAnswer = '';
|
|
156
|
+
if (start) {
|
|
157
|
+
formattedAnswer += `${this.labels.start}: ${start}`;
|
|
158
158
|
if (end) {
|
|
159
|
-
formattedAnswer +=
|
|
159
|
+
formattedAnswer += `\n`;
|
|
160
160
|
}
|
|
161
|
-
formattedAnswer = nl2br(escape(formattedAnswer));
|
|
162
|
-
} else {
|
|
163
|
-
formattedAnswer = this.notStartedText;
|
|
164
161
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
return [{ key: key, value: formattedAnswer, action: action }];
|
|
162
|
+
if (end) {
|
|
163
|
+
formattedAnswer += `${this.labels.end}: ${end}`;
|
|
164
|
+
}
|
|
165
|
+
return nl2br(escape(formattedAnswer));
|
|
170
166
|
}
|
|
171
167
|
}
|
|
172
168
|
|
|
@@ -258,7 +258,7 @@ describe('DatePeriodQuestion', () => {
|
|
|
258
258
|
});
|
|
259
259
|
});
|
|
260
260
|
|
|
261
|
-
describe('
|
|
261
|
+
describe('formatAnswer', () => {
|
|
262
262
|
it('should return correctly formatted answer if it exists', () => {
|
|
263
263
|
const dateQuestion = new DatePeriodQuestion({
|
|
264
264
|
title: TITLE,
|
|
@@ -274,22 +274,12 @@ describe('DatePeriodQuestion', () => {
|
|
|
274
274
|
start: new Date('2023-01-01T00:00:00.000Z'),
|
|
275
275
|
end: new Date('2023-01-10T00:00:00.000Z')
|
|
276
276
|
};
|
|
277
|
-
const href = 'fake href';
|
|
278
|
-
|
|
279
|
-
const journey = {
|
|
280
|
-
getCurrentQuestionUrl: () => {
|
|
281
|
-
return href;
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
277
|
|
|
285
|
-
const result = dateQuestion.
|
|
278
|
+
const result = dateQuestion.formatAnswer(answer);
|
|
286
279
|
|
|
287
|
-
assert.strictEqual(result
|
|
288
|
-
assert.strictEqual(result[0].action.href, href);
|
|
289
|
-
assert.strictEqual(result[0].action.text, 'Change');
|
|
290
|
-
assert.strictEqual(result[0].action.visuallyHiddenText, QUESTION);
|
|
291
|
-
assert.strictEqual(result[0].key, TITLE);
|
|
280
|
+
assert.strictEqual(result, 'Start: 00:00 1 January 2023<br>End: 00:00 10 January 2023');
|
|
292
281
|
});
|
|
282
|
+
|
|
293
283
|
it('should return start only if set', () => {
|
|
294
284
|
const dateQuestion = new DatePeriodQuestion({
|
|
295
285
|
title: TITLE,
|
|
@@ -304,21 +294,30 @@ describe('DatePeriodQuestion', () => {
|
|
|
304
294
|
const answer = {
|
|
305
295
|
start: new Date('2023-01-01T00:00:00.000Z')
|
|
306
296
|
};
|
|
307
|
-
const href = 'fake href';
|
|
308
297
|
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
298
|
+
const result = dateQuestion.formatAnswer(answer);
|
|
299
|
+
|
|
300
|
+
assert.strictEqual(result, 'Start: 00:00 1 January 2023');
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it('should return end only if set', () => {
|
|
304
|
+
const dateQuestion = new DatePeriodQuestion({
|
|
305
|
+
title: TITLE,
|
|
306
|
+
question: QUESTION,
|
|
307
|
+
fieldName: FIELDNAME,
|
|
308
|
+
hint: HINT,
|
|
309
|
+
hintStart: HINTSTART,
|
|
310
|
+
hintEnd: HINTEND,
|
|
311
|
+
validators: VALIDATORS
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
const answer = {
|
|
315
|
+
end: new Date('2023-01-10T00:00:00.000Z')
|
|
313
316
|
};
|
|
314
317
|
|
|
315
|
-
const result = dateQuestion.
|
|
318
|
+
const result = dateQuestion.formatAnswer(answer);
|
|
316
319
|
|
|
317
|
-
assert.strictEqual(result
|
|
318
|
-
assert.strictEqual(result[0].action.href, href);
|
|
319
|
-
assert.strictEqual(result[0].action.text, 'Change');
|
|
320
|
-
assert.strictEqual(result[0].action.visuallyHiddenText, QUESTION);
|
|
321
|
-
assert.strictEqual(result[0].key, TITLE);
|
|
320
|
+
assert.strictEqual(result, 'End: 00:00 10 January 2023');
|
|
322
321
|
});
|
|
323
322
|
|
|
324
323
|
it('should use custom labels if set', () => {
|
|
@@ -333,6 +332,66 @@ describe('DatePeriodQuestion', () => {
|
|
|
333
332
|
labels: { start: 'Open', end: 'Close' }
|
|
334
333
|
});
|
|
335
334
|
|
|
335
|
+
const answer = {
|
|
336
|
+
start: new Date('2023-01-01T00:00:00.000Z'),
|
|
337
|
+
end: new Date('2023-01-10T00:00:00.000Z')
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const result = dateQuestion.formatAnswer(answer);
|
|
341
|
+
|
|
342
|
+
assert.strictEqual(result, 'Open: 00:00 1 January 2023<br>Close: 00:00 10 January 2023');
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('should return not started text if answer does not exist', () => {
|
|
346
|
+
const dateQuestion = new DatePeriodQuestion({
|
|
347
|
+
title: TITLE,
|
|
348
|
+
question: QUESTION,
|
|
349
|
+
fieldName: FIELDNAME,
|
|
350
|
+
hint: HINT,
|
|
351
|
+
hintStart: HINTSTART,
|
|
352
|
+
hintEnd: HINTEND,
|
|
353
|
+
validators: VALIDATORS
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
const result = dateQuestion.formatAnswer(null);
|
|
357
|
+
|
|
358
|
+
assert.strictEqual(result, dateQuestion.notStartedText);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('should escape html in labels', () => {
|
|
362
|
+
const dateQuestion = new DatePeriodQuestion({
|
|
363
|
+
title: TITLE,
|
|
364
|
+
question: QUESTION,
|
|
365
|
+
fieldName: FIELDNAME,
|
|
366
|
+
hint: HINT,
|
|
367
|
+
hintStart: HINTSTART,
|
|
368
|
+
hintEnd: HINTEND,
|
|
369
|
+
validators: VALIDATORS,
|
|
370
|
+
labels: { start: '<b>Start</b>', end: 'End' }
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const answer = {
|
|
374
|
+
start: new Date('2023-01-01T00:00:00.000Z')
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const result = dateQuestion.formatAnswer(answer);
|
|
378
|
+
|
|
379
|
+
assert.strictEqual(result, '<b>Start</b>: 00:00 1 January 2023');
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
describe('formatAnswerForSummary', () => {
|
|
384
|
+
it('should integrate formatAnswer output with the summary row action and key', () => {
|
|
385
|
+
const dateQuestion = new DatePeriodQuestion({
|
|
386
|
+
title: TITLE,
|
|
387
|
+
question: QUESTION,
|
|
388
|
+
fieldName: FIELDNAME,
|
|
389
|
+
hint: HINT,
|
|
390
|
+
hintStart: HINTSTART,
|
|
391
|
+
hintEnd: HINTEND,
|
|
392
|
+
validators: VALIDATORS
|
|
393
|
+
});
|
|
394
|
+
|
|
336
395
|
const answer = {
|
|
337
396
|
start: new Date('2023-01-01T00:00:00.000Z'),
|
|
338
397
|
end: new Date('2023-01-10T00:00:00.000Z')
|
|
@@ -347,14 +406,15 @@ describe('DatePeriodQuestion', () => {
|
|
|
347
406
|
|
|
348
407
|
const result = dateQuestion.formatAnswerForSummary('segment', journey, answer);
|
|
349
408
|
|
|
350
|
-
assert.strictEqual(result[0].value,
|
|
409
|
+
assert.strictEqual(result[0].value, dateQuestion.formatAnswer(answer));
|
|
410
|
+
assert.strictEqual(result[0].value, 'Start: 00:00 1 January 2023<br>End: 00:00 10 January 2023');
|
|
351
411
|
assert.strictEqual(result[0].action.href, href);
|
|
352
412
|
assert.strictEqual(result[0].action.text, 'Change');
|
|
353
413
|
assert.strictEqual(result[0].action.visuallyHiddenText, QUESTION);
|
|
354
414
|
assert.strictEqual(result[0].key, TITLE);
|
|
355
415
|
});
|
|
356
416
|
|
|
357
|
-
it('should return not started if answer does not exist', () => {
|
|
417
|
+
it('should return not started action if answer does not exist', () => {
|
|
358
418
|
const dateQuestion = new DatePeriodQuestion({
|
|
359
419
|
title: TITLE,
|
|
360
420
|
question: QUESTION,
|
|
@@ -17,13 +17,9 @@ export class ManageListQuestion extends Question {
|
|
|
17
17
|
};
|
|
18
18
|
}>;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Format the answer for display in the summary, either as a count or as a list of answers
|
|
21
21
|
*/
|
|
22
|
-
|
|
23
|
-
key: string;
|
|
24
|
-
value: string;
|
|
25
|
-
action: import("#typedefs/question-types.d.ts").ActionView | import("#typedefs/question-types.d.ts").ActionView[] | undefined;
|
|
26
|
-
}[];
|
|
22
|
+
formatAnswer(answer: any): any;
|
|
27
23
|
renderConfirmationAction(res: any, itemToRemove: any, viewModel: any): void;
|
|
28
24
|
set section(section: import("../../section.js").Section);
|
|
29
25
|
get section(): import("../../section.js").Section;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;IAOC;;OAEG;IACH,oBAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAe1E;IAcD,wCAEC;IAyDD;;;;OAMC;IAED;;OAEG;IACH
|
|
1
|
+
{"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;IAOC;;OAEG;IACH,oBAFW,OAAO,+BAA+B,EAAE,wBAAwB,EAe1E;IAcD,wCAEC;IAyDD;;;;OAMC;IAED;;OAEG;IACH,+BAkBC;IAED,4EAQC;IAoCD,yDAEC;IATD,kDAKC;;CAKD;;;;;;mBApLa,MAAM;;;;;;;;;;;;;;yBAPK,WAAW"}
|
|
@@ -116,30 +116,26 @@ export class ManageListQuestion extends Question {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
|
119
|
-
*
|
|
119
|
+
* Format the answer for display in the summary, either as a count or as a list of answers
|
|
120
120
|
*/
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (this.#showAnswersInSummary) {
|
|
125
|
-
const answers = answer.map((a) => this.#formatItemAnswers(a));
|
|
126
|
-
// note: nunjucks.render uses the last configured environment
|
|
127
|
-
// so we assume here that it is the one used by the main application and
|
|
128
|
-
// is configured for dynamic-forms and govuk components
|
|
129
|
-
formattedAnswer = nunjucks.render('components/manage-list/answer-summary-list.njk', { answers });
|
|
130
|
-
} else if (answer.length > 0) {
|
|
131
|
-
formattedAnswer = `${answer.length} ${this.title}`;
|
|
132
|
-
}
|
|
121
|
+
formatAnswer(answer) {
|
|
122
|
+
if (!answer || !Array.isArray(answer)) {
|
|
123
|
+
return this.notStartedText;
|
|
133
124
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
125
|
+
|
|
126
|
+
if (this.#showAnswersInSummary) {
|
|
127
|
+
const answers = answer.map((a) => this.#formatItemAnswers(a));
|
|
128
|
+
// note: nunjucks.render uses the last configured environment
|
|
129
|
+
// so we assume here that it is the one used by the main application and
|
|
130
|
+
// is configured for dynamic-forms and govuk components
|
|
131
|
+
return nunjucks.render('components/manage-list/answer-summary-list.njk', { answers });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (answer.length > 0) {
|
|
135
|
+
return `${answer.length} ${this.title}`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return this.notStartedText;
|
|
143
139
|
}
|
|
144
140
|
|
|
145
141
|
renderConfirmationAction(res, itemToRemove, viewModel) {
|
|
@@ -81,21 +81,45 @@ describe('components/manage-list/question', () => {
|
|
|
81
81
|
});
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
describe('formatAnswer', () => {
|
|
85
|
+
it('should return the not started text when answer is not set', () => {
|
|
86
|
+
const q = newQuestion();
|
|
87
|
+
assert.strictEqual(q.formatAnswer(undefined), q.notStartedText);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should return the not started text when answer is not an array', () => {
|
|
91
|
+
const q = newQuestion();
|
|
92
|
+
assert.strictEqual(q.formatAnswer('not-an-array'), q.notStartedText);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should return the not started text when answer is an empty array', () => {
|
|
96
|
+
const q = newQuestion();
|
|
97
|
+
assert.strictEqual(q.formatAnswer([]), q.notStartedText);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should return a count of the answers by default', () => {
|
|
101
|
+
const q = newQuestion();
|
|
102
|
+
assert.strictEqual(q.formatAnswer([{}, {}, {}]), '3 Things');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should render all answers when showAnswersInSummary is true', (ctx) => {
|
|
106
|
+
// nunjucks.render uses the last environment configured, so make sure one is configured
|
|
107
|
+
configureNunjucksTestEnv();
|
|
108
|
+
const { q } = questionWithManageQuestions(ctx, { showAnswersInSummary: true });
|
|
109
|
+
const formatted = q.formatAnswer([{}, {}, {}]);
|
|
110
|
+
assertSnapshot(ctx, formatted, 'manage-list-answer-summary.html');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should integrate with formatAnswerForSummary to build a full summary row', (ctx) => {
|
|
85
115
|
const q = newQuestion();
|
|
86
116
|
mockRandomUUID(ctx);
|
|
87
|
-
const
|
|
117
|
+
const journey = mockJourney();
|
|
118
|
+
const answerForSummary = q.formatAnswerForSummary('section-1', journey, [{}, {}, {}]);
|
|
88
119
|
assert.strictEqual(answerForSummary.length, 1);
|
|
120
|
+
assert.deepStrictEqual(answerForSummary[0].key, TITLE);
|
|
89
121
|
assert.strictEqual(answerForSummary[0].value, '3 Things');
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
it('should support showing all answers in the format list answer for summary', (ctx) => {
|
|
93
|
-
// nunjucks.render uses the last environment configured, so make sure one is configured
|
|
94
|
-
configureNunjucksTestEnv();
|
|
95
|
-
const { q } = questionWithManageQuestions(ctx, { showAnswersInSummary: true });
|
|
96
|
-
const answerForSummary = q.formatAnswerForSummary('section-1', mockJourney(), [{}, {}, {}]);
|
|
97
|
-
assert.strictEqual(answerForSummary.length, 1);
|
|
98
|
-
assertSnapshot(ctx, answerForSummary[0].value, 'manage-list-answer-summary.html');
|
|
122
|
+
assert.ok(answerForSummary[0].action);
|
|
99
123
|
});
|
|
100
124
|
|
|
101
125
|
it('should render with answers', (ctx) => {
|
|
@@ -105,7 +105,7 @@ export class Question {
|
|
|
105
105
|
*
|
|
106
106
|
* @param {Object} options
|
|
107
107
|
* @param {import('#typedefs/journey-types.d.ts').RouteParams} options.params
|
|
108
|
-
* @param {import('../components/manage-list/question.js')} [options.manageListQuestion]
|
|
108
|
+
* @param {import('../components/manage-list/question.js').ManageListQuestion} [options.manageListQuestion]
|
|
109
109
|
* @param {import('../section.js').Section} options.section - the current section
|
|
110
110
|
* @param {import('../journey/journey.js').Journey} options.journey - the journey we are in
|
|
111
111
|
* @param {Record<string, unknown>} [options.customViewData] additional data to send to view
|
|
@@ -114,7 +114,7 @@ export class Question {
|
|
|
114
114
|
*/
|
|
115
115
|
toViewModel({ params, manageListQuestion, section, journey, customViewData, payload }: {
|
|
116
116
|
params: import("#typedefs/journey-types.d.ts").RouteParams;
|
|
117
|
-
manageListQuestion?:
|
|
117
|
+
manageListQuestion?: import("../components/manage-list/question.js").ManageListQuestion | undefined;
|
|
118
118
|
section: import("../section.js").Section;
|
|
119
119
|
journey: import("../journey/journey.js").Journey;
|
|
120
120
|
customViewData?: Record<string, unknown> | undefined;
|
|
@@ -167,10 +167,10 @@ export class Question {
|
|
|
167
167
|
* @param {import('express').Request} req
|
|
168
168
|
* @param {import('../journey/journey.js').Journey} journey
|
|
169
169
|
* @param {import('../section.js').Section} section
|
|
170
|
-
* @param {import('../components/manage-list/question.js')} [manageListQuestion]
|
|
170
|
+
* @param {import('../components/manage-list/question.js').ManageListQuestion} [manageListQuestion]
|
|
171
171
|
* @returns {import('#typedefs/question-types.d.ts').QuestionViewModel|undefined} returns the view model for displaying the error or undefined if there are no errors
|
|
172
172
|
*/
|
|
173
|
-
checkForValidationErrors(req: import("express").Request, section: import("../section.js").Section, journey: import("../journey/journey.js").Journey, manageListQuestion?:
|
|
173
|
+
checkForValidationErrors(req: import("express").Request, section: import("../section.js").Section, journey: import("../journey/journey.js").Journey, manageListQuestion?: import("../components/manage-list/question.js").ManageListQuestion): import("#typedefs/question-types.d.ts").QuestionViewModel | undefined;
|
|
174
174
|
/**
|
|
175
175
|
* Get the data to save from the request, returns an object of answers
|
|
176
176
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"AAKA;;;GAGG;AACH;IAiEC;;;OAGG;IACH,+NAHW,OAAO,+BAA+B,EAAE,kBAAkB,oBAC1D,MAAM,CAAC,MAAM,WAAW,EA0DlC;IA5HD,6EAA6E;IAC7E,WADW,MAAM,CACP;IACV,sDAAsD;IACtD,OADW,MAAM,CACX;IACN,+DAA+D;IAC/D,UADW,MAAM,CACR;IACT,mFAAmF;IACnF,aADW,MAAM,GAAC,SAAS,CACf;IACZ,iDAAiD;IACjD,YADW,MAAM,CACN;IACX,qHAAqH;IACrH,WADW,MAAM,CACP;IACV,6FAA6F;IAC7F,UADW,OAAO,CACF;IAChB,0IAA0I;IAC1I,YADW,KAAK,CAAE,OAAO,gCAAgC,EAAE,aAAa,CAAC,CACzD;IAChB,2DAA2D;IAC3D,MADW,MAAM,GAAC,SAAS,CACtB;IACL,sEAAsE;IACtE,oBADW,OAAO,CACQ;IAC1B,oDAAoD;IACpD,KADW,MAAM,GAAC,SAAS,CACvB;IACJ,qDAAqD;IACrD,MADW,MAAM,GAAC,SAAS,CACtB;IACL,sDAAsD;IACtD,eADW,MAAM,GAAC,SAAS,CACb;IACd,gGAAgG;IAChG,YADW,OAAO,+BAA+B,EAAE,UAAU,GAAC,SAAS,CAC5D;IAEX,iFAAiF;IACjF,gBADW,MAAM,CACc;IAC/B,sFAAsF;IACtF,kBADW,OAAO,CACM;IACxB,4CAA4C;IAC5C,oBADW,MAAM,CACe;IAChC,uDAAuD;IACvD,kBADW,MAAM,CACW;IAC5B,uDAAuD;IACvD,kBADW,MAAM,CACW;IAC5B,oDAAoD;IACpD,eADW,MAAM,CACK;IACtB,0IAA0I;IAC1I,oBADW,OAAO,+BAA+B,EAAE,qBAAqB,GAAC,SAAS,CAC/D;IAEnB;;;OAGG;IAEH,gBAAiB,WAJN,OAAO,gCAAgC,EAAE,eAI3B,KAHZ,OAAO,CAGe;IAEnC;;;MAGE;IACF;;;;;;OAMG;IACH,wBAFU,OAAO,CAEc;IA2C9B,iCAAgC;IAChC,kBAAwB;IAExB;;;;MAAwB;IAkBzB;;;;;;OAMG;IACH,4BAFa,OAAO,CAInB;IAWD,iCANa,OAAO,EAWnB;IAdD;;;;OAIG;IACH,6BAFa,OAAO,CAInB;IAqBD;;;;;;OAMG;IACH,sBAFa,MAAM,EAAE,CAIpB;IAED;;;;;;;;;;;;;;OAcG;IACH,uFARG;QAAoE,MAAM,EAAlE,OAAO,8BAA8B,EAAE,WAAW;
|
|
1
|
+
{"version":3,"file":"question.d.ts","sourceRoot":"","sources":["question.js"],"names":[],"mappings":"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"}
|
|
@@ -192,7 +192,7 @@ export class Question {
|
|
|
192
192
|
*
|
|
193
193
|
* @param {Object} options
|
|
194
194
|
* @param {import('#typedefs/journey-types.d.ts').RouteParams} options.params
|
|
195
|
-
* @param {import('../components/manage-list/question.js')} [options.manageListQuestion]
|
|
195
|
+
* @param {import('../components/manage-list/question.js').ManageListQuestion} [options.manageListQuestion]
|
|
196
196
|
* @param {import('../section.js').Section} options.section - the current section
|
|
197
197
|
* @param {import('../journey/journey.js').Journey} options.journey - the journey we are in
|
|
198
198
|
* @param {Record<string, unknown>} [options.customViewData] additional data to send to view
|
|
@@ -320,7 +320,7 @@ export class Question {
|
|
|
320
320
|
* @param {import('express').Request} req
|
|
321
321
|
* @param {import('../journey/journey.js').Journey} journey
|
|
322
322
|
* @param {import('../section.js').Section} section
|
|
323
|
-
* @param {import('../components/manage-list/question.js')} [manageListQuestion]
|
|
323
|
+
* @param {import('../components/manage-list/question.js').ManageListQuestion} [manageListQuestion]
|
|
324
324
|
* @returns {import('#typedefs/question-types.d.ts').QuestionViewModel|undefined} returns the view model for displaying the error or undefined if there are no errors
|
|
325
325
|
*/
|
|
326
326
|
checkForValidationErrors(req, section, journey, manageListQuestion) {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {import('../questions/question.js')} Question
|
|
3
|
-
*/
|
|
4
1
|
/**
|
|
5
2
|
* enforces a field is not empty when condition is satisfied
|
|
6
3
|
* @class
|
|
@@ -20,6 +17,5 @@ export class ConditionalRequiredValidator extends BaseValidator {
|
|
|
20
17
|
isValueIncluded(questionObj: any, value: any): import("express-validator").ValidationChain;
|
|
21
18
|
}
|
|
22
19
|
export default ConditionalRequiredValidator;
|
|
23
|
-
export type Question = typeof import("../questions/question.js");
|
|
24
20
|
import BaseValidator from './base-validator.js';
|
|
25
21
|
//# sourceMappingURL=conditional-required-validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditional-required-validator.d.ts","sourceRoot":"","sources":["conditional-required-validator.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conditional-required-validator.d.ts","sourceRoot":"","sources":["conditional-required-validator.js"],"names":[],"mappings":"AAIA;;;GAGG;AACH;IAMC;;;OAGG;IACH,2BAFW,MAAM,EAQhB;IAED;;;OAGG;IACH,sBAFW,OAAO,kCAAkC,EAAE,eAAe,WAcpE;IAED,+DAEC;IAED,2FAKC;CACD;;0BArDyB,qBAAqB"}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { body } from 'express-validator';
|
|
2
|
-
|
|
3
2
|
import BaseValidator from './base-validator.js';
|
|
4
3
|
import { toArray } from '#src/lib/utils.js';
|
|
5
4
|
|
|
6
|
-
/**
|
|
7
|
-
* @typedef {import('../questions/question.js')} Question
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
5
|
/**
|
|
11
6
|
* enforces a field is not empty when condition is satisfied
|
|
12
7
|
* @class
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {import('../questions/question.js')} Question
|
|
3
|
-
*/
|
|
4
1
|
/**
|
|
5
2
|
* enforces a confirmation checkbox is checked before proceeding
|
|
6
3
|
* @class
|
|
@@ -23,6 +20,5 @@ export class ConfirmationCheckboxValidator extends BaseValidator {
|
|
|
23
20
|
validate(): import("express-validator").ValidationChain;
|
|
24
21
|
}
|
|
25
22
|
export default ConfirmationCheckboxValidator;
|
|
26
|
-
export type Question = typeof import("../questions/question.js");
|
|
27
23
|
import BaseValidator from './base-validator.js';
|
|
28
24
|
//# sourceMappingURL=confirmation-checkbox-validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmation-checkbox-validator.d.ts","sourceRoot":"","sources":["confirmation-checkbox-validator.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"confirmation-checkbox-validator.d.ts","sourceRoot":"","sources":["confirmation-checkbox-validator.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH;IAMC;;;;;OAKG;IACH,4CAHG;QAAuB,YAAY,EAA3B,MAAM;QACS,YAAY,EAA3B,MAAM;KAChB,EAMA;IAFA,qBAAgC;IAIjC;;OAEG;IACH,wDAEC;CACD;;0BA/ByB,qBAAqB"}
|
package/test/questions.test.js
CHANGED
|
@@ -31,7 +31,7 @@ describe('question pages', () => {
|
|
|
31
31
|
* @param {import('node:test').TestContext} ctx
|
|
32
32
|
* @param {string} url
|
|
33
33
|
* @param {string} snapshotName
|
|
34
|
-
* @param {import('#src/questions/question.js')} q
|
|
34
|
+
* @param {import('#src/questions/question.js').Question} q
|
|
35
35
|
* @returns {Promise<void>}
|
|
36
36
|
*/
|
|
37
37
|
async function renderQuestionAndSnapshot(ctx, url, snapshotName, q) {
|
|
@@ -59,7 +59,7 @@ describe('question pages', () => {
|
|
|
59
59
|
/**
|
|
60
60
|
* @param {import('node:test').TestContext} ctx
|
|
61
61
|
* @param {string} url
|
|
62
|
-
* @param {import('#src/questions/question.js')} q
|
|
62
|
+
* @param {import('#src/questions/question.js').Question} q
|
|
63
63
|
* @returns {Promise<string>}
|
|
64
64
|
*/
|
|
65
65
|
async function postQuestionCheck(ctx, url, q) {
|