diff --git a/lib/importer/package-lock.json b/lib/importer/package-lock.json index ea07d061..c79a0919 100644 --- a/lib/importer/package-lock.json +++ b/lib/importer/package-lock.json @@ -2702,16 +2702,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "9.23.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", - "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", diff --git a/lib/importer/src/config.js b/lib/importer/src/config.js index b723fa40..ff4fa9e7 100644 --- a/lib/importer/src/config.js +++ b/lib/importer/src/config.js @@ -31,6 +31,11 @@ exports.PluginConfig = class { this.uploadPath = config.uploadPath; this.uploadPathDefault = false; + // Should we auto-select a sheet when there is only one sheet? + // manual - No, always select a sheet even if there is only one. + // automatic - Yes, always use the single sheet when there is only one. + this.sheetSelection = config.sheetSelection || "automatic"; + // If the config fields are in the old format (just names) then move them to // the new structure with default values of text for the type, and not required. if (this.fields.find(Boolean)) { @@ -77,10 +82,18 @@ exports.PluginConfig = class { } }; + setSheetSelection = (mode) => { + if (!["manual", "automatic"].includes(mode)) { + throw (`'${mode}' is not a valid sheet selection mode`) + } + this.sheetSelection = mode + } + as_object = () => { return { uploadPath: this.uploadPathDefault ? TEMP_DIRECTORY_LABEL : this.uploadPath, - fields: this.fields + fields: this.fields, + sheetSelection: this.sheetSelection } } @@ -95,6 +108,7 @@ exports.PluginConfig = class { let current = fse.readJsonSync(configFilePath); current.fields = this.fields; + current.sheetSelection = this.sheetSelection fse.writeJsonSync(configFilePath, current); }; diff --git a/lib/importer/src/config.test.js b/lib/importer/src/config.test.js index 8679bfe9..75e3ee18 100644 --- a/lib/importer/src/config.test.js +++ b/lib/importer/src/config.test.js @@ -35,6 +35,9 @@ describe("Configuration tests", () => { expect(original.uploadPath).not.toBeNull() expect(updated.uploadPath).not.toBeNull() expect(c.uploadPath).not.toBeNull() + + expect(updated.sheetSelection).not.toBeNull() + expect(updated.sheetSelection).toStrictEqual("automatic") } ); @@ -132,6 +135,68 @@ describe("Configuration tests", () => { mock_files.restore(); }); + test('manual sheet selection', () => { + mock_files({ + './fields/app/config.json': '{"fields": [{"name":"A"}, {"name": "B"}, {"name": "C"}]}', + }) + + withCurrent( + "./fields", + new cfg.PluginConfig(), + (c) => { + c.setSheetSelection("manual") + c.persistConfig() + }, + (original, updated) => { + expect(updated.sheetSelection).toStrictEqual("manual") + } + ); + + mock_files.restore(); + }); + + test('default sheet selection', () => { + mock_files({ + './fields/app/config.json': '{"fields": [{"name":"A"}, {"name": "B"}, {"name": "C"}]}', + }) + + withCurrent( + "./fields", + new cfg.PluginConfig(), + (c) => { + c.persistConfig() + }, + (original, updated) => { + expect(updated.sheetSelection).toStrictEqual("automatic") + } + ); + + mock_files.restore(); + }); + + + test('invalid sheet selection', () => { + mock_files({ + './fields/app/config.json': '{"fields": [{"name":"A"}, {"name": "B"}, {"name": "C"}]}', + }) + + withCurrent( + "./fields", + new cfg.PluginConfig(), + (c) => { + expect(() => { + c.setSheetSelection("invalid") + } + ).toThrow("'invalid' is not a valid sheet selection mode") + c.persistConfig() + }, + (original, updated) => { + expect(updated.sheetSelection).toStrictEqual("automatic") + } + ); + + mock_files.restore(); + }); }) diff --git a/lib/importer/src/index.js b/lib/importer/src/index.js index 70732529..254ebfd5 100644 --- a/lib/importer/src/index.js +++ b/lib/importer/src/index.js @@ -99,7 +99,11 @@ exports.Initialise = (config, router, prototypeKit) => { prototypeKit.views.addFunction( k, - (next) => { + (next, other = null) => { + if (next && other) { + return `${v}?next=${encodeURIComponent(next)}&other=${encodeURIComponent(other)}`; + } + return `${v}?next=${encodeURIComponent(next)}`; }, {}, @@ -164,8 +168,15 @@ exports.Initialise = (config, router, prototypeKit) => { if (session.sheets.length == 1) { session.sheet = session.sheets[0]; - } + // When there is only a single sheet, and if the prototype is configured to + // automatically progress, then this will do so if the 'other' url is + // specified. + if (plugin_config.sheetSelection.toLowerCase() == "automatic" && "other" in request.query) { + const otherPage = decodeURIComponent(request.query.other) + if (otherPage) { request.query.next = request.query.other } + } + } // Ensure the session is persisted. Currently in session, eventually another way request.session.data[IMPORTER_SESSION_KEY] = session; redirectOnwards(request, response); diff --git a/lib/importer/templates/upload.html b/lib/importer/templates/upload.html index b442b36c..4947f9bd 100644 --- a/lib/importer/templates/upload.html +++ b/lib/importer/templates/upload.html @@ -12,7 +12,7 @@