@planning-inspectorate/dynamic-forms 2.4.0 → 3.1.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 +12 -1
- package/package.json +3 -2
- package/src/components/address/question.js +25 -19
- package/src/components/address/question.test.js +1 -1
- package/src/components/date/question.js +7 -21
- package/src/components/date/question.test.js +1 -1
- package/src/components/date-period/question.js +17 -25
- package/src/components/date-period/question.test.js +1 -1
- package/src/components/date-time/question.js +10 -23
- package/src/components/identifier/question.js +3 -6
- package/src/components/manage-list/README.md +97 -0
- package/src/components/manage-list/answer-summary-list.njk +10 -0
- package/src/components/manage-list/index.njk +61 -0
- package/src/components/manage-list/manage-list-section.js +39 -0
- package/src/components/manage-list/manage-list-section.test.js +52 -0
- package/src/components/manage-list/question.js +147 -0
- package/src/components/manage-list/question.test.js +139 -0
- package/src/components/multi-field-input/index.njk +1 -1
- package/src/components/multi-field-input/question.js +12 -13
- package/src/components/multi-field-input/question.test.js +8 -8
- package/src/components/number-entry/question.js +7 -13
- package/src/components/radio/question.js +2 -4
- package/src/components/select/question.js +2 -4
- package/src/components/single-line-input/question.js +5 -6
- package/src/components/text-entry/question.js +5 -5
- package/src/components/text-entry-redact/question.js +18 -9
- package/src/components/text-entry-redact/question.test.js +12 -19
- package/src/components/unit-option-entry/question.js +9 -8
- package/src/components/utils/nunjucks.js +20 -0
- package/src/controller.js +39 -10
- package/src/controller.test.js +90 -24
- package/src/index.js +3 -2
- package/src/journey/journey-response.js +2 -2
- package/src/journey/journey-types.d.ts +21 -1
- package/src/journey/journey.js +64 -18
- package/src/journey/journey.test.js +80 -15
- package/src/questions/options-question.js +6 -7
- package/src/questions/question-props.d.ts +2 -1
- package/src/questions/question-types.d.ts +26 -0
- package/src/questions/question.js +119 -15
- package/src/questions/question.test.js +98 -5
- package/src/questions/questions.js +3 -1
- package/src/section-types.d.ts +18 -0
- package/src/section.js +40 -11
- package/src/section.test.js +89 -0
- package/test/journey.js +5 -0
- package/test/mock/journey.js +17 -0
- package/test/questions.js +30 -1
- package/test/questions.test.js +104 -40
- package/test/snapshots/check-your-answers-not-started.html +11 -0
- package/test/snapshots/check-your-answers-with-answers.html +11 -0
- package/test/snapshots/manage-list-answer-summary.html +14 -0
- package/test/snapshots/manage-list-render-questions.html +97 -0
- package/test/snapshots/manage-list-render.html +91 -0
- package/test/snapshots/travel-companions.html +19 -0
- package/test/snapshots/travel-companions_travel-companion-email.html +21 -0
- package/test/snapshots/travel-companions_travel-companion-name.html +21 -0
- package/tsconfig.json +2 -1
package/test/questions.js
CHANGED
|
@@ -174,6 +174,27 @@ export const questionProps = {
|
|
|
174
174
|
url: 'contact-email',
|
|
175
175
|
label: 'Email address',
|
|
176
176
|
validators: [new EmailValidator()]
|
|
177
|
+
},
|
|
178
|
+
travelCompanions: {
|
|
179
|
+
type: COMPONENT_TYPES.MANAGE_LIST,
|
|
180
|
+
title: 'Travel Companions',
|
|
181
|
+
question: 'Travel Companions',
|
|
182
|
+
fieldName: 'travelCompanions',
|
|
183
|
+
url: 'travel-companions'
|
|
184
|
+
},
|
|
185
|
+
travelCompanionName: {
|
|
186
|
+
type: COMPONENT_TYPES.SINGLE_LINE_INPUT,
|
|
187
|
+
title: 'Travel Companion Name',
|
|
188
|
+
question: 'Travel Companion Name',
|
|
189
|
+
fieldName: 'travelCompanionName',
|
|
190
|
+
url: 'travel-companion-name'
|
|
191
|
+
},
|
|
192
|
+
travelCompanionEmail: {
|
|
193
|
+
type: COMPONENT_TYPES.EMAIL,
|
|
194
|
+
title: 'Travel Companion Email',
|
|
195
|
+
question: 'Travel Companion Email',
|
|
196
|
+
fieldName: 'travelCompanionEmail',
|
|
197
|
+
url: 'travel-companion-email'
|
|
177
198
|
}
|
|
178
199
|
};
|
|
179
200
|
|
|
@@ -194,7 +215,15 @@ export const questionsInOrder = [
|
|
|
194
215
|
questionProps.nights,
|
|
195
216
|
questionProps.hotelAddress,
|
|
196
217
|
questionProps.luggageWeight,
|
|
197
|
-
questionProps.contactEmail
|
|
218
|
+
questionProps.contactEmail,
|
|
219
|
+
questionProps.travelCompanions
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
export const manageListQuestions = [
|
|
223
|
+
{
|
|
224
|
+
manageListQuestion: questionProps.travelCompanions,
|
|
225
|
+
questions: [questionProps.travelCompanionName, questionProps.travelCompanionEmail]
|
|
226
|
+
}
|
|
198
227
|
];
|
|
199
228
|
|
|
200
229
|
export const getQuestions = () => createQuestions(questionProps, questionClasses, {});
|
package/test/questions.test.js
CHANGED
|
@@ -2,7 +2,7 @@ import { describe, it } from 'node:test';
|
|
|
2
2
|
import assert from 'assert';
|
|
3
3
|
import { createApp } from './utils/app.js';
|
|
4
4
|
import { TestServer } from './utils/test-server.js';
|
|
5
|
-
import { getQuestions, questionsInOrder } from './questions.js';
|
|
5
|
+
import { getQuestions, manageListQuestions, questionsInOrder } from './questions.js';
|
|
6
6
|
import { buildGetJourney } from '../src/middleware/build-get-journey.js';
|
|
7
7
|
import { createJourney, JOURNEY_ID } from './journey.js';
|
|
8
8
|
import { buildGetJourneyResponseFromSession, saveDataToSession } from '../src/lib/session-answer-store.js';
|
|
@@ -13,6 +13,7 @@ import path from 'path';
|
|
|
13
13
|
import { COMPONENT_TYPES } from '../src/index.js';
|
|
14
14
|
import { escapeForRegExp, snapshotsDir } from './utils/utils.js';
|
|
15
15
|
import { BOOLEAN_OPTIONS } from '../src/components/boolean/question.js';
|
|
16
|
+
import { mockRandomUUID } from '#src/lib/uuid.test.js';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* @param {import('node:test').TestContext} ctx
|
|
@@ -29,10 +30,15 @@ export async function createAppWithQuestions(ctx) {
|
|
|
29
30
|
// next();
|
|
30
31
|
// });
|
|
31
32
|
|
|
32
|
-
app.get(
|
|
33
|
+
app.get(
|
|
34
|
+
'/:section/:question{/:manageListAction/:manageListItemId/:manageListQuestion}',
|
|
35
|
+
getJourneyResponse,
|
|
36
|
+
getJourney,
|
|
37
|
+
question
|
|
38
|
+
);
|
|
33
39
|
|
|
34
40
|
app.post(
|
|
35
|
-
'/:section/:question',
|
|
41
|
+
'/:section/:question{/:manageListAction/:manageListItemId/:manageListQuestion}',
|
|
36
42
|
getJourneyResponse,
|
|
37
43
|
getJourney,
|
|
38
44
|
validate,
|
|
@@ -83,50 +89,72 @@ describe('question pages', () => {
|
|
|
83
89
|
}
|
|
84
90
|
});
|
|
85
91
|
|
|
92
|
+
/**
|
|
93
|
+
* @param {import('node:test').TestContext} ctx
|
|
94
|
+
* @param {string} url
|
|
95
|
+
* @param {string} snapshotName
|
|
96
|
+
* @param {import('#src/questions/question.js')} q
|
|
97
|
+
* @returns {Promise<void>}
|
|
98
|
+
*/
|
|
99
|
+
async function renderQuestionCheck(ctx, url, snapshotName, q) {
|
|
100
|
+
mockRandomUUID(ctx);
|
|
101
|
+
const testServer = await createAppWithQuestions(ctx);
|
|
102
|
+
|
|
103
|
+
const response = await testServer.get(url, {
|
|
104
|
+
redirect: 'manual'
|
|
105
|
+
});
|
|
106
|
+
assert.strictEqual(response.status, 200);
|
|
107
|
+
const text = await response.text();
|
|
108
|
+
// be sure to escape parentheses in the question text for the regex
|
|
109
|
+
assert.match(text, new RegExp(escapeForRegExp(q.question), 'i'));
|
|
110
|
+
assert.match(text, /<form action="" method="post"/i);
|
|
111
|
+
if (q.options) {
|
|
112
|
+
for (const option of q.options) {
|
|
113
|
+
if (q.type === COMPONENT_TYPES.SELECT) {
|
|
114
|
+
assert.match(
|
|
115
|
+
text,
|
|
116
|
+
new RegExp(`<option[^>]*value="${option.value}"[^>]*>\\s*${option.text}\\s*</option>`, 'i')
|
|
117
|
+
);
|
|
118
|
+
} else {
|
|
119
|
+
assert.match(text, new RegExp(`<input[^>]*value="${option.value}"[^>]*>`));
|
|
120
|
+
assert.match(text, new RegExp(`<label[^>]*>\\s*${option.text}\\s*</label>`, 'i'));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
ctx.assert.fileSnapshot(text, path.join(snapshotsDir(), snapshotName + '.html'), {
|
|
125
|
+
serializers: [(v) => v]
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @param {import('node:test').TestContext} ctx
|
|
131
|
+
* @param {string} url
|
|
132
|
+
* @param {import('#src/questions/question.js')} q
|
|
133
|
+
* @returns {Promise<string>}
|
|
134
|
+
*/
|
|
135
|
+
async function postQuestionCheck(ctx, url, q) {
|
|
136
|
+
const testServer = await createAppWithQuestions(ctx);
|
|
137
|
+
const payload = mockAnswerBody(q);
|
|
138
|
+
const response = await testServer.post(url, payload, { redirect: 'manual' });
|
|
139
|
+
if (![302, 303].includes(response.status)) {
|
|
140
|
+
const text = await response.text();
|
|
141
|
+
console.log(`Response for ${q.url}:\n`, text);
|
|
142
|
+
}
|
|
143
|
+
// Should redirect (302 or 303)
|
|
144
|
+
assert.ok([302, 303].includes(response.status), `Expected redirect, got ${response.status}`);
|
|
145
|
+
// Should redirect to the next question (if there is one)
|
|
146
|
+
return response.headers.get('location');
|
|
147
|
+
}
|
|
148
|
+
|
|
86
149
|
for (let i = 0; i < questionsInOrder.length; i++) {
|
|
87
150
|
const q = questionsInOrder[i];
|
|
88
151
|
|
|
89
152
|
it(`should render question: ${q.url}`, async (ctx) => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const response = await testServer.get('/questions/' + q.url, {
|
|
93
|
-
redirect: 'manual'
|
|
94
|
-
});
|
|
95
|
-
assert.strictEqual(response.status, 200);
|
|
96
|
-
const text = await response.text();
|
|
97
|
-
// be sure to escape parentheses in the question text for the regex
|
|
98
|
-
assert.match(text, new RegExp(escapeForRegExp(q.question), 'i'));
|
|
99
|
-
assert.match(text, /<form action="" method="post"/i);
|
|
100
|
-
if (q.options) {
|
|
101
|
-
for (const option of q.options) {
|
|
102
|
-
if (q.type === COMPONENT_TYPES.SELECT) {
|
|
103
|
-
assert.match(
|
|
104
|
-
text,
|
|
105
|
-
new RegExp(`<option[^>]*value="${option.value}"[^>]*>\\s*${option.text}\\s*</option>`, 'i')
|
|
106
|
-
);
|
|
107
|
-
} else {
|
|
108
|
-
assert.match(text, new RegExp(`<input[^>]*value="${option.value}"[^>]*>`));
|
|
109
|
-
assert.match(text, new RegExp(`<label[^>]*>\\s*${option.text}\\s*</label>`, 'i'));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
ctx.assert.fileSnapshot(text, path.join(snapshotsDir(), q.url + '.html'), {
|
|
114
|
-
serializers: [(v) => v]
|
|
115
|
-
});
|
|
153
|
+
await renderQuestionCheck(ctx, '/questions/' + q.url, q.url, q);
|
|
116
154
|
});
|
|
117
155
|
|
|
118
156
|
it(`should POST valid data for question: ${q.url} and redirect to next`, async (ctx) => {
|
|
119
|
-
const
|
|
120
|
-
const payload = mockAnswerBody(q);
|
|
121
|
-
const response = await testServer.post(`/questions/${q.url}`, payload, { redirect: 'manual' });
|
|
122
|
-
if (![302, 303].includes(response.status)) {
|
|
123
|
-
const text = await response.text();
|
|
124
|
-
console.log(`Response for ${q.url}:\n`, text);
|
|
125
|
-
}
|
|
126
|
-
// Should redirect (302 or 303)
|
|
127
|
-
assert.ok([302, 303].includes(response.status), `Expected redirect, got ${response.status}`);
|
|
128
|
-
// Should redirect to the next question (if there is one)
|
|
129
|
-
const location = response.headers.get('location');
|
|
157
|
+
const location = await postQuestionCheck(ctx, `/questions/${q.url}`, q);
|
|
130
158
|
const nextQ = questionsInOrder[i + 1];
|
|
131
159
|
if (nextQ) {
|
|
132
160
|
assert.strictEqual(location, `questions/${nextQ.url}`);
|
|
@@ -135,6 +163,29 @@ describe('question pages', () => {
|
|
|
135
163
|
}
|
|
136
164
|
});
|
|
137
165
|
}
|
|
166
|
+
|
|
167
|
+
describe('manage list questions', () => {
|
|
168
|
+
for (const { manageListQuestion, questions } of manageListQuestions) {
|
|
169
|
+
const qUrl = (q) => ['questions', manageListQuestion.url, 'add', 'id', q.url].join('/');
|
|
170
|
+
for (let i = 0; i < questions.length; i++) {
|
|
171
|
+
const q = questions[i];
|
|
172
|
+
it(`should render question: ${q.url}`, async (ctx) => {
|
|
173
|
+
await renderQuestionCheck(ctx, '/' + qUrl(q), manageListQuestion.url + '_' + q.url, q);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it(`should POST valid data for question: ${q.url} and redirect to next`, async (ctx) => {
|
|
177
|
+
const location = await postQuestionCheck(ctx, '/' + qUrl(q), q);
|
|
178
|
+
const nextQ = questions[i + 1];
|
|
179
|
+
if (nextQ) {
|
|
180
|
+
assert.strictEqual(location, qUrl(nextQ));
|
|
181
|
+
} else {
|
|
182
|
+
// at the end of the manage list section, return to the manage list question
|
|
183
|
+
assert.strictEqual(location, 'questions/' + manageListQuestion.url);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
138
189
|
});
|
|
139
190
|
|
|
140
191
|
/**
|
|
@@ -202,6 +253,16 @@ export function mockAnswerBody(q) {
|
|
|
202
253
|
};
|
|
203
254
|
case COMPONENT_TYPES.EMAIL:
|
|
204
255
|
return { [q.fieldName]: 'test@example.com' };
|
|
256
|
+
case COMPONENT_TYPES.MANAGE_LIST: {
|
|
257
|
+
// manage list questions not available here so just hard coded
|
|
258
|
+
return {
|
|
259
|
+
[q.fieldName]: [
|
|
260
|
+
{ travelCompanionName: 'Companion 1', travelCompanionEmail: 'compaion-1@example.com' },
|
|
261
|
+
{ travelCompanionName: 'Companion 2', travelCompanionEmail: 'compaion-2@example.com' },
|
|
262
|
+
{ travelCompanionName: 'Companion 3', travelCompanionEmail: 'compaion-3@example.com' }
|
|
263
|
+
]
|
|
264
|
+
};
|
|
265
|
+
}
|
|
205
266
|
default:
|
|
206
267
|
return { [q.fieldName]: 'test' };
|
|
207
268
|
}
|
|
@@ -251,6 +312,9 @@ export function mockAnswer(q) {
|
|
|
251
312
|
return '10 kg';
|
|
252
313
|
case COMPONENT_TYPES.EMAIL:
|
|
253
314
|
return 'test@example.com';
|
|
315
|
+
case COMPONENT_TYPES.MANAGE_LIST: {
|
|
316
|
+
return `3 ${q.title}`;
|
|
317
|
+
}
|
|
254
318
|
default:
|
|
255
319
|
return 'test';
|
|
256
320
|
}
|
|
@@ -196,6 +196,17 @@
|
|
|
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
|
+
Travel Companions
|
|
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/travel-companions">Answer<span class="govuk-visually-hidden"> Travel Companions</span></a>
|
|
208
|
+
</dd>
|
|
209
|
+
</div>
|
|
199
210
|
</dl>
|
|
200
211
|
|
|
201
212
|
<form action method="post">
|
|
@@ -196,6 +196,17 @@
|
|
|
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
|
+
Travel Companions
|
|
202
|
+
</dt>
|
|
203
|
+
<dd class="govuk-summary-list__value">
|
|
204
|
+
3 Travel Companions
|
|
205
|
+
</dd>
|
|
206
|
+
<dd class="govuk-summary-list__actions">
|
|
207
|
+
<a class="govuk-link" href="questions/travel-companions">Change<span class="govuk-visually-hidden"> Travel Companions</span></a>
|
|
208
|
+
</dd>
|
|
209
|
+
</div>
|
|
199
210
|
</dl>
|
|
200
211
|
|
|
201
212
|
<form action method="post">
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<div class="govuk-grid-row">
|
|
2
|
+
<div class="govuk-grid-column-two-thirds">
|
|
3
|
+
<form action="" method="post" novalidate>
|
|
4
|
+
|
|
5
|
+
<h1 class="govuk-heading-l">You have added 3 Things</h1>
|
|
6
|
+
|
|
7
|
+
<dl class="govuk-summary-list">
|
|
8
|
+
<div class="govuk-summary-list__row ">
|
|
9
|
+
<dt class="govuk-summary-list__key">
|
|
10
|
+
Thing 1
|
|
11
|
+
</dt>
|
|
12
|
+
<dt class="govuk-summary-list__value">
|
|
13
|
+
Q 1:<br>
|
|
14
|
+
mock answer
|
|
15
|
+
<br><br>
|
|
16
|
+
Q 2:<br>
|
|
17
|
+
mock answer 2
|
|
18
|
+
</dt>
|
|
19
|
+
<dd class="govuk-summary-list__actions">
|
|
20
|
+
<ul class="govuk-summary-list__actions-list">
|
|
21
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
22
|
+
<a class="govuk-link" href="/edit/id-1/first-question">
|
|
23
|
+
Change <span class="govuk-visually-hidden">Thing 1</span>
|
|
24
|
+
</a>
|
|
25
|
+
</li>
|
|
26
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
27
|
+
<a class="govuk-link" href="/remove/id-1/confirm">
|
|
28
|
+
Remove <span class="govuk-visually-hidden">Thing 1</span>
|
|
29
|
+
</a>
|
|
30
|
+
</li>
|
|
31
|
+
</ul>
|
|
32
|
+
</dd>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="govuk-summary-list__row ">
|
|
35
|
+
<dt class="govuk-summary-list__key">
|
|
36
|
+
Thing 2
|
|
37
|
+
</dt>
|
|
38
|
+
<dt class="govuk-summary-list__value">
|
|
39
|
+
Q 1:<br>
|
|
40
|
+
mock answer
|
|
41
|
+
<br><br>
|
|
42
|
+
Q 2:<br>
|
|
43
|
+
mock answer 2
|
|
44
|
+
</dt>
|
|
45
|
+
<dd class="govuk-summary-list__actions">
|
|
46
|
+
<ul class="govuk-summary-list__actions-list">
|
|
47
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
48
|
+
<a class="govuk-link" href="/edit/id-2/first-question">
|
|
49
|
+
Change <span class="govuk-visually-hidden">Thing 2</span>
|
|
50
|
+
</a>
|
|
51
|
+
</li>
|
|
52
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
53
|
+
<a class="govuk-link" href="/remove/id-2/confirm">
|
|
54
|
+
Remove <span class="govuk-visually-hidden">Thing 2</span>
|
|
55
|
+
</a>
|
|
56
|
+
</li>
|
|
57
|
+
</ul>
|
|
58
|
+
</dd>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="govuk-summary-list__row ">
|
|
61
|
+
<dt class="govuk-summary-list__key">
|
|
62
|
+
Thing 3
|
|
63
|
+
</dt>
|
|
64
|
+
<dt class="govuk-summary-list__value">
|
|
65
|
+
Q 1:<br>
|
|
66
|
+
mock answer
|
|
67
|
+
<br><br>
|
|
68
|
+
Q 2:<br>
|
|
69
|
+
mock answer 2
|
|
70
|
+
</dt>
|
|
71
|
+
<dd class="govuk-summary-list__actions">
|
|
72
|
+
<ul class="govuk-summary-list__actions-list">
|
|
73
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
74
|
+
<a class="govuk-link" href="/edit/id-3/first-question">
|
|
75
|
+
Change <span class="govuk-visually-hidden">Thing 3</span>
|
|
76
|
+
</a>
|
|
77
|
+
</li>
|
|
78
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
79
|
+
<a class="govuk-link" href="/remove/id-3/confirm">
|
|
80
|
+
Remove <span class="govuk-visually-hidden">Thing 3</span>
|
|
81
|
+
</a>
|
|
82
|
+
</li>
|
|
83
|
+
</ul>
|
|
84
|
+
</dd>
|
|
85
|
+
</div>
|
|
86
|
+
</dl>
|
|
87
|
+
|
|
88
|
+
<p class="govuk-body">
|
|
89
|
+
<a href="/add/00000000-0000-0000-0000-000000000000/first-question" class="govuk-link">Add another</a>
|
|
90
|
+
</p>
|
|
91
|
+
|
|
92
|
+
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|
|
93
|
+
Continue
|
|
94
|
+
</button>
|
|
95
|
+
</form>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<div class="govuk-grid-row">
|
|
2
|
+
<div class="govuk-grid-column-two-thirds">
|
|
3
|
+
<form action="" method="post" novalidate>
|
|
4
|
+
|
|
5
|
+
<h1 class="govuk-heading-l">You have added 3 Things</h1>
|
|
6
|
+
|
|
7
|
+
<dl class="govuk-summary-list">
|
|
8
|
+
<div class="govuk-summary-list__row ">
|
|
9
|
+
<dt class="govuk-summary-list__key">
|
|
10
|
+
Thing 1
|
|
11
|
+
</dt>
|
|
12
|
+
<dt class="govuk-summary-list__value">
|
|
13
|
+
mock answer
|
|
14
|
+
<br>
|
|
15
|
+
mock answer 2
|
|
16
|
+
</dt>
|
|
17
|
+
<dd class="govuk-summary-list__actions">
|
|
18
|
+
<ul class="govuk-summary-list__actions-list">
|
|
19
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
20
|
+
<a class="govuk-link" href="/edit/id-1/first-question">
|
|
21
|
+
Change <span class="govuk-visually-hidden">Thing 1</span>
|
|
22
|
+
</a>
|
|
23
|
+
</li>
|
|
24
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
25
|
+
<a class="govuk-link" href="/remove/id-1/confirm">
|
|
26
|
+
Remove <span class="govuk-visually-hidden">Thing 1</span>
|
|
27
|
+
</a>
|
|
28
|
+
</li>
|
|
29
|
+
</ul>
|
|
30
|
+
</dd>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="govuk-summary-list__row ">
|
|
33
|
+
<dt class="govuk-summary-list__key">
|
|
34
|
+
Thing 2
|
|
35
|
+
</dt>
|
|
36
|
+
<dt class="govuk-summary-list__value">
|
|
37
|
+
mock answer
|
|
38
|
+
<br>
|
|
39
|
+
mock answer 2
|
|
40
|
+
</dt>
|
|
41
|
+
<dd class="govuk-summary-list__actions">
|
|
42
|
+
<ul class="govuk-summary-list__actions-list">
|
|
43
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
44
|
+
<a class="govuk-link" href="/edit/id-2/first-question">
|
|
45
|
+
Change <span class="govuk-visually-hidden">Thing 2</span>
|
|
46
|
+
</a>
|
|
47
|
+
</li>
|
|
48
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
49
|
+
<a class="govuk-link" href="/remove/id-2/confirm">
|
|
50
|
+
Remove <span class="govuk-visually-hidden">Thing 2</span>
|
|
51
|
+
</a>
|
|
52
|
+
</li>
|
|
53
|
+
</ul>
|
|
54
|
+
</dd>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="govuk-summary-list__row ">
|
|
57
|
+
<dt class="govuk-summary-list__key">
|
|
58
|
+
Thing 3
|
|
59
|
+
</dt>
|
|
60
|
+
<dt class="govuk-summary-list__value">
|
|
61
|
+
mock answer
|
|
62
|
+
<br>
|
|
63
|
+
mock answer 2
|
|
64
|
+
</dt>
|
|
65
|
+
<dd class="govuk-summary-list__actions">
|
|
66
|
+
<ul class="govuk-summary-list__actions-list">
|
|
67
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
68
|
+
<a class="govuk-link" href="/edit/id-3/first-question">
|
|
69
|
+
Change <span class="govuk-visually-hidden">Thing 3</span>
|
|
70
|
+
</a>
|
|
71
|
+
</li>
|
|
72
|
+
<li class="govuk-summary-list__actions-list-item">
|
|
73
|
+
<a class="govuk-link" href="/remove/id-3/confirm">
|
|
74
|
+
Remove <span class="govuk-visually-hidden">Thing 3</span>
|
|
75
|
+
</a>
|
|
76
|
+
</li>
|
|
77
|
+
</ul>
|
|
78
|
+
</dd>
|
|
79
|
+
</div>
|
|
80
|
+
</dl>
|
|
81
|
+
|
|
82
|
+
<p class="govuk-body">
|
|
83
|
+
<a href="/add/00000000-0000-0000-0000-000000000000/first-question" class="govuk-link">Add another</a>
|
|
84
|
+
</p>
|
|
85
|
+
|
|
86
|
+
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|
|
87
|
+
Continue
|
|
88
|
+
</button>
|
|
89
|
+
</form>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div class="govuk-grid-row">
|
|
2
|
+
<div class="govuk-grid-column-two-thirds">
|
|
3
|
+
<form action="" method="post" novalidate>
|
|
4
|
+
|
|
5
|
+
<h1 class="govuk-heading-l">You have added 0 Travel Companions</h1>
|
|
6
|
+
|
|
7
|
+
<dl class="govuk-summary-list">
|
|
8
|
+
</dl>
|
|
9
|
+
|
|
10
|
+
<p class="govuk-body">
|
|
11
|
+
<a href="/questions/travel-companions/add/00000000-0000-0000-0000-000000000000/travel-companion-name" class="govuk-link">Add another</a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|
|
15
|
+
Continue
|
|
16
|
+
</button>
|
|
17
|
+
</form>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div class="govuk-grid-row">
|
|
2
|
+
<div class="govuk-grid-column-two-thirds">
|
|
3
|
+
<form action="" method="post" novalidate>
|
|
4
|
+
|
|
5
|
+
<div class="govuk-form-group">
|
|
6
|
+
<h1 class="govuk-label-wrapper">
|
|
7
|
+
<label class="govuk-label govuk-label--l" for="travelCompanionEmail">
|
|
8
|
+
Travel Companion Email
|
|
9
|
+
</label>
|
|
10
|
+
</h1>
|
|
11
|
+
<input class="govuk-input" id="travelCompanionEmail" name="travelCompanionEmail" type="email" value="" autocomplete="email" spellcheck="false">
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|
|
17
|
+
Continue
|
|
18
|
+
</button>
|
|
19
|
+
</form>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<div class="govuk-grid-row">
|
|
2
|
+
<div class="govuk-grid-column-two-thirds">
|
|
3
|
+
<form action="" method="post" novalidate>
|
|
4
|
+
|
|
5
|
+
<div class="govuk-form-group">
|
|
6
|
+
<h1 class="govuk-label-wrapper">
|
|
7
|
+
<label class="govuk-label govuk-label--l" for="travelCompanionName">
|
|
8
|
+
Travel Companion Name
|
|
9
|
+
</label>
|
|
10
|
+
</h1>
|
|
11
|
+
<input class="govuk-input" id="travelCompanionName" name="travelCompanionName" type="text" value="">
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|
|
17
|
+
Continue
|
|
18
|
+
</button>
|
|
19
|
+
</form>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|