Skip to content

Commit

Permalink
Merge branch 'main' into content/datasetTaskList
Browse files Browse the repository at this point in the history
  • Loading branch information
GeorgeGoodall authored Aug 13, 2024
2 parents 18aab00 + 2d55d32 commit 0eef19f
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 176 deletions.
23 changes: 9 additions & 14 deletions src/controllers/OrganisationsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import performanceDbApi from '../services/performanceDbApi.js' // Assume you hav
import logger from '../utils/logger.js'
import { types } from '../utils/logging.js'
import { dataSubjects } from '../utils/utils.js'
import { statusToTagClass } from '../filters/filters.js'

// get a list of available datasets
const availableDatasets = Object.values(dataSubjects)
Expand All @@ -19,17 +20,10 @@ const availableDatasets = Object.values(dataSubjects)
* @returns {object} - An object with a `tag` property containing the text label and CSS class.
*/
function getStatusTag (status) {
const statusToTagClass = {
Error: 'govuk-tag--red',
'Needs fixing': 'govuk-tag--yellow',
Warning: 'govuk-tag--blue',
Issue: 'govuk-tag--blue'
}

return {
tag: {
text: status,
classes: statusToTagClass[status]
classes: statusToTagClass(status)
}
}
}
Expand Down Expand Up @@ -73,16 +67,17 @@ const organisationsController = {
if (!keys.includes(dataset)) {
datasets.push({
slug: dataset,
endpoint: null
endpoint: null,
status: 'Not submitted'
})
}
})

const totalDatasets = datasets.length
const [datasetsWithEndpoints, datasetsWithIssues, datasetsWithErrors] = datasets.reduce((accumulator, dataset) => {
if (dataset.endpoint !== null) accumulator[0]++
if (dataset.issue) accumulator[1]++
if (dataset.error) accumulator[2]++
if (dataset.endpoint) accumulator[0]++
if (dataset.status === 'Needs fixing') accumulator[1]++
if (dataset.status === 'Error') accumulator[2]++
return accumulator
}, [0, 0, 0])

Expand All @@ -100,7 +95,7 @@ const organisationsController = {

res.render('organisations/overview.html', params)
} catch (error) {
logger.error(error)
logger.warn('organisationsController.getOverview(): ' + error.message ?? error.errorMessage, { type: types.App })
next(error)
}
},
Expand Down Expand Up @@ -130,7 +125,7 @@ const organisationsController = {

res.render('organisations/find.html', { alphabetisedOrgs })
} catch (err) {
logger.warn(err)
logger.warn('organisationsController.getOrganisations(): ' + err.message ?? err.errorMessage, { type: types.App })
next(err)
}
},
Expand Down
18 changes: 18 additions & 0 deletions src/filters/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ import prettifyColumnName from './prettifyColumnName.js'
import getFullServiceName from './getFullServiceName.js'
import { makeDatasetSlugToReadableNameFilter } from './makeDatasetSlugToReadableNameFilter.js'

/** maps dataset status (as returned by performanceDbApi/getLpaOverview()) to a
* CSS class used by the govuk-tag component
*/
const statusToTagClassMapping = {
Error: 'govuk-tag--red',
'Not submitted': 'govuk-tag--red',
'Needs fixing': 'govuk-tag--yellow',
Warning: 'govuk-tag--blue',
Issue: 'govuk-tag--blue', // deprecated
Live: 'govuk-tag--green'
}

export function statusToTagClass (status) {
console.assert(status in statusToTagClassMapping, `statusToTagClass: unknown status ${status}`)
return statusToTagClassMapping[status]
}

const { govukMarkdown, govukDateTime } = xGovFilters

const addFilters = (nunjucksEnv, { datasetNameMapping }) => {
Expand All @@ -20,6 +37,7 @@ const addFilters = (nunjucksEnv, { datasetNameMapping }) => {
nunjucksEnv.addFilter('toErrorList', toErrorList)
nunjucksEnv.addFilter('prettifyColumnName', prettifyColumnName)
nunjucksEnv.addFilter('getFullServiceName', getFullServiceName)
nunjucksEnv.addFilter('statusToTagClass', statusToTagClass)
}

export default addFilters
2 changes: 1 addition & 1 deletion src/services/datasette.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
* Executes a SQL query on the Datasette instance and returns the results.
*
* @param {string} query - The SQL query to execute.
* @returns {Promise<{data: object, formattedData: object}>} - A promise that resolves to an object with the following properties:
* @returns {Promise<{data: object, formattedData: object[]}>} - A promise that resolves to an object with the following properties:
* - `data`: The raw data returned by Datasette.
* - `formattedData`: The formatted data, with columns and rows parsed into a usable format.
* @throws {Error} If the query fails or there is an error communicating with Datasette.
Expand Down
74 changes: 34 additions & 40 deletions src/services/performanceDbApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ fs.createReadStream('src/content/entityIssueMessages.csv')

/**
* @typedef {object} Dataset
* @property {'Not submitted' | 'Error' | 'Needs fixing' | 'Warning' | 'Live' } status
* @property {string} endpoint
* @property {?string} error
* @property {?string} issue
*/

/**
Expand Down Expand Up @@ -80,27 +80,32 @@ export default {
rle.resource,
rle.exception,
rle.status as http_status,
case
when (rle.status != '200') then 'Error'
when (it.severity = 'error') then 'Issue'
when (it.severity = 'warning') then 'Warning'
else 'No issues'
end as status,
case
when (rle.status is null) then 'Not Submitted'
when (rle.status != '200') then 'Error'
when (it.severity = 'error') then 'Needs fixing'
when (it.severity = 'warning') then 'Warning'
else 'Live'
end as status,
case
when (it.severity = 'info') then ''
else i.issue_type
end as issue_type,
case
when (it.severity = 'info') then ''
else it.severity
end as severity,
it.responsibility,
COUNT(
case
when it.severity != 'info' then 1
else null
end
) as issue_count
when ((cast(rle.status as integer) > 200)) then format('There was a %s error accessing the data URL', rle.status)
else null
end as error,
case
when (it.severity = 'info') then ''
else i.issue_type
end as issue_type,
case
when (it.severity = 'info') then ''
else it.severity
end as severity,
it.responsibility,
COUNT(
case
when it.severity != 'info' then 1
else null
end
) as issue_count
FROM
provision p
LEFT JOIN
Expand Down Expand Up @@ -130,24 +135,17 @@ ORDER BY
const result = await datasette.runQuery(query)

const datasets = result.formattedData.reduce((accumulator, row) => {
let error
if (row.http_status !== '200' || row.exception) {
error = row.exception ? row.exception : `endpoint returned with a status of ${row.http_status}`
}

let issue
if (row.issue_count > 0) {
issue = `There are ${row.issue_count} issues in this dataset`
}

accumulator[row.dataset] = {
endpoint: row.endpoint,
error,
issue
status: row.status
}
return accumulator
}, {})

if (result.formattedData.length === 0) {
throw new Error(`No records found for LPA=${lpa}`)
}

return {
name: result.formattedData[0].name,
organisation: result.formattedData[0].organisation,
Expand Down Expand Up @@ -206,13 +204,9 @@ ORDER BY
ORDER BY it.severity`

const result = await datasette.runQuery(sql)
return result.formattedData.map((row) => {
return {
num_issues: row.num_issues,
issue_type: row.issue_type,
resource: row.resource,
status: row.status
}
/* eslint camelcase: "off" */
return result.formattedData.map(({ num_issues, issue_type, resource, status }) => {
return { num_issues, issue_type, resource, status }
})
},

