Skip to content

Commit 95862eb

Browse files
List all exports
1 parent 1939336 commit 95862eb

7 files changed

Lines changed: 190 additions & 4 deletions

File tree

app/controllers/download.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,57 @@
11
import programmesData from '../datasets/programmes.js'
22
import { AcademicYear, DownloadFormat, ProgrammeType } from '../enums.js'
33
import { Download, Programme, Team } from '../models.js'
4+
import { getDateValueDifference } from '../utils/date.js'
5+
import { getResults, getPagination } from '../utils/pagination.js'
46

57
export const downloadController = {
8+
readAll(request, response, next) {
9+
response.locals.downloads = Download.findAll(request.session.data)
10+
11+
next()
12+
},
13+
614
list(request, response) {
15+
const { type } = request.query
16+
const { data } = request.session
17+
const { downloads } = response.locals
18+
19+
let results = downloads
20+
21+
// Filter by type
22+
if (type && type !== 'none') {
23+
results = results.filter((download) => download.type === type)
24+
}
25+
26+
// Sort
27+
results = results.sort((a, b) =>
28+
getDateValueDifference(b.createdAt, a.createdAt)
29+
)
30+
31+
// Results
32+
response.locals.results = getResults(results, request.query, 40)
33+
response.locals.pages = getPagination(results, request.query, 40)
34+
35+
// Clean up session data
36+
delete data.type
37+
738
response.render(`download/list`)
839
},
940

41+
filterList(request, response) {
42+
const params = new URLSearchParams()
43+
44+
// Radios and text inputs
45+
for (const key of ['type']) {
46+
const value = request.body[key]
47+
if (value) {
48+
params.append(key, String(value))
49+
}
50+
}
51+
52+
response.redirect(`/downloads?${params}`)
53+
},
54+
1055
form(request, response) {
1156
const { data } = request.session
1257

app/data.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const data = {
3333
clinics,
3434
counts: {},
3535
defaultBatches: {},
36+
downloads: {},
3637
features: {},
3738
instructions,
3839
moves,

app/enums.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ export const DownloadFormat = {
106106
SystmOne: 'XLSX for SystmOne (TPP)'
107107
}
108108

109+
/**
110+
* @readonly
111+
* @enum {string}
112+
*/
113+
export const DownloadType = {
114+
Report: 'Vaccination records'
115+
}
116+
109117
/**
110118
* @readonly
111119
* @enum {string}

app/locales/en.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,10 +717,21 @@ export const en = {
717717
label: 'Exports',
718718
title: 'Exports'
719719
},
720+
search: {
721+
label: 'Find export'
722+
},
723+
results:
724+
'{count, plural, =0 {No exports matching your search criteria were found} one {Showing <b>{from}</b> to <b>{to}</b> of <b>{count}</b> export} other {Showing <b>{from}</b> to <b>{to}</b> of <b>{count}</b> exports}}',
720725
new: {
721726
label: 'Download vaccination report',
722727
confirm: 'Download vaccination data'
723728
},
729+
createdAt: {
730+
label: 'Requested at'
731+
},
732+
createdBy: {
733+
label: 'Requested by'
734+
},
724735
startAt: {
725736
label: 'Get vaccination data from'
726737
},
@@ -735,6 +746,9 @@ export const en = {
735746
title: 'Select providers',
736747
label: 'Providers'
737748
},
749+
type: {
750+
label: 'Type'
751+
},
738752
vaccinations: {
739753
label: 'Records'
740754
}
@@ -2139,7 +2153,7 @@ export const en = {
21392153
'Use this page to upload and import child, class list and vaccination records.\n\nUpload times can vary. Refresh the page to see the latest status.'
21402154
},
21412155
search: {
2142-
label: 'Find upload'
2156+
label: 'Find import'
21432157
},
21442158
results:
21452159
'{count, plural, =0 {No imports matching your search criteria were found} one {Showing <b>{from}</b> to <b>{to}</b> of <b>{count}</b> import} other {Showing <b>{from}</b> to <b>{to}</b> of <b>{count}</b> imports}}',

app/models/download.js

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { fakerEN_GB as faker } from '@faker-js/faker'
22
import xlsx from 'json-as-xlsx'
33

4-
import { DownloadFormat } from '../enums.js'
5-
import { Programme, Team, Vaccination } from '../models.js'
4+
import { DownloadFormat, DownloadType } from '../enums.js'
5+
import { Programme, Team, Vaccination, User } from '../models.js'
66
import {
77
convertIsoDateToObject,
88
convertObjectToIsoDate,
@@ -25,6 +25,7 @@ import { formatList } from '../utils/string.js'
2525
* @property {Date} [endAt] - Date to end report
2626
* @property {object} [endAt_] - Date to end report (from `dateInput`)
2727
* @property {DownloadFormat} [format] - Downloaded file format
28+
* @property {DownloadType} [type] - Download type
2829
* @property {string} [programme_id] - Programme ID
2930
* @property {Array<string>} [team_ids] - Team IDs
3031
* @property {Array<string>} [vaccination_uuids] - Vaccination UUIDs
@@ -41,11 +42,27 @@ export class Download {
4142
this.endAt = options?.endAt && new Date(options.endAt)
4243
this.endAt_ = options?.endAt_
4344
this.format = options?.format || DownloadFormat.CSV
45+
this.type = options?.type || DownloadType.Report
4446
this.programme_id = options?.programme_id
4547
this.team_ids = options?.team_ids
4648
this.vaccination_uuids = options?.vaccination_uuids || []
4749
}
4850

51+
/**
52+
* Get user who created upload
53+
*
54+
* @returns {User} User
55+
*/
56+
get createdBy() {
57+
try {
58+
if (this.createdBy_uid) {
59+
return User.findOne(this.createdBy_uid, this.context)
60+
}
61+
} catch (error) {
62+
console.error('Upload.createdBy', error.message)
63+
}
64+
}
65+
4966
/**
5067
* Get start date for `dateInput`
5168
*
@@ -291,6 +308,15 @@ export class Download {
291308
*/
292309
get formatted() {
293310
return {
311+
createdAt: formatDate(this.createdAt, {
312+
day: 'numeric',
313+
month: 'long',
314+
year: 'numeric',
315+
hour: 'numeric',
316+
minute: '2-digit',
317+
hour12: true
318+
}),
319+
createdBy: this.createdBy?.fullName,
294320
startAt: this.startAt
295321
? formatDate(this.startAt, { dateStyle: 'long' })
296322
: 'Earliest recorded vaccination',
@@ -323,6 +349,19 @@ export class Download {
323349
return `/reports/${this.programme_id}/download/${this.id}`
324350
}
325351

352+
/**
353+
* Find all
354+
*
355+
* @param {object} context - Context
356+
* @returns {Array<Download>|undefined} Downloads
357+
* @static
358+
*/
359+
static findAll(context) {
360+
return Object.values(context.downloads).map(
361+
(upload) => new Download(upload, context)
362+
)
363+
}
364+
326365
/**
327366
* Find one
328367
*

app/routes/download.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { downloadController as download } from '../controllers/download.js'
44

55
const router = express.Router({ strict: true })
66

7-
router.get('/', download.list)
7+
router.get('/', download.readAll, download.list)
8+
router.post('/', download.filterList)
89

910
router.get('/new', download.form)
1011
router.post('/new', download.create)

app/views/download/list.njk

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,82 @@
1212
{{ interchangeNavigation({
1313
view: "downloads"
1414
}) }}
15+
16+
<div class="nhsuk-grid-row">
17+
<app-auto-submit class="app-grid-column-filters">
18+
{% call card({
19+
classes: "app-filters",
20+
feature: true,
21+
heading: __("download.search.label"),
22+
headingLevel: 3
23+
}) %}
24+
{{ radios({
25+
classes: "nhsuk-radios--small",
26+
fieldset: {
27+
legend: {
28+
classes: "nhsuk-fieldset__legend--s",
29+
text: __("download.type.label")
30+
}
31+
},
32+
items: radioFilterItems(DownloadType),
33+
decorate: "type"
34+
}) }}
35+
36+
{{ appButtonGroup({
37+
buttons: [{
38+
classes: "nhsuk-button--secondary nhsuk-button--small",
39+
text: __("search.confirm"),
40+
attributes: {
41+
formaction: params.formaction,
42+
formmethod: "post",
43+
role: "search"
44+
}
45+
}, {
46+
classes: "nhsuk-button--secondary nhsuk-button--small",
47+
text: __("search.clear"),
48+
href: "/downloads"
49+
} if data.type]
50+
}) }}
51+
{% endcall %}
52+
</app-auto-submit>
53+
54+
<div class="app-grid-column-results">
55+
{% if data.type and data.type != "none" %}
56+
{% set title = data.type | replace("records", "record exports") %}
57+
{% else %}
58+
{% set title = "All exports" %}
59+
{% endif %}
60+
61+
{{ appHeading({
62+
level: 3,
63+
size: "m",
64+
title: title,
65+
summary: __mf("download.results", {
66+
from: results.from,
67+
to: results.to,
68+
count: results.count
69+
}) | safe
70+
}) }}
71+
72+
{% for download in results.page %}
73+
{{ summaryList({
74+
card: {
75+
classes: "app-card--compact",
76+
heading: download.name,
77+
headingSize: "s",
78+
headingLevel: 4,
79+
href: download.uri,
80+
clickable: true
81+
},
82+
rows: summaryRows(download, {
83+
createdAt: {},
84+
createdBy: {},
85+
type: {}
86+
})
87+
}) }}
88+
{% endfor %}
89+
90+
{{ pagination(pages) }}
91+
</div>
92+
</div>
1593
{% endblock %}

0 commit comments

Comments
 (0)