-
Notifications
You must be signed in to change notification settings - Fork 1
/
datasetTaskList.middleware.js
180 lines (159 loc) · 4.91 KB
/
datasetTaskList.middleware.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import {
fetchDatasetInfo,
validateQueryParams,
fetchResources,
processEntitiesMiddlewares,
fetchOrgInfo,
fetchEntityIssueCounts,
fetchEntryIssueCounts,
logPageError,
addEntityCountsToResources
} from './common.middleware.js'
import { fetchOne, renderTemplate } from './middleware.builders.js'
import performanceDbApi from '../services/performanceDbApi.js'
import { statusToTagClass } from '../filters/filters.js'
import * as v from 'valibot'
import logger from '../utils/logger.js'
/**
* Fetches the resource status
*/
export const fetchResourceStatus = fetchOne({
query: ({ params }) => performanceDbApi.resourceStatusQuery(params.lpa, params.dataset),
result: 'resourceStatus'
})
/**
* Returns a status tag object with a text label and a CSS class based on the status.
*
* @param {string} status - The status to generate a tag for (e.g. "Error", "Needs fixing", etc.)
* @returns {object} - An object with a `tag` property containing the text label and CSS class.
*/
function getStatusTag (status) {
return {
tag: {
text: status,
classes: statusToTagClass(status)
}
}
}
const SPECIAL_ISSUE_TYPES = ['reference values are not unique']
/**
* Prepares the task list for the dataset task list page
*
* This function takes the request, response, and next middleware function as arguments
* and uses the parsed request parameters, entities, resources, and entry/ entity issue counts
* to generate a list of tasks based on the issues found in the dataset
*
* @param {Object} req - The request object
* @param {Object} res - The response object
* @param {Function} next - The next middleware function
* @return {undefined}
*/
export const prepareTasks = (req, res, next) => {
const { lpa, dataset } = req.parsedParams
const { entities, resources } = req
const { entryIssueCounts, entityIssueCounts } = req
const entityCount = entities.length
let issues = [...entryIssueCounts, ...entityIssueCounts]
issues = issues.filter(
issue => issue.issue_type !== '' &&
issue.issue_type !== undefined &&
issue.field !== '' &&
issue.field !== undefined
)
req.taskList = Object.values(issues).map(({ field, issue_type: type, count }) => {
// if the issue doesn't have an entity, or is one of the special case issue types then we should use the resource_row_count
let rowCount = entityCount
if (SPECIAL_ISSUE_TYPES.includes(type)) {
if (resources.length > 0) {
rowCount = resources[0].entry_count
} else {
rowCount = 0
}
}
let title
try {
title = performanceDbApi.getTaskMessage({ num_issues: count, rowCount, field, issue_type: type })
} catch (e) {
logger.warn('datasetTaskList::prepareTasks could not get task title so setting to default', { error: e, params: { num_issues: count, rowCount, field, issue_type: type } })
title = `${count} issue${count > 1 ? 's' : ''} of type ${type}`
}
return {
title: {
text: title
},
href: `/organisations/${encodeURIComponent(lpa)}/${encodeURIComponent(dataset)}/${encodeURIComponent(type)}/${encodeURIComponent(field)}`,
status: getStatusTag('Needs fixing')
}
})
next()
}
/**
* Middleware. Updates req with `templateParams`
*
* @param {*} req
* @param {*} res
* @param {*} next
* @returns { { templateParams: object }}
*/
export const prepareDatasetTaskListTemplateParams = (req, res, next) => {
const { taskList, dataset, orgInfo: organisation } = req
req.templateParams = {
taskList,
organisation,
dataset
}
next()
}
const getDatasetTaskList = renderTemplate({
templateParams: (req) => req.templateParams,
template: 'organisations/datasetTaskList.html',
handlerName: 'getDatasetTaskList'
})
/**
* Middleware. Updates req with `templateParams`
*
* @param {*} req
* @param {*} res
* @param {} next
* @returns {{ templateParams: object }}
*/
export const prepareDatasetTaskListErrorTemplateParams = (req, res, next) => {
const { orgInfo: organisation, dataset, resourceStatus: resource } = req
const daysSince200 = resource.days_since_200
const today = new Date()
const last200Date = new Date(
today.getTime() - daysSince200 * 24 * 60 * 60 * 1000
)
const last200Datetime = last200Date.toISOString().slice(0, 19) + 'Z'
req.templateParams = {
organisation,
dataset,
errorData: {
endpoint_url: resource.endpoint_url,
http_status: resource.status,
latest_log_entry_date: resource.latest_log_entry_date,
latest_200_date: last200Datetime
}
}
next()
}
const validateParams = validateQueryParams({
schema: v.object({
lpa: v.string(),
dataset: v.string()
})
})
export default [
validateParams,
fetchOrgInfo,
fetchDatasetInfo,
fetchResources,
addEntityCountsToResources,
...processEntitiesMiddlewares,
fetchEntityIssueCounts,
fetchEntryIssueCounts,
prepareTasks,
prepareDatasetTaskListTemplateParams,
getDatasetTaskList,
logPageError
]