diff --git a/config.js b/config.js index 056f6c210..07d9c5887 100644 --- a/config.js +++ b/config.js @@ -283,16 +283,9 @@ const config = { { title: 'Your details', data: ['your-details'] } ], canRemoveStatic: [ - '/accessibility-findings', - '/prototype-url', - '/figma-link', - '/component-code-details', - '/add-external-audit', - '/add-internal-audit', - '/add-assistive-tech' + ], canRemoveMultiples: [ - // '/component-image', '/prototype-url', '/figma-link', '/component-code-details' @@ -305,4 +298,5 @@ const config = { } } + module.exports = config diff --git a/docs/stylesheets/components/_prose.scss b/docs/stylesheets/components/_prose.scss index 0c47dcfae..e2d8c6e76 100644 --- a/docs/stylesheets/components/_prose.scss +++ b/docs/stylesheets/components/_prose.scss @@ -52,11 +52,11 @@ @extend %govuk-list; } - ol { + ol:not([class]) { @extend %govuk-list--number; } - ul { + ul:not([class]) { @extend %govuk-list--bullet; } diff --git a/helpers/check-your-answers.js b/helpers/check-your-answers.js index 1f5378173..42e0a5a81 100644 --- a/helpers/check-your-answers.js +++ b/helpers/check-your-answers.js @@ -54,13 +54,13 @@ const answersFromSession = (data, session, canRemove) => { const answers = [] const defaultConfig = { removableFields: canRemove } data.forEach((form) => { - console.log(form) + // console.log(form) if (typeof form === 'object') { console.log('form is an object') for (const [formName, formConfig] of Object.entries(form)) { - console.log(formConfig) + // console.log(formConfig) const config = Object.assign({}, defaultConfig, formConfig) - console.log(config) + // console.log(config) answers.push(...extractFieldData(formName, session, config)) } } else { @@ -123,7 +123,7 @@ const extractFieldData = (field, session, options = {}) => { includeFields: [] } const opts = Object.assign({}, defaults, options) - console.log(opts) + // console.log(opts) const fieldName = field const fieldPath = `/${field}` console.log(`extracting field data for: ${fieldName}`) @@ -135,8 +135,8 @@ const extractFieldData = (field, session, options = {}) => { for (const [key, value] of Object.entries(session)) { if (typeof value === 'object' && !Array.isArray(value)) { Object.keys(value).forEach(function (field) { - console.log(field) - console.log(opts.includeFields) + // console.log(field) + // console.log(opts.includeFields) if (opts.includeFields.includes(field)) { console.log('field should be included') parsedSession[key] = {} @@ -207,7 +207,7 @@ const extractFieldData = (field, session, options = {}) => { if (subKey === 'shareYourDetails') { displayValue.value.html = shareYourDetailsValueReplacement(subValue) - } else if(subKey === 'componentCodeLanguage' || subKey === 'componentCodeLanguageOther') { + } else if(subKey === 'componentCode') { displayValue.value.text = 'Code provided' } else if ( subValue && @@ -221,7 +221,7 @@ const extractFieldData = (field, session, options = {}) => { ) } - console.log(`display value: ${displayValue.value.text}`) + // console.log(`display value: ${displayValue.value.text}`) if (opts.removableFields.includes(key) && !removeAdded) { removeAdded = true @@ -238,9 +238,9 @@ const extractFieldData = (field, session, options = {}) => { visuallyHiddenText: `${humanReadableLabel(fieldName)} - ${humanReadableLabel(subKey, fieldName)}` }) - console.log( - `display key: ${formPages[fieldName]?.fields[subKey]?.label}` - ) + // console.log( + // `display key: ${formPages[fieldName]?.fields[subKey]?.label}` + // ) return { key: { text: humanReadableLabel(subKey, fieldName) }, diff --git a/helpers/next-page.js b/helpers/next-page.js index ba3bbc545..566a55395 100644 --- a/helpers/next-page.js +++ b/helpers/next-page.js @@ -1,5 +1,10 @@ const { COMPONENT_FORM_PAGES } = require('../config') +/** + * @param {object} conditions - the conditions for the page being checked + * @param {object} session - the current session data + * @returns {boolean} + */ const checkConditions = (conditions, session) => { return Object.entries(conditions).every(([key, value]) => { if (typeof value === 'object') { @@ -9,33 +14,65 @@ const checkConditions = (conditions, session) => { }) } -const nextPage = (url, session, body, subpage) => { +const getCurrentPageUrl = (url) => { + return url.split('/')[1] // ensure we get the page not the forward slash or any subpage detail +} + +const getCurrentPageIndex = (pageUrl) => { const pages = Object.keys(COMPONENT_FORM_PAGES) - const currentPage = url.split('/')[1] // ensure we get the page not the forward slash or any subpage detail - const currentPageIndex = pages.findIndex((page) => currentPage.endsWith(page)) + return pages.findIndex((page) => pageUrl.endsWith(page)) +} +/** + * @param {string} url - the full url of the page + * @param {object} session - the current session + * @param {string} body - the submitted data + * @param {int} subpage + * @returns {(string|null)} + */ +const getNextPage = (url, session, pages, subpage, amending) => { + console.log(pages) + const currentPageUrl = url.split('/')[1] // ensure we get the page not the forward slash or any subpage detail + const currentPageIndex = pages.findIndex((page) => currentPageUrl.endsWith(page)) if (subpage) { + console.log('there is a subpage') // Return same page but with the next subpage - return `${currentPage}/${subpage}` + return `${currentPageUrl}/${subpage}` } - // Combine session and posted data - const pageData = {} - if (body) { - pageData[url] = body + if(!amending && !(currentPageIndex+1 > pages.length)){ + console.log('not making amendments') + return pages[currentPageIndex + 1] } - const data = { ...session, ...pageData } + // check all pages in getCurrentFormPages have answers for (let i = currentPageIndex + 1; i < pages.length; i++) { - const page = pages[i] - const conditions = COMPONENT_FORM_PAGES[page].conditions || {} - const shouldShowPage = checkConditions(conditions, data) - if (shouldShowPage) { - return page + const nextPage = pages[i] + if(!session[`/${nextPage}`]) { + return nextPage } } return null } -module.exports = nextPage +const getCurrentFormPages = (url,session) => { + const pages = [] + for(const [page, config] of Object.entries(COMPONENT_FORM_PAGES)) { + if(config?.conditions){ + if(checkConditions(config.conditions, session)) { + pages.push(page) + } + } else { + pages.push(page) + } + } + return pages +} + +module.exports = { + getCurrentPageIndex, + getCurrentPageUrl, + getCurrentFormPages, + getNextPage +} diff --git a/middleware/component-session.js b/middleware/component-session.js index 6437a284c..fb8b58c8d 100644 --- a/middleware/component-session.js +++ b/middleware/component-session.js @@ -9,7 +9,7 @@ const { } = require('../config') const ApplicationError = require('../helpers/application-error') const extractBody = require('../helpers/extract-body') -const nextPage = require('../helpers/next-page') +const { getNextPage, getCurrentFormPages } = require('../helpers/next-page') const previousPage = require('../helpers/previous-page') const redis = require('../helpers/redis-client') const { humanReadableLabel } = require('../helpers/text-helper') @@ -45,23 +45,82 @@ const transformErrorsToErrorList = (errors) => { })) } +const setCurrentFormPages = (req, res, next) => { + const { url, session } = req + req.formPages = getCurrentFormPages(url, session) + next() +} + const setNextPage = (req, res, next) => { + console.log('setting nextPage') + const amendingAnswers = req?.session?.checkYourAnswers const addAnother = req?.body?.addAnother !== undefined - if (req?.session?.checkYourAnswers && !addAnother) { + let subpage = null + + if (addAnother) { + subpage = req?.params?.subpage + ? Number.parseInt(req?.params?.subpage) + 1 + : 1 + } + + const { url, session, formPages } = req + const nextPage = getNextPage( + url, + session, + formPages, + subpage, + amendingAnswers + ) + + console.log(nextPage) + + // if (skippedPages.length) { + // clearSkippedPageData(skippedPages, session) + // } + + // const dependentAnswersRequired = !req?.session[`/${nextPage}`] + // if (dependentAnswersRequired) { + // console.log('you need to answer some more quesions') + // } + + if (!nextPage && amendingAnswers && !addAnother) { req.nextPage = 'check-your-answers' if (req.method === 'POST') { delete req.session.checkYourAnswers } } else { - let subpage = null - if (addAnother) { - subpage = req?.params?.subpage - ? Number.parseInt(req?.params?.subpage) + 1 - : 1 + req.nextPage = nextPage + } + next() +} + +/** + * @param {string[]} pages - array of pages to clear data for + * @param {object} session - array of pages to clear data for + */ +const clearSkippedPageData = (req, res, next) => { + console.log('clearing data for skipped pages') + const requiredPages = req.formPages.map((page) => { + return page.startsWith('/') ? page : `/${page}` + }) + + console.log(requiredPages) + // Delete page and subpage data + for (const sessionPage of Object.keys(req.session)) { + if ( + !['started', 'cookie', 'csrfToken', 'checkYourAnswers'].includes(sessionPage) + ) { + console.log(sessionPage) + const parentPage = `/${sessionPage.split('/')[1]}` + console.log(`checking${parentPage}`) + if (!requiredPages.includes(parentPage)) { + console.log(`clearing data for ${sessionPage}`) + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete req.session[sessionPage] + } } - const { url, session, body } = req - req.nextPage = nextPage(url, session, body, subpage) } + next() } @@ -82,7 +141,6 @@ const errorTemplateVariables = ( backLink: req?.backLink || false, addAnother: req?.params?.subpage || 1, showAddAnother: req?.showAddAnother || 'addAnother' in (req.body || {}), - skipQuestion: req?.skipQuestion || false, csrfToken: req?.session?.csrfToken } } @@ -236,13 +294,6 @@ const getRawSessionText = (req, res, next) => { next() } -// Check if can skip question and set value to page to skip to -const canSkipQuestion = (req, res, next) => { - const skipPage = req?.nextPage - req.skipQuestion = skipPage || false - next() -} - // Determine if can add another copy of the form const canAddAnother = (req, res, next) => { const addAnotherCount = req?.params?.subpage @@ -335,11 +386,11 @@ const saveFileToRedis = async (req, res, next) => { module.exports = { setNextPage, + setCurrentFormPages, validateFormData, saveSession, getFormDataFromSession, getRawSessionText, - canSkipQuestion, canAddAnother, getBackLink, getFormSummaryListForRemove, @@ -347,5 +398,6 @@ module.exports = { sessionStarted, validateFormDataFileUpload, validateComponentImagePage, - saveFileToRedis + saveFileToRedis, + clearSkippedPageData } diff --git a/routes/add-component.js b/routes/add-component.js index 0d44937b6..6005e67dc 100644 --- a/routes/add-component.js +++ b/routes/add-component.js @@ -16,14 +16,15 @@ const { saveSession, getFormDataFromSession, getRawSessionText, - canSkipQuestion, canAddAnother, getBackLink, getFormSummaryListForRemove, removeFromSession, sessionStarted, validateFormDataFileUpload, - saveFileToRedis + saveFileToRedis, + setCurrentFormPages, + clearSkippedPageData } = require('../middleware/component-session') const { generateMarkdown } = require('../middleware/generate-documentation') const { pushToGitHub, createPullRequest } = require('../middleware/github-api') @@ -82,6 +83,7 @@ router.all('*', setCsrfToken) router.get('*', (req, res, next) => { if (req?.session) { if (req?.url.endsWith(checkYourAnswersPath)) { + console.log('visited checkYourAnswersPath') // Indicate that we've been on the check your answers page req.session.checkYourAnswers = true } @@ -201,11 +203,10 @@ router.get( ['/:page', '/:page/:subpage'], validatePageParams, getFormDataFromSession, - setNextPage, canAddAnother, - canSkipQuestion, getBackLink, (req, res) => { + console.log(`CYA: ${req?.session?.checkYourAnswers}`) res.render(`${req.params.page}`, { page: COMPONENT_FORM_PAGES[req.params.page], submitUrl: req.originalUrl, @@ -213,7 +214,6 @@ router.get( formData: req?.formData, addAnother: req?.addAnother, showAddAnother: req?.showAddAnother, - skipQuestion: req?.skipQuestion || false, backLink: req?.backLink || false, csrfToken: req?.session?.csrfToken, changeUrl: `${ADD_NEW_COMPONENT_ROUTE}/change/${req.params.page}${req.params.subpage ? `/${req.params.subpage}` : ''}` @@ -232,7 +232,7 @@ router.post( req.session, submissionRef ) - console.log(submissionFiles) + // console.log(submissionFiles) const { filename: markdownFilename, content: markdownContent } = generateMarkdown(req.session, submissionFiles) const markdown = {} @@ -274,7 +274,6 @@ router.post( saveFileToRedis, canAddAnother, validateFormDataFileUpload, - setNextPage, getBackLink, validateFormData, (req, res, next) => { @@ -289,9 +288,11 @@ router.post( next() } }, + setCurrentFormPages, + setNextPage, (req, res, next) => { if (req.file) { - console.log(req.file) + // console.log(req.file) // return to same page after upload res.redirect(`${ADD_NEW_COMPONENT_ROUTE}${req.url}`) } @@ -311,11 +312,12 @@ router.post( xss(), verifyCsrf, validatePageParams, - setNextPage, - canSkipQuestion, getBackLink, validateFormData, saveSession, + setCurrentFormPages, + setNextPage, + clearSkippedPageData, (req, res, next) => { if (req?.nextPage) { res.redirect(`${ADD_NEW_COMPONENT_ROUTE}/${req.nextPage}`)