Fix report pagination and rebuild saved plan navigation
Test and deploy / test-and-deploy (push) Successful in 1m43s
Test and deploy / test-and-deploy (push) Successful in 1m43s
This commit is contained in:
1 parent
824a964f9d
commit
5f3a015ea2
20 files changed
+1480
-809
No files matched your search
@@ -0,0 +1,71 @@
|
||||
import { computeLedger } from "./ledger.js?v=__ASSET_VERSION__";
|
||||
import { buildPlanCurve } from "./curve.js?v=__ASSET_VERSION__";
|
||||
import { parseDuration } from "./time.js?v=__ASSET_VERSION__";
|
||||
export const MILESTONES = [
|
||||
["charge", "Charge"],
|
||||
["tp", "Turning point"],
|
||||
["yellow", "Yellow / dry end"],
|
||||
["fc", "First crack"],
|
||||
["drop", "Drop"],
|
||||
];
|
||||
export function sanitizeObservations(raw) {
|
||||
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
||||
const out = {};
|
||||
for (const [key] of MILESTONES) {
|
||||
if (raw[key] === undefined) continue;
|
||||
const row = raw[key];
|
||||
if (!row || typeof row !== "object" || Array.isArray(row)) return null;
|
||||
const clean = {};
|
||||
for (const field of ["timeS", "tempC"]) {
|
||||
const v = row[field];
|
||||
if (v === undefined || v === null) {
|
||||
clean[field] = null;
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
typeof v !== "number" ||
|
||||
!Number.isFinite(v) ||
|
||||
v < 0 ||
|
||||
v > (field === "timeS" ? 7200 : 350)
|
||||
)
|
||||
return null;
|
||||
clean[field] = v;
|
||||
}
|
||||
clean.note = String(row.note ?? "").slice(0, 2000);
|
||||
out[key] = clean;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
export function buildComparison(detail) {
|
||||
const points = detail.plan
|
||||
? buildPlanCurve(detail.plan, computeLedger(detail.plan))
|
||||
: [];
|
||||
return MILESTONES.map(([key, label]) => {
|
||||
const target = points.find((p) => p.key === key);
|
||||
const uploaded =
|
||||
key === "tp"
|
||||
? detail.parsed?.turningPoint
|
||||
: detail.parsed?.milestones?.find((p) => p.key === key);
|
||||
const saved = detail.observations?.[key],
|
||||
legacy = detail.plan?.planActual?.[key];
|
||||
const timeS =
|
||||
saved?.timeS ?? uploaded?.timeS ?? parseDuration(legacy?.actualTime);
|
||||
const legacyTemp =
|
||||
legacy?.actualBt !== "" && legacy?.actualBt != null
|
||||
? Number(legacy.actualBt)
|
||||
: null;
|
||||
const tempC =
|
||||
saved?.tempC ??
|
||||
uploaded?.tempC ??
|
||||
(Number.isFinite(legacyTemp) ? legacyTemp : null);
|
||||
return {
|
||||
key,
|
||||
label,
|
||||
target,
|
||||
timeS,
|
||||
tempC,
|
||||
note: saved?.note ?? legacy?.note ?? "",
|
||||
deltaS: target && timeS != null ? timeS - target.timeS : null,
|
||||
};
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user