Skip to content

Commit 7587d31

Browse files
authored
Merge pull request #15 from NHSDigital/d-05-session-edit-subflows
D-05: complete single-session changes within each edit subflow
2 parents b96b002 + 4782caf commit 7587d31

4 files changed

Lines changed: 195 additions & 21 deletions

File tree

app/routes/sessions.js

Lines changed: 82 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,43 @@ function sessions (router, shared) {
2626
return `/sites/${siteId}/session/${availId}/${date}/breaks`
2727
}
2828

29+
function getSessionEditBaseHref (siteId, availId, date) {
30+
return `/sites/${siteId}/session/${availId}/${date}/edit`
31+
}
32+
33+
function getSessionEditCheckHref (siteId, availId, date) {
34+
return `${getSessionEditBaseHref(siteId, availId, date)}/check`
35+
}
36+
37+
function getSessionEditPathHref (siteId, availId, date, editPath) {
38+
const base = getSessionEditBaseHref(siteId, availId, date)
39+
if (editPath === 'booking-length') return `${base}/booking-length`
40+
if (editPath === 'services') return `${base}/services`
41+
return `${base}/times`
42+
}
43+
44+
function renderSessionEditCheckPage (req, res, avail, draft) {
45+
const serviceNames = (draft.services || [])
46+
.map(id => (req.data.services[id] ? req.data.services[id].name : id))
47+
const editLabel = draft.editPath === 'booking-length'
48+
? 'booking length'
49+
: (draft.editPath === 'services' ? 'services' : 'session times')
50+
51+
res.render('sites/session-edit-check', {
52+
site: req.site,
53+
sessionLabel: avail.label,
54+
date: req.params.date,
55+
editLabel,
56+
draft,
57+
serviceNames,
58+
formAction: getSessionEditCheckHref(req.site.id, avail.id, req.params.date),
59+
backHref: getSessionEditPathHref(req.site.id, avail.id, req.params.date, draft.editPath),
60+
changeHref: getSessionEditPathHref(req.site.id, avail.id, req.params.date, draft.editPath),
61+
affectedCount: (draft.affectedBookingIds || []).length,
62+
bookingsHref: `${getSessionEditInfoHref(req.site.id, avail.id, req.params.date)}/warning`
63+
})
64+
}
65+
2966
function getSessionBreakBackHref (siteId, availId, date, draft) {
3067
const base = getSessionBreaksBaseHref(siteId, availId, date)
3168
if (draft.breakAction === 'change' && Number.isInteger(draft.breakIndex)) return `${base}/${draft.breakIndex}/change`
@@ -110,16 +147,7 @@ function sessions (router, shared) {
110147
})
111148

112149
router.post('/sites/:siteId/session/:availId/:date', (req, res) => {
113-
const avail = req.site.availability.find(a => a.id === req.params.availId)
114-
if (!avail) return res.status(404).send('Availability not found')
115-
const draft = ensureSessionEditDraft(req, avail, req.params.date)
116-
117-
if ((draft.affectedBookingIds || []).length > 0) {
118-
return res.redirect(`${getSessionEditInfoHref(req.site.id, avail.id, req.params.date)}/warning`)
119-
}
120-
121-
applySessionEditDraft(req, avail, draft)
122-
res.redirect(`${getSessionEditInfoHref(req.site.id, avail.id, req.params.date)}/success`)
150+
res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
123151
})
124152

