Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
dd8fc70
feat: add column mapping functionality to C&P
gibahjoe May 27, 2026
e3c54f1
fixed nitpix
gibahjoe May 27, 2026
6573aa5
fixed issue with missing column
gibahjoe May 28, 2026
9aadc91
Merge branch 'move-to-task-pipeline' into 1181-bring-column-mapping-i…
gibahjoe May 28, 2026
d57d7bc
feat: enhance column mapping functionality and improve dataset handling
gibahjoe May 29, 2026
b316398
fix: update dataset error handling and improve test descriptions
gibahjoe May 29, 2026
849d42e
clean up
gibahjoe May 29, 2026
1b45846
fix: prevent showing column mapping for blocking external errors
gibahjoe Jun 1, 2026
5736de2
test: add cases for handling missing-field and internal issues in col…
gibahjoe Jun 1, 2026
45a953e
feat: add manageServiceUrl to configuration files and implement inter…
gibahjoe Jun 2, 2026
bc98296
refactor notes to use
gibahjoe Jun 2, 2026
405c609
refactor: simplify internal note creation for Jira issues
gibahjoe Jun 2, 2026
7092401
fix: await asynchronous calls for attaching files and adding internal…
gibahjoe Jun 2, 2026
f5f0ccf
test: mock attachFileToIssue in createJiraServiceRequest for improved…
gibahjoe Jun 2, 2026
5cb6aca
fix: enhance internal note message with alternative link instructions…
gibahjoe Jun 2, 2026
0f4cf80
chore: implement local fallback for Jira configuration in CheckAnswer…
gibahjoe Jun 2, 2026
80d3f64
fix: update column mapping to ensure proper text representation in se…
gibahjoe Jun 2, 2026
373b013
Merge branch 'main' into 1181-bring-column-mapping-into-cp
Ben-Hodgkiss Jun 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,4 @@ features:
nonAuthPages:
# This feature enables pages to show non-authoritative datasets
# If off, it will still check for local-plan datasets.
enabled: true
enabled: true
1 change: 1 addition & 0 deletions config/development.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ aws: {
region: eu-west-2,
bucket: 'development-pub-async-request-files',
}
manageServiceUrl: 'https://manage.development.planning.data.gov.uk'
datasetteUrl: https://datasette.development.planning.data.gov.uk
downloadUrl: 'https://download.development.planning.data.gov.uk'
redis: {
Expand Down
1 change: 1 addition & 0 deletions config/local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ aws: {
endpoint: 'http://localhost:4566',
s3ForcePathStyle: true,
}
manageServiceUrl: 'http://localhost:5000'
organisationTypes:
- local-authority
- national-park-authority
Expand Down
1 change: 1 addition & 0 deletions config/production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ aws: {
region: eu-west-2,
bucket: 'production-pub-async-request-files',
}
manageServiceUrl: 'https://manage.planning.data.gov.uk'
redis: {
secure: true,
host: 'production-pub-async-redis-eihmmv.serverless.euw2.cache.amazonaws.com',
Expand Down
1 change: 1 addition & 0 deletions config/staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ aws: {
region: eu-west-2,
bucket: 'staging-pub-async-request-files',
}
manageServiceUrl: 'https://manage.staging.planning.data.gov.uk/'
redis: {
secure: true,
host: 'staging-pub-async-redis-kh1elu.serverless.euw2.cache.amazonaws.com',
Expand Down
33 changes: 33 additions & 0 deletions src/assets/scss/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,39 @@ code * {
border-left: govuk-spacing(1) solid $govuk-error-colour;
}

.column-mapping__row--error {
padding-left: 0;

.govuk-table__cell:first-child {
border-left: govuk-spacing(1) solid $govuk-error-colour;
}
}

.column-mapping-table {
th,
td {
padding-top: govuk-spacing(2);
padding-bottom: govuk-spacing(2);
}
}

.column-mapping-panel {
background-color: govuk-colour("light-grey");
padding: 15px 20px;
}

.column-mapping__unmap-select {
background-color: govuk-colour("green");
color: govuk-colour("white");
font-weight: bold;
font-size: 0.875rem;
padding: 2px 8px;
border: none;
border-radius: 0;
cursor: pointer;
appearance: auto;
}

.app-content__markdown img {
max-width: 100%;
}
Expand Down
41 changes: 38 additions & 3 deletions src/controllers/CheckAnswersController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PageController from './pageController.js'
import config from '../../config/index.js'
import { attachFileToIssue, createCustomerRequest } from '../services/jiraService.js'
import { addInternalNoteToIssue, attachFileToIssue, createCustomerRequest } from '../services/jiraService.js'
import logger from '../utils/logger.js'
import { types } from '../utils/logging.js'
import { stringify } from 'csv-stringify/sync'
Expand Down Expand Up @@ -41,6 +41,12 @@ class CheckAnswersController extends PageController {
async post (req, res, next) {
try {
const issue = await this.createJiraServiceRequest(req, res, next)
if (issue?.localJiraFallback) {
return res.json({
message: issue.message,
manageServiceLink: issue.manageServiceLink
})
}
if (issue) {
req.sessionModel.set('reference', issue.issueKey)
req.sessionModel.set('errors', [])
Expand Down Expand Up @@ -80,6 +86,18 @@ class CheckAnswersController extends PageController {
const checkTool = requestId
? `${config.url}check/results/${requestId}/${config.jira.requestTypeId}`
: 'Check tool link unavailable'
const manageServiceLink = buildManageServiceLink(requestId, data)

// Theres no point in attempting to create a Jira issue if we're going to fail, so we check
// first and return early with a message about using the Manage Service for local development
// if Jira isn't configured
if (config.environment === 'local' && !isJiraConfigured()) {
return {
localJiraFallback: true,
message: 'Jira is not configured for local development. Use this Manage Service link to add the data.',
manageServiceLink
}
}

const isNonProd = ['local', 'development', 'staging'].includes(config.environment)
const summary = `${isNonProd ? '[TEST] ' : ''}Dataset URL request: ${data.organisationName} for ${data.dataset}`
Expand Down Expand Up @@ -112,14 +130,22 @@ class CheckAnswersController extends PageController {
return null
}

this.attachFileToIssue(requestId, data, description, response).catch((error) => {
logger.error('CheckAnswersController.attachFileToIssue(): Failed to attach CSV to Jira issue', {
const internalNote = `This request is ready to be added in the Manage Service.\n\n[Open this request in Manage Service|${manageServiceLink}]\n\nIf the link does not open, copy and paste this URL in your browser:\n${manageServiceLink}`
await addInternalNoteToIssue(response.data.issueKey, internalNote).catch((error) => {
logger.error('CheckAnswersController.addInternalNoteToIssue(): Failed to add internal note to Jira issue', {
errorMessage: error.message,
errorStack: error,
type: types.External
})
})

await this.attachFileToIssue(requestId, data, description, response).catch((error) => {
logger.error('CheckAnswersController.attachFileToIssue(): Failed to attach CSV to Jira issue', {
errorMessage: error.message,
errorStack: error,
type: types.External
})
})
return response.data
}

Expand Down Expand Up @@ -188,4 +214,13 @@ class CheckAnswersController extends PageController {
}
}

function buildManageServiceLink (requestId, data) {
const urlSearchParams = new URLSearchParams({ requestId, documentationUrl: data.documentationUrl })
return `${config.manageServiceUrl}/datamanager${urlSearchParams.toString() ? `?${urlSearchParams.toString()}` : ''}`
}

function isJiraConfigured () {
return Boolean(process.env.JIRA_URL && process.env.JIRA_API_KEY && process.env.JIRA_SERVICE_DESK_ID)
}

export default CheckAnswersController
Loading
Loading