Expand Down
79 changes: 19 additions & 60 deletions src/views/organisations/overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
{
text: "Organisations",
href: "/overview/organisations"
href: "/organisations"
}
]
}) }}
Expand All @@ -40,17 +40,17 @@ <h1 class="govuk-heading-xl">
<div class="dataset-status">
<div class="dataset-status--item">
<span class="big-number">{{datasetsWithEndpoints}}/{{totalDatasets}}</span>
datasets provided
datasets submitted
</div>

<div class="dataset-status--item">
<span class="big-number">{{datasetsWithErrors}}</span>
datasets with errors
data URL with errors
</div>

<div class="dataset-status--item">
<span class="big-number">{{datasetsWithIssues}}</span>
datasets with issues
datasets need fixing
</div>
</div>
</div>
Expand All @@ -66,69 +66,34 @@ <h2 class="govuk-heading-m">Datasets</h2>
<li class="govuk-task-list__item govuk-task-list__item--with-link">
<div class="govuk-task-list__name-and-hint">
<h2 class="govuk-heading-m">
<a class="govuk-link govuk-task-list__link"
href="/organisations/{{ organisation.organisation }}/{{dataset.slug}}">
{% if dataset.endpoint %}
<a class="govuk-link govuk-task-list__link"
href="/organisations/{{ organisation.organisation }}/{{dataset.slug}}">
{{dataset.slug | datasetSlugToReadableName}}
</a>
{% else %}
{{dataset.slug | datasetSlugToReadableName}}
</a>
{% endif %}
</h2>
<div class="govuk-task-list__hint">
{% if dataset.endpoint is null %}
<p>Endpoint not provided</p>
<p>Data URL not submitted</p>
{% elif dataset.error %}
<p>{{dataset.error}}</p>
{% elif dataset.issue %}
<p>{{dataset.issue}}</p>
{% elif dataset.issue_count > 0 %}
<p>There are {{ dataset.issue_count }} issues in this dataset</p>
{% else %}
<p>Endpoint provided</p>
<p>Data URL submitted</p>
{% endif %}

<ul class="planning-data-actions">
{% if dataset.endpoint is null %}
<li class="planning-data-actions--item">
<a href="/taskLists/taskChecklist">Add endpoint</a>
</li>
{% endif %}
{% if dataset.error %}
<li class="planning-data-actions--item">
<a href="/taskLists/taskChecklist">Fix errors</a>
</li>
{% elseif dataset.issue %}
<li class="planning-data-actions--item">
<a href="/taskLists/taskChecklist">Fix issues</a>
</li>
{% endif %}
{% if dataset.endpoint %}
<li class="planning-data-actions--item">
<a href="/taskLists/taskChecklist">View data</a>
</li>
{% endif %}
</ul>

</div>
</div>

<div class="govuk-task-list__status">
{% if dataset.endpoint is null %}
{{govukTag({
text: "Not provided",
classes: "govuk-tag--grey"
})}}
{% elif dataset.error %}
{{govukTag({
text: "Error",
classes: "govuk-tag--red"
})}}
{% elif dataset.issue %}
{{govukTag({
text: "Issues",
classes: "govuk-tag--yellow"
})}}
{% else %}
{{govukTag({
text: "No issues",
classes: "govuk-tag--green"
})}}
{% endif %}
{{govukTag({
text: dataset.status,
classes: dataset.status | statusToTagClass
})}}
</div>
</li>
{% endfor %}
Expand All @@ -137,10 +102,4 @@ <h2 class="govuk-heading-m">
</div>
</div>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<p>View your <a href="/taskLists/taskChecklist">task list</a> to fix and improve your datasets</p>
</div>
</div>

{% endblock %}
Loading

0 comments on commit 0eef19f

Please sign in to comment.