@gov-cy/govcy-express-services
Version:
An Express-based system that dynamically renders services using @gov-cy/govcy-frontend-renderer and posts data to a submission API.
120 lines (106 loc) • 5.45 kB
JavaScript
import { getPageConfigData } from "../utils/govcyLoadConfigData.mjs";
import { populateFormData } from "../utils/govcyFormHandling.mjs";
import * as govcyResources from "../resources/govcyResources.mjs";
import * as dataLayer from "../utils/govcyDataLayer.mjs";
import { logger } from "../utils/govcyLogger.mjs";
import { evaluatePageConditions } from "../utils/govcyExpressions.mjs";
// import {flattenContext, evaluateExpressionWithFlattening, evaluatePageConditions } from "../utils/govcyExpressions.mjs";
/**
* Middleware to handle page rendering and form processing
* This middleware processes the page template, populates form data, and shows validation errors.
*/
export function govcyPageHandler() {
return (req, res, next) => {
try {
// Extract siteId and pageUrl from request
let { siteId, pageUrl } = req.params;
// get service data
let serviceCopy = req.serviceData;
// 🏠 Handle index page: If pageUrl is undefined (meaning the user accessed `/:siteId`), set a default value or handle accordingly
if (!pageUrl) {
logger.debug(`No pageUrl provided for siteId: ${siteId}`, req);
// Example: Redirect to a default page or load a homepage
pageUrl = "index"; // Change "index" to whatever makes sense for your service
}
// 🔍 Find the page by pageUrl
const page = getPageConfigData(serviceCopy, pageUrl);
// Deep copy pageTemplate to avoid modifying the original
const pageTemplateCopy = JSON.parse(JSON.stringify(page.pageTemplate));
// ----- Conditional logic comes here
// Check if the page has conditions and apply logic
const result = evaluatePageConditions(page, req.session, req.params.siteId, req);
if (result.result === false) {
return res.redirect(`/${req.params.siteId}/${result.redirect}`);
}
//if user is logged in add the user nane section in the page template
if (dataLayer.getUser(req.session)) {
pageTemplateCopy.sections.push(govcyResources.userNameSection(dataLayer.getUser(req.session).name)); // Add user name section
}
//⚙️ Process forms before rendering
pageTemplateCopy.sections.forEach(section => {
section.elements.forEach(element => {
if (element.element === "form") {
logger.debug("Processing form element:", element, req);
element.params.action = govcyResources.constructPageUrl(siteId, page.pageData.url, (req.query.route === "review" ? "review" : ""));
// Set form method to POST
element.params.method = "POST";
// ➕ Add CSRF token
element.params.elements.push(govcyResources.csrfTokenInput(req.csrfToken()));
element.params.elements.push(govcyResources.staticResources.elements["govcyFormsJs"]);
// 🔍 Find the first button with `prototypeNavigate`
const button = element.params.elements.find(subElement =>
// subElement.element === "button" && subElement.params.prototypeNavigate
subElement.element === "button"
);
// ⚙️ Modify the button if it exists
if (button) {
// Store the value of `prototypeNavigate`
//const prototypeNavigateValue = button.params.prototypeNavigate;
// Remove `prototypeNavigate`
if (button.params.prototypeNavigate) {
delete button.params.prototypeNavigate;
}
// Set `type` to "submit"
button.params.type = "submit";
}
// Handle form data
let theData = {};
//--------- Handle Validation Errors ---------
// Check if validation errors exist in the session
const validationErrors = dataLayer.getPageValidationErrors(req.session, siteId, pageUrl);
if (validationErrors ) {
// Populate form data from validation errors
theData = validationErrors?.formData || {};
} else {
// Populate form data from session
theData = dataLayer.getPageData(req.session, siteId, pageUrl);
}
//--------- End of Handle Validation Errors ---------
populateFormData(element.params.elements, theData,validationErrors);
// if there are validation errors, add an error summary
if (validationErrors?.errorSummary?.length > 0) {
element.params.elements.unshift(govcyResources.errorSummary(validationErrors.errorSummary));
}
logger.debug("Processed form element:", element, req);
}
});
});
// Attach processed data to request
req.processedPage = {
pageData: {
"site": serviceCopy.site,
"pageData": {
"title": page.pageData.title,
"layout": page.pageData.layout,
"mainLayout": page.pageData.mainLayout
}
},
pageTemplate: pageTemplateCopy
};
logger.debug("Processed page data:", req.processedPage, req);
next(); // Pass control to the next middleware or route
} catch (error) {
return next(error); // Pass error to govcyHttpErrorHandler
}
};
}