Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PAF-11: Attachments #63

Merged
merged 1 commit into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions apps/paf/behaviours/disable-file-upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = superclass => class extends superclass {
locals(req, res) {
const locals = super.locals(req, res);
const images = req.sessionModel.get('images');
if (images && images.length >= 3) {
// disable file upload if attachment limit reached.
req.form.options.fields['other-info-file-upload'].attributes = [{attribute: 'disabled'}];
return locals;
}
req.form.options.fields['other-info-file-upload'].attributes = [];
return locals;
}
}
16 changes: 16 additions & 0 deletions apps/paf/behaviours/limit-documents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = superclass => class LimitDocs extends superclass {
validate(req, res, next) {
const images = req.sessionModel.get('images');
if (images && images.length >= 3 && req.form.values['other-info-file-uploads-add-another'] === 'yes') {
return next({
'other-info-file-uploads-add-another': new this.ValidationError(
'other-info-file-uploads-add-another',
{
type: 'tooMany'
}
)
});
} super.validate(req, res, next);
return next;
}
};
15 changes: 15 additions & 0 deletions apps/paf/behaviours/remove-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

module.exports = superclass => class extends superclass {
configure(req, res, next) {
if (req.query.delete) {
const images = req.sessionModel.get('images') || [];
const remaining = images.filter(i => i.id !== req.query.delete);
req.log('info', `Reference: ${req.sessionModel.get('reference')}, Removing image: ${req.query.delete}`);
req.sessionModel.set('images', remaining);
const path = req.baseUrl + req.path;
return res.redirect(path);
}
return super.configure(req, res, next);
}
};
41 changes: 41 additions & 0 deletions apps/paf/behaviours/save-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

const _ = require('lodash');
const Model = require('../models/file-upload');

