Files
site/WESP_REL/static/js/pages/stock-forecast.js
T
2026-07-17 12:57:18 +03:00

82 lines
2.5 KiB
JavaScript

/**
* Прогноз запаса на /feed_consumption.
*/
(function (global) {
const COPY = () => global.WespAnalyticsCopy || {};
function escapeHtml(value) {
return String(value ?? "")
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
}
let forecastByComponentId = {};
async function fetchForecast() {
try {
const resp = await fetch("/api/analytics/stock-forecast");
if (!resp.ok) return null;
return await resp.json();
} catch {
return null;
}
}
function renderBanner(data) {
const el = document.getElementById("stockForecastBanner");
if (!el) return;
const text = (data && data.alertBanner) || "";
if (!text) {
el.hidden = true;
el.textContent = "";
return;
}
el.hidden = false;
el.innerHTML =
`<strong>${escapeHtml(COPY().stock?.bannerTitle || "Обратите внимание:")}</strong> ` +
escapeHtml(text);
}
function applyToCards() {
document.querySelectorAll(".component-card[data-forecast-key], .component-card[data-component-id]").forEach((card) => {
const key = card.getAttribute("data-forecast-key") || card.getAttribute("data-component-id");
const fc = forecastByComponentId[key];
if (!fc) return;
const adjEl = card.querySelector("[data-stock-days-adjusted]");
const explEl = card.querySelector("[data-stock-explanation]");
const label = fc.daysLeftAdjustedLabel || fc.days_left_adjusted_label;
if (adjEl && label) {
adjEl.textContent = label;
const daysVal = fc.daysLeftAdjusted != null ? fc.daysLeftAdjusted : fc.days_left_adjusted;
adjEl.closest(".info-item")?.classList.toggle(
"info-item--warn",
daysVal != null && daysVal <= 2
);
}
if (explEl && fc.explanation) {
explEl.textContent = fc.explanation;
explEl.hidden = false;
}
});
}
async function refresh() {
const data = await fetchForecast();
forecastByComponentId = {};
(data?.items || []).forEach((item) => {
const key = item.forecast_key || item.component_id || item.name_key;
if (key) forecastByComponentId[key] = item;
});
renderBanner(data);
applyToCards();
return data;
}
function getForecast(componentId) {
return forecastByComponentId[componentId] || null;
}
global.WespStockForecast = { refresh, getForecast, applyToCards };
})(typeof window !== "undefined" ? window : globalThis);