Skip to content

Commit b08b568

Browse files
authored
Provide sample files for trying out the prototype (#325)
The prototype requires users to have a file to upload, in order to try it out. To make this easier, we now provide two sample files (from the fixtures) which can be used by the user instead of having to build their own. The files (pension data and tribbles) are included in the prototypes samples folder, and an endpoint was added to the demo to facilitate the download of these files, should the user wish to see them. The prototype itself has had changes to the index page giving the user a link to download, or a button to use that sample without needing to download it. This functionality required changes in the plugin, which only exports an initialise function, using it to then set up multiple routes. The new route added is for using samples and requires a POST request with a parameter called samplefile. This parameter should be the name of a file in the samples folder of the prototype. Once submitted the user is directed to select a sheet as if they had manually uploaded a file.
1 parent 14f734b commit b08b568

File tree

5 files changed

+87
-8
lines changed

5 files changed

+87
-8
lines changed

lib/importer/src/index.js

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const session_lib = require("./session.js");
66
const sheets_lib = require("./dudk/sheets.js");
77
const tpl_functions = require("./functions.js")
88
const tpl_filters = require("./filters.js")
9-
const usage = require("./usage.js")
9+
const usage = require("./usage.js");
1010

1111
const IMPORTER_SESSION_KEY = "importer.session";
1212
const IMPORTER_ERROR_KEY = "importer.error";
@@ -21,6 +21,7 @@ const IMPORTER_ERROR_EXTRA_KEY = "importer.error.extra";
2121
const IMPORTER_ROUTE_MAP = new Map([
2222
["importerStartPath", "/importer/start"],
2323
["importerUploadPath", "/importer/upload"],
24+
["importerSamplePath", "/importer/sample"],
2425
["importerSelectSheetPath", "/importer/sheets"],
2526
["importerMapDataPath", "/importer/mapping"],
2627
["importerReviewDataPath", "/importer/review"],
@@ -161,16 +162,60 @@ exports.Initialise = (config, router, prototypeKit) => {
161162
//--------------------------------------------------------------------
162163
const uploader = getUploader(plugin_config);
163164

165+
// Actual upload endpoint
164166
router.post(
165167
IMPORTER_ROUTE_MAP.get("importerUploadPath"),
166168
uploader.single("file"),
167169
(request, response) => {
168-
let createResponse = session_lib.CreateSession(plugin_config, request);
169-
if (createResponse.error) {
170-
request.session.data[IMPORTER_ERROR_KEY] = createResponse.error;
170+
const error = uploadFile(request);
171+
if (error) {
172+
request.session.data[IMPORTER_ERROR_KEY] = error;
173+
response.redirect(request.get("Referrer"));
174+
return;
175+
}
176+
177+
redirectOnwards(request, response);
178+
},
179+
);
180+
181+
// A samples endpoint that uses a prototype-provided sample file
182+
// rather than expecting the user to upload one themselves. Samples
183+
// are restricted to XLSX files present in a 'samples' directory.
184+
router.post(
185+
IMPORTER_ROUTE_MAP.get("importerSamplePath"),
186+
(request, response) => {
187+
188+
const filename = `${request.body.samplefile}`;
189+
190+
// Copy file to upload folder if not already present there
191+
const destFile = path.join(plugin_config.uploadPath, filename)
192+
if (!fs.existsSync(destFile)) {
193+
const sourceFile = path.join(path.resolve(process.cwd(), './samples'), filename)
194+
fs.copyFileSync(sourceFile, destFile)
195+
}
196+
197+
request.file = {
198+
mimetype: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
199+
filename: filename
200+
}
201+
202+
const error = uploadFile(request);
203+
if (error) {
204+
request.session.data[IMPORTER_ERROR_KEY] = error;
171205
response.redirect(request.get("Referrer"));
172206
return;
173207
}
208+
209+
redirectOnwards(request, response);
210+
},
211+
);
212+
213+
214+
const uploadFile = (request) => {
215+
let createResponse = session_lib.CreateSession(plugin_config, request);
216+
if (createResponse.error) {
217+
return createResponse.error;
218+
}
174219
let session = createResponse.session;
175220

176221
if (session.sheets.length == 1) {
@@ -187,9 +232,8 @@ exports.Initialise = (config, router, prototypeKit) => {
187232

188233
// Ensure the session is persisted. Currently in session, eventually another way
189234
request.session.data[IMPORTER_SESSION_KEY] = session;
190-
redirectOnwards(request, response);
191-
},
192-
);
235+
};
236+
193237

194238
//--------------------------------------------------------------------
195239
// When the user has chosen a sheet to use, this route stores the sheet

prototypes/basic/app/routes.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@
44
//
55
const govukPrototypeKit = require("govuk-prototype-kit");
66
const router = govukPrototypeKit.requests.setupRouter();
7-
7+
const path = require("path");
88

99
// Below 3 lines added by the Data Upload Design Kit plugin.
1010
// If you uninstall the plugin, remove the 3 lines below.
1111
const importer = require("@register-dynamics/importer");
1212
const cfg = require("govuk-prototype-kit/lib/config");
1313
importer.Initialise(cfg.getConfig(), router, govukPrototypeKit);
14+
15+
// This custom route handles file downloads from the samples folder.
16+
// To use it, link to /download/filename.ext
17+
// where filename.ext is the name of the file in the samples folder.
18+
router.get("/download/:filename", function (req, res) {
19+
res.sendFile(req.params.filename, { root: path.join(process.cwd(), "samples") });
20+
});

prototypes/basic/app/views/index.html

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,34 @@ <h1 class="govuk-heading-xl">
5353
You can then correct the error and re-upload the file.
5454
</p>
5555

56+
<p class="govuk-body">
57+
The following sample files are provided to demonstrate the upload process.
58+
You can use these files to explore the service without needing to create your own data.
59+
</p>
60+
61+
<p class="govuk-body">
62+
<strong>Sample file 1:</strong> <a href="/download/pensions-data-sample.xlsx" class="govuk-link">pensions-data-sample.xlsx</a>
63+
- an Excel spreadsheet containing 10 records with no errors.
64+
65+
<form action="{{ importerSamplePath('/select_sheet') }}" method="post">
66+
<input type="hidden" name="samplefile" value="pensions-data-sample.xlsx">
67+
<input type="submit" class="govuk-button govuk-button--secondary" value="Use pensions-data-sample.xlsx" name="submit">
68+
</form>
69+
70+
</p>
71+
72+
<p class="govuk-body">
73+
<strong>Sample file 2:</strong> <a href="/download/tribbles.xlsx" class="govuk-link">tribbles.xlsx</a>
74+
- an Excel spreadsheet containing my favourite Star Trek aliens.
75+
76+
<form action="{{ importerSamplePath('/select_sheet') }}" method="post">
77+
<input type="hidden" name="samplefile" value="tribbles.xlsx">
78+
<input type="submit" class="govuk-button govuk-button--secondary" value="Use tribbles.xlsx" name="submit">
79+
</form>
80+
81+
</p>
82+
83+
5684
<p class="govuk-body">
5785
On completion, you will be provided with a reference number for the upload which should be quoted
5886
in any correspondence about this process.
12.7 KB
Binary file not shown.
8.81 KB
Binary file not shown.

0 commit comments

Comments
 (0)