forked from UKSOURCE/cms.lams
Disable the automatic writing of data to JSON files in `createPageContentController`, `admissionsController`, and `policiesController` to prevent redundant file system operations during updates.
223 lines
7.0 KiB
JavaScript
223 lines
7.0 KiB
JavaScript
const PoliciesPage = require("../models/policiesPage");
|
|
const AUDIT_ACTIONS = require("../constants/auditAction");
|
|
const {
|
|
baseConfig: policiesConfig,
|
|
createPoliciesSectionEditorConfig,
|
|
} = require("../utils/contentEditors/policiesConfig");
|
|
const createPageContentController = require("./_createPageContentController");
|
|
const createRenderSingletonPageView = require("./_renderSingletonPageView");
|
|
const writeAuditLog = require("../audit/writeAuditLog");
|
|
const diffObject = require("../audit/diffObject");
|
|
const jsonHelper = require("../utils/jsonHelper");
|
|
const { ensureUniqueIds } = require("../utils/contentEditorIds");
|
|
const {
|
|
normalizePolicy,
|
|
normalizePoliciesDocument,
|
|
validateContent,
|
|
} = require("../utils/policiesBlockContent");
|
|
|
|
function formatLastUpdated(date = new Date()) {
|
|
return `Last updated: ${new Intl.DateTimeFormat("en-US", {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
}).format(date)}`;
|
|
}
|
|
|
|
function withLastUpdated(payload, { beforeData } = {}) {
|
|
const existingPolicies = Array.isArray(beforeData?.policies) ? beforeData.policies : [];
|
|
|
|
const policies = ensureUniqueIds(
|
|
Array.isArray(payload.policies) ? payload.policies : [],
|
|
(policy) => policy.id,
|
|
(policy, index) => policy.navLabel || policy.title || `policy-${index + 1}`,
|
|
"policy",
|
|
).map((policy) => {
|
|
const existingPolicy = existingPolicies.find((item) => item.id === policy.id);
|
|
const normalizedExistingPolicy = normalizePolicy(existingPolicy || policy);
|
|
|
|
return {
|
|
...policy,
|
|
content: normalizedExistingPolicy.content,
|
|
};
|
|
});
|
|
|
|
return {
|
|
...payload,
|
|
policies,
|
|
hero: {
|
|
...(payload.hero || {}),
|
|
lastUpdated: formatLastUpdated(),
|
|
},
|
|
};
|
|
}
|
|
|
|
const baseController = createPageContentController({
|
|
model: PoliciesPage,
|
|
modelName: "PoliciesPage",
|
|
auditAction: AUDIT_ACTIONS.UPDATE_POLICIES,
|
|
editorConfig: policiesConfig,
|
|
normalizeForEditor: normalizePoliciesDocument,
|
|
normalizeForApi: normalizePoliciesDocument,
|
|
preparePayload: withLastUpdated,
|
|
});
|
|
|
|
module.exports = {
|
|
...baseController,
|
|
async index(req, res) {
|
|
try {
|
|
return await createRenderSingletonPageView({
|
|
model: PoliciesPage,
|
|
editorConfig: policiesConfig,
|
|
view: "admin/policies/index",
|
|
})(req, res);
|
|
} catch (error) {
|
|
console.error("policies index error:", error);
|
|
req.flash("error_msg", "Error loading Policies Management");
|
|
return req.session.save(() => res.redirect("/admin/dashboard"));
|
|
}
|
|
},
|
|
|
|
async editSections(req, res) {
|
|
try {
|
|
const doc = await PoliciesPage.getSingle();
|
|
const data = normalizePoliciesDocument(doc.toObject());
|
|
const policy = (data.policies || []).find(
|
|
(item) => item.id === req.params.policyId,
|
|
);
|
|
|
|
if (!policy) {
|
|
req.flash("error_msg", "Policy not found");
|
|
return req.session.save(() => res.redirect("/admin/policies"));
|
|
}
|
|
|
|
const frontendUrl = process.env.FRONTEND_URL || "http://localhost:3000";
|
|
const backendUrl =
|
|
process.env.BACKEND_URL ?? `${req.protocol}://${req.get("host")}`;
|
|
const editorConfig = createPoliciesSectionEditorConfig(
|
|
policy,
|
|
data.policies || [],
|
|
);
|
|
|
|
return res.render("admin/policies/sections", {
|
|
layout: "layouts/main",
|
|
title: editorConfig.title,
|
|
subtitle: editorConfig.subtitle,
|
|
data: {
|
|
policy,
|
|
content: policy.content,
|
|
},
|
|
editorConfig,
|
|
activeTab: "sections",
|
|
frontendUrl,
|
|
backendUrl,
|
|
previewUrl: `${frontendUrl}${editorConfig.previewPath}`,
|
|
currentPath: req.path,
|
|
user: req.session.user,
|
|
});
|
|
} catch (error) {
|
|
console.error("policies section index error:", error);
|
|
req.flash("error_msg", "Error loading policy sections");
|
|
return req.session.save(() => res.redirect("/admin/policies"));
|
|
}
|
|
},
|
|
|
|
async updateSections(req, res) {
|
|
try {
|
|
const payload =
|
|
typeof req.body.pageJson === "string"
|
|
? JSON.parse(req.body.pageJson)
|
|
: req.body.pageJson || {};
|
|
const doc = await PoliciesPage.getSingle();
|
|
const beforeData = JSON.parse(JSON.stringify(doc.toObject()));
|
|
const policyIndex = (doc.policies || []).findIndex(
|
|
(item) => item.id === req.params.policyId,
|
|
);
|
|
|
|
if (policyIndex === -1) {
|
|
req.flash("error_msg", "Policy not found");
|
|
return req.session.save(() => res.redirect("/admin/policies"));
|
|
}
|
|
|
|
const policyIds = (doc.policies || [])
|
|
.map((item) => item.id)
|
|
.filter(Boolean);
|
|
const validation = validateContent(payload.content, policyIds);
|
|
|
|
if (validation.errors.length > 0) {
|
|
req.flash("error_msg", validation.errors.join(" "));
|
|
return req.session.save(() =>
|
|
res.redirect(`/admin/policies/${req.params.policyId}/section`),
|
|
);
|
|
}
|
|
|
|
const normalizedPolicies = (doc.policies || []).map((item) =>
|
|
normalizePolicy(JSON.parse(JSON.stringify(item))),
|
|
);
|
|
const currentPolicy = normalizedPolicies[policyIndex];
|
|
const updatedPolicy = {
|
|
...currentPolicy,
|
|
content: validation.content,
|
|
};
|
|
|
|
delete updatedPolicy.sections;
|
|
delete updatedPolicy.contentByLanguage;
|
|
normalizedPolicies.splice(policyIndex, 1, updatedPolicy);
|
|
const nextHero = {
|
|
...(doc.hero || {}),
|
|
lastUpdated: formatLastUpdated(),
|
|
};
|
|
await PoliciesPage.updateOne(
|
|
{ _id: doc._id },
|
|
{
|
|
$set: {
|
|
policies: normalizedPolicies,
|
|
hero: nextHero,
|
|
},
|
|
},
|
|
);
|
|
|
|
const reloadedDoc = await PoliciesPage.findById(doc._id);
|
|
const afterData = JSON.parse(JSON.stringify(reloadedDoc.toObject()));
|
|
const changes = diffObject(beforeData, afterData);
|
|
|
|
if (changes.length > 0) {
|
|
await writeAuditLog({
|
|
model: "PoliciesPage",
|
|
documentId: doc._id,
|
|
action: AUDIT_ACTIONS.UPDATE_POLICIES,
|
|
before: beforeData,
|
|
after: afterData,
|
|
changes,
|
|
req,
|
|
});
|
|
}
|
|
|
|
// const finalData = normalizePoliciesDocument(
|
|
// (await PoliciesPage.findOne()
|
|
// .select("-_id -__v -createdAt -updatedAt")
|
|
// .lean()) || {},
|
|
// );
|
|
// jsonHelper.writeJsonFile(policiesConfig.dataFile, finalData);
|
|
|
|
const successMessage = validation.warnings.length
|
|
? `Policy content updated with warnings: ${validation.warnings.join(" ")}`
|
|
: "Policy content updated successfully";
|
|
req.flash("success_msg", successMessage);
|
|
const redirectUrl =
|
|
req.body.intent === "save-back"
|
|
? "/admin/policies?tab=policies"
|
|
: `/admin/policies/${req.params.policyId}/section`;
|
|
return req.session.save(() =>
|
|
res.redirect(redirectUrl),
|
|
);
|
|
} catch (error) {
|
|
console.error("policies section update error:", error);
|
|
req.flash("error_msg", `Error updating policy sections: ${error.message}`);
|
|
return req.session.save(() =>
|
|
res.redirect(`/admin/policies/${req.params.policyId}/section`),
|
|
);
|
|
}
|
|
},
|
|
};
|