module.exports = name => superclass => class extends superclass {
process(req) {
if (req.files && req.files[name]) {
// set image name on values for filename extension validation
// N:B validation controller gets values from
// req.form.values and not on req.files
req.form.values[name] = req.files[name].name;
req.log('info', `Reference: ${req.sessionModel.get('reference')},
Processing image: ${req.form.values[name]}`);
}
super.process.apply(this, arguments);
}

locals(req, res, next) {
if (!Object.keys(req.form.errors).length) {
req.form.values['other-info-file-upload'] = null;
}
return super.locals(req, res, next);
}

saveValues(req, res, next) {
const images = req.sessionModel.get('images') || [];
if (req.files && req.files[name]) {
req.log('info', `Reference: ${req.sessionModel.get('reference')}, Saving image: ${req.files[name].name}`);
const image = _.pick(req.files[name], ['name', 'data', 'mimetype']);
const model = new Model(image);
return model.save()
.then(() => {
req.sessionModel.set('images', [...images, model.toJSON()]);
return super.saveValues(req, res, next);
})
.catch(next);
}
return super.saveValues.apply(this, arguments);
}
};
32 changes: 21 additions & 11 deletions apps/paf/fields/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ module.exports = {
dependent: {
field: 'vehicle-type',
value: 'cars'
},
}
},
'crime-hgv-group': {
mixin: 'radio-group',
Expand All @@ -238,7 +238,7 @@ module.exports = {
dependent: {
field: 'vehicle-type',
value: 'hgvs'
},
}
},
'crime-lorry-group': {
mixin: 'radio-group',
Expand All @@ -252,7 +252,7 @@ module.exports = {
dependent: {
field: 'vehicle-type',
value: 'lorries'
},
}
},
'crime-van-group': {
mixin: 'radio-group',
Expand All @@ -268,7 +268,7 @@ module.exports = {
dependent: {
field: 'vehicle-type',
value: 'vans'
},
}
},
'boat-type': {
isPageHeading: true,
Expand Down Expand Up @@ -320,7 +320,7 @@ module.exports = {
dependent: {
field: 'boat-type',
value: 'carriers'
},
}
},
'crime-general-cargo-group': {
mixin: 'radio-group',
Expand All @@ -334,7 +334,7 @@ module.exports = {
dependent: {
field: 'boat-type',
value: 'general-cargos'
},
}
},
'crime-vessel-group': {
mixin: 'radio-group',
Expand All @@ -349,7 +349,7 @@ module.exports = {
dependent: {
field: 'boat-type',
value: 'vessels'
},
}
},
'boat-name': {
mixin: 'input-text'
Expand Down Expand Up @@ -913,7 +913,7 @@ module.exports = {
dependent: {
field: 'report-person-transport-type',
value: 'cars'
},
}
},
'report-person-transport-hgv-group': {
mixin: 'radio-group',
Expand All @@ -930,7 +930,7 @@ module.exports = {
dependent: {
field: 'report-person-transport-type',
value: 'hgv'
},
}
},
'report-person-transport-lorry-group': {
mixin: 'radio-group',
Expand All @@ -944,7 +944,7 @@ module.exports = {
dependent: {
field: 'report-person-transport-type',
value: 'lorries'
},
}
},
'report-person-transport-van-group': {
mixin: 'radio-group',
Expand All @@ -960,7 +960,7 @@ module.exports = {
dependent: {
field: 'report-person-transport-type',
value: 'vans'
},
}
},
'report-person-transport-make': {
mixin: 'input-text'
Expand Down Expand Up @@ -1167,6 +1167,16 @@ module.exports = {
value: 'yes'
}
},
'other-info-file-upload': {
mixin: 'input-file',
className: 'govuk-file-upload',
attributes: []
},
'add-other-info-file-upload': {
isPageHeading: true,
mixin: 'radio-group',
options: ['yes', 'no']
},
'about-you-first-name': {
mixin: 'input-text'
},
Expand Down
37 changes: 36 additions & 1 deletion apps/paf/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
'use strict';
const saveImage = require('./behaviours/save-file');
const removeImage = require('./behaviours/remove-file');
const CombineAndLoopFields = require('hof').components.combineAndLoopFields;
const limitDocs = require('./behaviours/limit-documents');
const disableUpload = require('./behaviours/disable-file-upload');
const SummaryPageBehaviour = require('hof').components.summary;
const transportBehaviour = require('./behaviours/transport-behaviour');
const Aggregate = require('./behaviours/aggregator');
Expand Down Expand Up @@ -356,7 +361,7 @@ module.exports = {
field: 'report-person-occupation',
value: 'yes'
}
},
}
]
},
'/report-person-occupation-type': {
Expand Down Expand Up @@ -662,6 +667,36 @@ module.exports = {
next: '/other-info-file-upload'
},
'/other-info-file-upload': {
behaviours: [saveImage('other-info-file-upload'), disableUpload],
fields: ['other-info-file-upload'],
continueOnEdit: true,
forks: [{
target: '/add-other-info-file-upload',
condition: req => {
if (req.form.values['other-info-file-upload']) {
return true
}
return false;
}
}],
next: '/about-you'
},
'/add-other-info-file-upload': {
template: 'list-add-looped-files',
behaviours: [CombineAndLoopFields({
groupName: 'other-info-file-uploads',
fieldsToGroup: [
'other-info-file-upload'
],
groupOptional: true,
removePrefix: 'other-',
combineValuesToSingleField: 'record',
returnTo: '/other-info-file-upload'
}), removeImage, limitDocs],
next: '/about-you',
locals: {
section: 'other-info-file-upload'
}
},
'/about-you': {
fields: ['how-did-you-find-out-about-the-crime'],
Expand Down
75 changes: 75 additions & 0 deletions apps/paf/models/file-upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

const url = require('url');
const Model = require('hof').model;
const uuid = require('uuid').v4;
const config = require('../../../config');

module.exports = class UploadModel extends Model {
constructor(...args) {
super(...args);
this.set('id', uuid());
}

async save() {
const result = await new Promise((resolve, reject) => {
const attributes = {
url: config.upload.hostname
};
const reqConf = url.parse(this.url(attributes));
reqConf.formData = {
document: {
value: this.get('data'),
options: {
filename: this.get('name'),
contentType: this.get('mimetype')
}
}
};
reqConf.method = 'POST';
this.request(reqConf, (err, data) => {
if (err) {
return reject(err);
}
resolve(data);
});
});
this.set({ url: result.url });
return this.unset('data');
}
Rhodine-orleans-lindsay marked this conversation as resolved.
Show resolved Hide resolved

auth() {
if (!config.keycloak.token) {
// eslint-disable-next-line no-console
console.error('keycloak token url is not defined');
return Promise.resolve({
bearer: 'abc123'
});
}
const tokenReq = {
url: config.keycloak.token,
form: {
username: config.keycloak.username,
password: config.keycloak.password,
grant_type: 'password',
client_id: config.keycloak.clientId,
client_secret: config.keycloak.secret
},
method: 'POST'
};

return new Promise((resolve, reject) => {
this._request(tokenReq, (err, response) => {
const body = JSON.parse(response.body);

if (err || body.error) {
return reject(err || new Error(`${body.error} - ${body.error_description}`));
}

resolve({
bearer: JSON.parse(response.body).access_token
});
});
});
}
};
12 changes: 11 additions & 1 deletion apps/paf/sections/summary-data-sections.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,17 @@ module.exports = {
'other-info': [
'other-info-description',
'other-info-another-crime',
'other-info-another-crime-description'
'other-info-another-crime-description',
{
step: '/add-other-info-file-upload',
field: 'images',
parse: (list, req) => {
if (!req.sessionModel.get('images') ) {
return null;
}
return list && list.map(a => a.name).join('\n————————————————\n') || 'None';
}
}
],
'about-you': [
'how-did-you-find-out-about-the-crime',
Expand Down
18 changes: 18 additions & 0 deletions apps/paf/translations/src/en/fields.json
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,21 @@
},
"legendClassName": "govuk-fieldset__legend"
},
"other-info-file-upload": {
"hint": "You can add up to 3 documents",
"label": "Attachment"
},
"other-info-file-uploads-add-another": {
"options": {
"yes": {
"label": "Yes"
},
"no": {
"label": "No"
}
},
"legendClassName": "govuk-fieldset__legend"
},
"persons": {
"label": "Additional People",
"changeLinkDescription": "Additional People"
Expand Down Expand Up @@ -1356,5 +1371,8 @@
},
"when-to-contact": {
"label": "When would you like us to contact you?"
},
"images": {
"label": "Attachments"
}
}
Loading