Skip to content

Commit 9e2a700

Browse files
Feature/vvahwr 318 (#10)
* Application reference search & cosmetic bugs
1 parent c4efb08 commit 9e2a700

File tree

11 files changed

+148
-88
lines changed

11 files changed

+148
-88
lines changed

app/frontend/src/css/application.scss

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ $govuk-assets-path: "~govuk-frontend/govuk/assets/";
153153
* pagination from: https://home-office-digital-patterns.herokuapp.com/components/pagination
154154
*/
155155
.pagination {
156+
font-family: "GDS Transport", arial, sans-serif;
156157
padding: 0;
157158
margin: 0;
158159
display: inline-block;

app/routes/applications.js

+50-28
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,41 @@ const Joi = require('joi')
66
const { setAppSearch, getAppSearch } = require('../session')
77
const keys = require('../session/keys')
88

9-
async function createModel (request) {
10-
const page = request.query.page ?? 1
9+
async function createModel (request, page) {
10+
page = page ?? request.query.page ?? 1
1111
const { limit, offset } = getPagination(page, request.query.limit)
1212
const path = request.headers.path ?? ''
1313
const searchText = getAppSearch(request, keys.appSearch.searchText)
1414
const searchType = getAppSearch(request, keys.appSearch.searchType)
1515
const apps = await getApplications(searchType, searchText, limit, offset, request.yar.id)
1616
if (apps.total > 0) {
1717
const pagingData = getPagingData(apps.total ?? 0, limit, page, path)
18-
19-
let statusClass, status
18+
let statusClass
2019
return {
2120
applications: apps.applications.map(n => {
22-
switch (n.status) {
23-
case 1:
21+
switch (n.status.status) {
22+
case 'In Progress':
2423
statusClass = 'govuk-tag--grey'
25-
status = 'In Progress'
2624
break
27-
case 2:
25+
case 'Submitted':
2826
statusClass = 'govuk-tag--blue'
29-
status = 'Submitted'
3027
break
31-
case 3:
28+
case 'Withdrawn':
3229
statusClass = 'govuk-tag--red'
33-
status = 'Withdrawn'
3430
break
35-
case 4:
31+
case 'Deleted':
3632
statusClass = 'govuk-tag--red'
37-
status = 'Deleted'
3833
break
3934
default:
4035
statusClass = 'govuk-tag--grey'
41-
status = 'Pending'
4236
}
4337
return [
4438
{ text: n.reference },
45-
{ text: n.data.organisation.name },
46-
{ text: n.data.organisation.sbi },
39+
{ text: n.data?.organisation?.name },
40+
{ text: n.data?.organisation?.sbi },
4741
{ text: new Date(n.createdAt).toLocaleDateString('en-GB') },
4842
{ text: new Date(n.createdAt).toLocaleDateString('en-GB') },
49-
{ html: `<span class="govuk-tag ${statusClass}">${status}</span>` },
43+
{ html: `<span class="govuk-tag ${statusClass}">${n.status.status}</span>` },
5044
{ html: `<a href="view-application/${n.reference}">View application</a>` }
5145
]
5246
}),
@@ -61,6 +55,36 @@ async function createModel (request) {
6155
}
6256
}
6357
}
58+
const appRefRegEx = /^vv-[\da-f]{4}-[\da-f]{4}$/i
59+
const validStatus = ['pending', 'in progress', 'deleted', 'submitted', 'withdrawn', 'completed']
60+
const sbiRegEx = /^[\0-9]{9}$/i
61+
function checkValidSearch (searchText) {
62+
let searchType
63+
searchText = (searchText ?? '').trim()
64+
switch (true) {
65+
case appRefRegEx.test(searchText):
66+
searchType = 'ref'
67+
break
68+
case validStatus.indexOf(searchText.toLowerCase()) !== -1:
69+
searchType = 'status'
70+
break
71+
case sbiRegEx.test(searchText):
72+
searchType = 'sbi'
73+
break
74+
}
75+
76+
if (!searchType && searchText.length <= 0) {
77+
searchType = 'reset'
78+
}
79+
if (searchType) {
80+
return {
81+
searchText,
82+
searchType
83+
}
84+
} else {
85+
throw new Error('Invalid search. It should be application reference or status or sbi number.')
86+
}
87+
}
6488
module.exports = [
6589
{
6690
method: 'GET',
@@ -85,19 +109,17 @@ module.exports = [
85109
query: Joi.object({
86110
page: Joi.number().greater(0).default(1),
87111
limit: Joi.number().greater(0).default(10)
88-
}),
89-
payload: Joi.object({
90-
searchText: Joi.number().min(10000000).max(999999999),
91-
searchType: Joi.string()
92-
}),
93-
failAction: async (request, h, error) => {
94-
return h.view(viewTemplate, { ...request.payload, errorMessage: { text: error.details[0].message }, error: true }).code(400).takeover()
95-
}
112+
})
96113
},
97114
handler: async (request, h) => {
98-
setAppSearch(request, keys.appSearch.searchText, request.payload.searchText ?? '')
99-
setAppSearch(request, keys.appSearch.searchType, request.payload.searchType ?? '')
100-
return h.view(viewTemplate, await createModel(request))
115+
try {
116+
const { searchText, searchType } = checkValidSearch(request.payload.searchText)
117+
setAppSearch(request, keys.appSearch.searchText, searchText ?? '')
118+
setAppSearch(request, keys.appSearch.searchType, searchType ?? '')
119+
return h.view(viewTemplate, await createModel(request, 1))
120+
} catch (err) {
121+
return h.view(viewTemplate, { ...request.payload, error: err }).code(400).takeover()
122+
}
101123
}
102124
}
103125
}

app/routes/view-application.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ const { getApplication } = require('../messaging/applications')
44

55
const getOrganisationRows = (organisation) => {
66
return [
7-
{ key: { text: 'SBI number:' }, value: { text: organisation.sbi }, actions: { items: [{ href: '#', text: 'Change' }] } },
8-
{ key: { text: 'Address:' }, value: { text: organisation.address }, actions: { items: [{ href: '#', text: 'Change' }] } },
9-
{ key: { text: 'Email address:' }, value: { text: organisation.email }, actions: { items: [{ href: '#', text: 'Change' }] } }
7+
{ key: { text: 'SBI number:' }, value: { text: organisation?.sbi }, actions: { items: [{ href: '#', text: 'Change' }] } },
8+
{ key: { text: 'Address:' }, value: { text: organisation?.address }, actions: { items: [{ href: '#', text: 'Change' }] } },
9+
{ key: { text: 'Email address:' }, value: { text: organisation?.email }, actions: { items: [{ href: '#', text: 'Change' }] } }
1010
]
1111
}
1212

@@ -21,11 +21,12 @@ module.exports = {
2121
},
2222
auth: false,
2323
handler: async (request, h) => {
24-
const application = await getApplication(request.params.reference, request.yar.id)
25-
if (!application) {
24+
const response = await getApplication(request.params.reference, request.yar.id)
25+
if (!response) {
2626
throw boom.badRequest()
2727
}
28-
return h.view('view-application', { applicationId: application.reference, organisationName: application?.data?.organisation?.name, listData: { rows: getOrganisationRows(application?.data?.organisation) } })
28+
const application = response.applications[0]
29+
return h.view('view-application', { applicationId: application.reference, status: application.status.status, organisationName: application?.data?.organisation?.name, listData: { rows: getOrganisationRows(application?.data?.organisation) } })
2930
}
3031
}
3132
}

app/views/applications.njk

+2-5
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@
2424

2525
<div class="user-search-box govuk-!-width-two-thirds">
2626
<label class="govuk-label govuk-label--s" for="user-search">
27-
Search for a user by SBI number
27+
Search for a application by SBI number or reference or status
2828
</label>
2929

3030
<form method="POST">
3131
<input type="hidden" name="crumb" value="{{crumb}}"/>
3232
<input class="govuk-input" id="searchText" name="searchText" type="text" value="{{searchText}}" aria-describedby="user-search-hint" spellcheck="false">
33-
<input type="hidden" id="searchType" name="searchType" value="sbi"/>
3433
<button class="search-button" data-module="govuk-button">
3534
Search
3635
</button>
@@ -40,9 +39,7 @@
4039

4140
{% if error %}
4241
<div class="govuk-grid-row">
43-
<div class="govuk-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1" data-module="govuk-error-summary">
44-
<h2 class="govuk-error-summary__title" id="error-summary-title">{{error}}</h2>
45-
</div>
42+
<p class="govuk-error-message">{{error}}</p>
4643
</div>
4744
{% else %}
4845
<div class="govuk-grid-row">

app/views/cookies/cookie-banner.njk

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@
1313
<div class="js-cookies-container">
1414
<input type="hidden" name="crumbBanner" id="crumbBanner" value="{{ crumb }}" autocomplete="off"/>
1515
{% set html %}
16-
<p>We use some essential cookies to make this service work.</p>
17-
<p>We’d also like to use analytics cookies so we can understand how you use the service and make improvements.</p>
16+
<p class="govuk-body">We use some essential cookies to make this service work.</p>
17+
<p class="govuk-body">We’d also like to use analytics cookies so we can understand how you use the service and make improvements.</p>
1818
{% endset %}
1919
{% set acceptHtml %}
20-
<p>You’ve accepted analytics cookies. You can
20+
<p class="govuk-body">You’ve accepted analytics cookies. You can
2121
<a class="govuk-link" href="/cookies">change your cookie settings</a>
2222
at any time.</p>
2323
{% endset %}
2424
{% set rejectHtml %}
25-
<p>You’ve rejected analytics cookies. You can
25+
<p class="govuk-body">You’ve rejected analytics cookies. You can
2626
<a class="govuk-link" href="/cookies">change your cookie settings</a>
2727
at any time.</p>
2828
{% endset %}

app/views/home.njk

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<div class="govuk-grid-row">
1616
<div class="govuk-grid-column-two-thirds">
1717
<h1 class="govuk-heading-l">{{ serviceName }}</h1>
18+
<a class="govuk-link" href="/applications" >Applicaitons</a>
1819
</div>
1920
</div>
2021
{% endblock %}

app/views/macros/pagination.njk

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@
1919
{% if page < totalPages %}
2020

2121
<li class="pagination__item">
22-
<span class="pagination__link current" aria-label="Page 1">1</span>
22+
<span class="pagination__link current" aria-label="Page {{ page }}">{{ page}}</span>
2323
</li>
2424
{% endif %}
2525
{% if page+1 < totalPages %}
2626
<li class="pagination__item">
27-
<a class="pagination__link" href="{{ url }}?page={{ page + 1 }}" aria-label="Page {{ page + 1 }}">2</a>
27+
<a class="pagination__link" href="{{ url }}?page={{ page + 1 }}" aria-label="Page {{ page + 1 }}">{{ page + 1 }}</a>
2828
</li>
2929

3030
{% endif %}
3131
{% if page+2 < totalPages %}
3232
<li class="pagination__item">
33-
<a class="pagination__link" href="{{ url }}?page={{ page + 2 }}" aria-label="Page {{ page + 3 }}">3</a>
33+
<a class="pagination__link" href="{{ url }}?page={{ page + 2 }}" aria-label="Page {{ page + 2 }}">{{ page + 2 }}</a>
3434
</li>
3535

3636
{% endif %}

app/views/view-application.njk

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,26 @@
22

33
{% block pageTitle %}Application {{ applicationId }}{% endblock %}
44

5+
{% block beforeContent %}
6+
{{ govukBreadcrumbs({
7+
items: [{
8+
text: "Applications",
9+
href: "/applications"
10+
}]
11+
})}}
12+
{% endblock %}
513
{% block content %}
614
<div class="govuk-grid-row">
715
<div class="govuk-grid-column-two-thirds">
8-
<h1 class="govuk-heading-l">Application {{ applicationId }} <span class="govuk-tag govuk-tag--green">Applied</span></h1>
16+
<h1 class="govuk-heading-l">Application {{ applicationId }} <span class="govuk-tag govuk-tag--green">{{ status }}</span></h1>
917

1018
<h2 class="govuk-heading-m">{{ organisationName }}</h2>
1119
{{ govukSummaryList({
1220
rows: listData.rows
1321
}) }}
1422

1523
{% set applicationHtml %}
16-
<h2 class="govuk-heading-l">Applied</h2>
24+
<h2 class="govuk-heading-l">{{ status }}</h2>
1725
{{ govukTable({
1826
head: [
1927
{

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ffc-ahwr-backoffice",
3-
"version": "1.1.1",
3+
"version": "1.3.0",
44
"description": "description-of-project-goes-here",
55
"homepage": "https://github.com/DEFRA/ffc-ahwr-backoffice",
66
"main": "app/index.js",

0 commit comments

Comments
 (0)