Refactor templates to externalize JavaScript: Moved inline scripts to separate JS files and added JSON data attributes for better maintainability and performance. Updated consumption, costs, equipment, maintenance, production, reporting, and simulations templates accordingly.

This commit is contained in:
2025-10-21 07:20:02 +02:00
parent 5a84445e90
commit 18f4ae7278
21 changed files with 1963 additions and 1986 deletions

157
static/js/production.js Normal file
View File

@@ -0,0 +1,157 @@
document.addEventListener("DOMContentLoaded", () => {
const dataElement = document.getElementById("production-data");
let data = { scenarios: [], production: {} };
if (dataElement) {
try {
const parsed = JSON.parse(dataElement.textContent || "{}");
if (parsed && typeof parsed === "object") {
data = {
scenarios: Array.isArray(parsed.scenarios) ? parsed.scenarios : [],
production:
parsed.production && typeof parsed.production === "object"
? parsed.production
: {},
};
}
} catch (error) {
console.error("Unable to parse production data", error);
}
}
const productionByScenario = data.production;
const filterSelect = document.getElementById("production-scenario-filter");
const tableWrapper = document.getElementById("production-table-wrapper");
const tableBody = document.getElementById("production-table-body");
const emptyState = document.getElementById("production-empty");
const form = document.getElementById("production-form");
const feedbackEl = document.getElementById("production-feedback");
const showFeedback = (message, type = "success") => {
if (!feedbackEl) {
return;
}
feedbackEl.textContent = message;
feedbackEl.classList.remove("hidden", "success", "error");
feedbackEl.classList.add(type);
};
const hideFeedback = () => {
if (!feedbackEl) {
return;
}
feedbackEl.classList.add("hidden");
feedbackEl.textContent = "";
};
const formatAmount = (value) =>
Number(value).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
const renderProductionRows = (scenarioId) => {
if (!tableBody || !tableWrapper || !emptyState) {
return;
}
const key = String(scenarioId);
const records = productionByScenario[key] || [];
tableBody.innerHTML = "";
if (!records.length) {
emptyState.textContent =
"No production output recorded for this scenario yet.";
emptyState.classList.remove("hidden");
tableWrapper.classList.add("hidden");
return;
}
emptyState.classList.add("hidden");
tableWrapper.classList.remove("hidden");
records.forEach((record) => {
const row = document.createElement("tr");
row.innerHTML = `
<td>${formatAmount(record.amount)}</td>
<td>${record.description || "—"}</td>
`;
tableBody.appendChild(row);
});
};
if (filterSelect) {
filterSelect.addEventListener("change", (event) => {
const value = event.target.value;
if (!value) {
if (emptyState && tableWrapper && tableBody) {
emptyState.textContent =
"Choose a scenario to review its production output.";
emptyState.classList.remove("hidden");
tableWrapper.classList.add("hidden");
tableBody.innerHTML = "";
}
return;
}
renderProductionRows(value);
});
}
const submitProduction = async (event) => {
event.preventDefault();
hideFeedback();
if (!form) {
return;
}
const formData = new FormData(form);
const scenarioId = formData.get("scenario_id");
const payload = {
scenario_id: scenarioId ? Number(scenarioId) : null,
amount: Number(formData.get("amount")),
description: formData.get("description") || null,
};
try {
const response = await fetch("/api/production/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
if (!response.ok) {
const errorDetail = await response.json().catch(() => ({}));
throw new Error(
errorDetail.detail || "Unable to add production output record."
);
}
const result = await response.json();
const mapKey = String(result.scenario_id);
if (!Array.isArray(productionByScenario[mapKey])) {
productionByScenario[mapKey] = [];
}
productionByScenario[mapKey].push(result);
form.reset();
showFeedback("Production output saved.", "success");
if (filterSelect && filterSelect.value === String(result.scenario_id)) {
renderProductionRows(filterSelect.value);
}
} catch (error) {
showFeedback(error.message || "An unexpected error occurred.", "error");
}
};
if (form) {
form.addEventListener("submit", submitProduction);
}
if (filterSelect && filterSelect.value) {
renderProductionRows(filterSelect.value);
}
});