125153
router.get('/sites/:siteId/session/:availId/:date/remove', (req, res) => {
@@ -469,6 +497,7 @@ function sessions (router, shared) {
469497
const draft = req.session.data.sessionEditDraft
470498
if (!draft) return res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
471499
const base = `/sites/${req.site.id}/session/${req.params.availId}/${req.params.date}/edit`
500+
draft.editPath = 'times'
472501

473502
res.render('sites/availability-shared-times', {
474503
site: req.site,
@@ -501,14 +530,20 @@ function sessions (router, shared) {
501530
}
502531

503532
draft.timeBlocks = parsedBlocks
533+
draft.editPath = 'times'
504534
updateSessionEditDraftImpacts(req.site, req.params.availId, req.params.date, draft)
505-
res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
535+
if ((draft.affectedBookingIds || []).length > 0) {
536+
return res.redirect(`${getSessionEditInfoHref(req.site.id, req.params.availId, req.params.date)}/warning`)
537+
}
538+
539+
res.redirect(getSessionEditCheckHref(req.site.id, req.params.availId, req.params.date))
506540
})
507541

508542
router.get('/sites/:siteId/session/:availId/:date/edit/booking-length', (req, res) => {
509543
const draft = req.session.data.sessionEditDraft
510544
if (!draft) return res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
511545
const base = `/sites/${req.site.id}/session/${req.params.availId}/${req.params.date}/edit`
546+
draft.editPath = 'booking-length'
512547

513548
res.render('sites/availability-shared-booking-length', {
514549
site: req.site,
@@ -538,14 +573,20 @@ function sessions (router, shared) {
538573
}
539574

540575
draft.slotLength = value
576+
draft.editPath = 'booking-length'
541577
updateSessionEditDraftImpacts(req.site, req.params.availId, req.params.date, draft)
542-
res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
578+
if ((draft.affectedBookingIds || []).length > 0) {
579+
return res.redirect(`${getSessionEditInfoHref(req.site.id, req.params.availId, req.params.date)}/warning`)
580+
}
581+
582+
res.redirect(getSessionEditCheckHref(req.site.id, req.params.availId, req.params.date))
543583
})
544584

545585
router.get('/sites/:siteId/session/:availId/:date/edit/services', (req, res) => {
546586
const draft = req.session.data.sessionEditDraft
547587
if (!draft) return res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
548588
const base = `/sites/${req.site.id}/session/${req.params.availId}/${req.params.date}/edit`
589+
draft.editPath = 'services'
549590

550591
res.render('sites/availability-shared-services', {
551592
site: req.site,
@@ -579,8 +620,32 @@ function sessions (router, shared) {
579620
}
580621

581622
draft.services = services
623+
draft.editPath = 'services'
582624
updateSessionEditDraftImpacts(req.site, req.params.availId, req.params.date, draft)
583-
res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
625+
if ((draft.affectedBookingIds || []).length > 0) {
626+
return res.redirect(`${getSessionEditInfoHref(req.site.id, req.params.availId, req.params.date)}/warning`)
627+
}
628+
629+
res.redirect(getSessionEditCheckHref(req.site.id, req.params.availId, req.params.date))
630+
})
631+
632+
router.get('/sites/:siteId/session/:availId/:date/edit/check', (req, res) => {
633+
const avail = req.site.availability.find(a => a.id === req.params.availId)
634+
const draft = req.session.data.sessionEditDraft
635+
if (!avail) return res.status(404).send('Availability not found')
636+
if (!draft || !draft.editPath) return res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
637+
638+
renderSessionEditCheckPage(req, res, avail, draft)
639+
})
640+
641+
router.post('/sites/:siteId/session/:availId/:date/edit/check', (req, res) => {
642+
const avail = req.site.availability.find(a => a.id === req.params.availId)
643+
const draft = req.session.data.sessionEditDraft
644+
if (!avail) return res.status(404).send('Availability not found')
645+
if (!draft || !draft.editPath) return res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
646+
647+
applySessionEditDraft(req, avail, draft)
648+
res.redirect(`${getSessionEditInfoHref(req.site.id, avail.id, req.params.date)}/success`)
584649
})
585650

586651
router.get('/sites/:siteId/session/:availId/:date/edit/warning', (req, res) => {
@@ -608,7 +673,9 @@ function sessions (router, shared) {
608673
affectedCount: affected.length,
609674
affectedBookingRows,
610675
formAction: `${base}/warning`,
611-
backHref: getSessionEditSummaryHref(site.id, req.params.availId, date)
676+
backHref: draft.editPath
677+
? getSessionEditPathHref(site.id, req.params.availId, date, draft.editPath)
678+
: getSessionEditSummaryHref(site.id, req.params.availId, date)
612679
})
613680
})
614681

@@ -619,8 +686,7 @@ function sessions (router, shared) {
619686
if (!draft) return res.redirect(getSessionEditSummaryHref(req.site.id, req.params.availId, req.params.date))
620687

621688
draft.bookingsChoice = req.body.bookingsChoice || 'keep'
622-
applySessionEditDraft(req, avail, draft)
623-
res.redirect(`${getSessionEditInfoHref(req.site.id, avail.id, req.params.date)}/success`)
689+
res.redirect(getSessionEditCheckHref(req.site.id, avail.id, req.params.date))
624690
})
625691

626692
router.get('/sites/:siteId/session/:availId/:date/edit/success', (req, res) => {

app/routes/shared/session-edit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ function buildSessionEditDraft (avail, date) {
123123
originalBreakTimes: avail.breakTimes || [],
124124
affectedBookingIds: [],
125125
unaffectedBookingIds: [],
126+
editPath: null,
126127
changeDescription: 'session times',
127128
bookingsChoice: 'keep'
128129
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{% extends 'layout.html' %}
2+
3+
{% set pageName = "Check your answers — " + site.name %}
4+
5+
{% block beforeContent %}
6+
{{ backLink({ href: backHref }) }}
7+
{% endblock %}
8+
9+
{% block content %}
10+
<div class="nhsuk-grid-row">
11+
<div class="nhsuk-grid-column-two-thirds">
12+
13+
<h1 class="nhsuk-heading-xl">Check your answers</h1>
14+
15+
<p class="nhsuk-body">Review the changes to {{ editLabel }} before saving.</p>
16+
17+
{% set summaryRows = [
18+
{
19+
key: { text: "Session" },
20+
value: { text: sessionLabel }
21+
},
22+
{
23+
key: { text: "Date" },
24+
value: { text: date | formatDateLong }
25+
}
26+
] %}
27+
28+
{% if draft.editPath === 'booking-length' %}
29+
{% set summaryRows = (summaryRows.push({
30+
key: { text: "Booking length" },
31+
value: { text: draft.slotLength + " minutes" },
32+
actions: {
33+
items: [{
34+
href: changeHref,
35+
text: "Change",
36+
visuallyHiddenText: "booking length"
37+
}]
38+
}
39+
}), summaryRows) %}
40+
{% elif draft.editPath === 'services' %}
41+
{% set summaryRows = (summaryRows.push({
42+
key: { text: "Services" },
43+
value: { text: serviceNames | join(", ") },
44+
actions: {
45+
items: [{
46+
href: changeHref,
47+
text: "Change",
48+
visuallyHiddenText: "services"
49+
}]
50+
}
51+
}), summaryRows) %}
52+
{% else %}
53+
{% set blocksList %}
54+
<ul class="nhsuk-list nhsuk-u-margin-bottom-0">
55+
{% for blk in draft.timeBlocks %}
56+
<li>{{ blk.start | formatTime }} to {{ blk.end | formatTime }}</li>
57+
{% endfor %}
58+
</ul>
59+
{% endset %}
60+
{% set summaryRows = (summaryRows.push({
61+
key: { text: "Time periods" },
62+
value: { html: blocksList },
63+
actions: {
64+
items: [{
65+
href: changeHref,
66+
text: "Change",
67+
visuallyHiddenText: "session times"
68+
}]
69+
}
70+
}), summaryRows) %}
71+
{% endif %}
72+
73+
{% if affectedCount > 0 %}
74+
{% set summaryRows = (summaryRows.push({
75+
key: { text: "Bookings affected" },
76+
value: { text: affectedCount }
77+
}), summaryRows) %}
78+
{% set summaryRows = (summaryRows.push({
79+
key: { text: "What do you want to do with bookings" },
80+
value: { text: "Keep bookings" if draft.bookingsChoice === "keep" else ("Cancel " + affectedCount + " " + ("booking" if affectedCount === 1 else "bookings")) },
81+
actions: {
82+
items: [{
83+
href: bookingsHref,
84+
text: "Change",
85+
visuallyHiddenText: "what to do with bookings"
86+
}]
87+
}
88+
}), summaryRows) %}
89+
{% endif %}
90+
91+
{{ summaryList({ rows: summaryRows }) }}
92+
93+
{% if affectedCount > 0 and draft.bookingsChoice === "cancel" %}
94+
{% call warningCallout({ heading: "You are about to remove " + affectedCount + " " + ("booking" if affectedCount === 1 else "bookings") }) %}
95+
<p>This cannot be undone.</p>
96+
{% endcall %}
97+
98+
<form method="post" action="{{ formAction }}">
99+
{{ button({
100+
text: "Change session and remove " + affectedCount + " " + ("booking" if affectedCount === 1 else "bookings"),
101+
classes: "nhsuk-button--warning"
102+
}) }}
103+
</form>
104+
{% else %}
105+
<form method="post" action="{{ formAction }}">
106+
{{ button({ text: "Change session" }) }}
107+
</form>
108+
{% endif %}
109+
110+
</div>
111+
</div>
112+
{% endblock %}

app/views/sites/session-options.html

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,6 @@ <h2 class="app-summary-card__title">Services</h2>
9393
] }) }}
9494
</div>
9595
</div>
96-
97-
<form method="post" action="{{ formAction }}">
98-
{{ button({ text: "Save changes" }) }}
99-
</form>
100-
10196
</div>
10297
</div>
10398
{% endblock %}

0 commit comments

Comments
 (0)