Ver código fonte

fix: nutikodu no-cache päised + joonte ühine ajavahemik

- app.py: Cache-Control no-cache (staatika + API) — väldib vana JS/HTML vahemällu jäämist
- app.js: clipToCommonRange — kõik jooned algavad/lõpevad ühises ajavahemikus
ardo 1 mês atrás
pai
commit
be683b2b27
2 arquivos alterados com 30 adições e 3 exclusões
  1. 15 0
      dev/nutikodu-web/app.py
  2. 15 3
      dev/nutikodu-web/static/app.js

+ 15 - 0
dev/nutikodu-web/app.py

@@ -46,6 +46,21 @@ MAX_RANGE_DAYS = 3660
 app = FastAPI(title="Nutikodu", version="0.2.0")
 
 
+@app.middleware("http")
+async def add_no_cache(request: Request, call_next):
+    """Staatika ja API ilma vahemäluta — muidu jääb brauserisse vana JS/HTML."""
+    response = await call_next(request)
+    path = request.url.path
+    if (
+        path == "/"
+        or path.startswith("/api/")
+        or path.endswith((".js", ".css", ".html", ".webmanifest", ".svg"))
+    ):
+        response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
+        response.headers["Pragma"] = "no-cache"
+    return response
+
+
 def ch_query(query: str, params: dict[str, str] | None = None) -> list[dict]:
     """Käivita ClickHouse'i päring ja tagasta read JSON-objektidena."""
     q = {"database": CH_DB, "query": f"{query} FORMAT JSONEachRow"}

+ 15 - 3
dev/nutikodu-web/static/app.js

@@ -28,8 +28,7 @@ function toLocalInput(date) {
   return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
 }
 
-function setStatus(ok) {
-  const el = $("#status");
+function setStatus(ok) {  const el = $("#status");
   el.classList.toggle("ok", ok === true);
   el.classList.toggle("err", ok === false);
 }
@@ -50,6 +49,19 @@ function applyPreset(days) {
   load();
 }
 
+// Kärbi kõik seeriad ühisesse ajavahemikku, et jooned algaksid ja lõpeksid koos.
+function clipToCommonRange(series) {
+  const active = series.filter((s) => Array.isArray(s.data) && s.data.length);
+  if (active.length < 2) return series;
+  const start = Math.max(...active.map((s) => s.data[0][0]));
+  const end = Math.min(...active.map((s) => s.data[s.data.length - 1][0]));
+  if (!(start < end)) return series;
+  return series.map((s) => {
+    if (!Array.isArray(s.data)) return s;
+    return { ...s, data: s.data.filter((d) => d && d[0] >= start && d[0] <= end) };
+  });
+}
+
 function buildOption(data) {
   const text = cssVar("--text");
   const muted = cssVar("--muted");
@@ -206,7 +218,7 @@ function buildOption(data) {
       { type: "inside", throttle: 50 },
       { type: "slider", height: 22, bottom: 14, borderColor: border, textStyle: { color: muted }, fillColor: cssVar("--accent-soft") },
     ],
-    series,
+    series: clipToCommonRange(series),
   };
 }