chainage panel update
This commit is contained in:
@@ -105,6 +105,8 @@ export function ChainagePanel({
|
||||
const [calibs, setCalibs] = useState<CalibrationRow[]>([]);
|
||||
const [calibsErr, setCalibsErr] = useState<string | null>(null);
|
||||
const [summary, setSummary] = useState<CalibrationSummary | null>(null);
|
||||
// true = loaded from the server (someone's earlier compute); false = just run here.
|
||||
const [summaryIsSaved, setSummaryIsSaved] = useState(false);
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
// add-point form
|
||||
@@ -144,7 +146,27 @@ export function ChainagePanel({
|
||||
useEffect(() => {
|
||||
if (open) void loadPoints();
|
||||
}, [open, loadPoints]);
|
||||
useEffect(() => setSummary(null), [projectId, group]);
|
||||
|
||||
// On open / group change, show the SAVED result of the last recompute (persisted
|
||||
// server-side) so a freshly signed-in admin sees the existing compute for LHS/RHS
|
||||
// instead of an empty panel asking to recompute.
|
||||
useEffect(() => {
|
||||
setSummary(null);
|
||||
setSummaryIsSaved(false);
|
||||
if (!open) return;
|
||||
let alive = true;
|
||||
api.chainageSummary(projectId, group)
|
||||
.then((s) => {
|
||||
if (alive && s && typeof s === "object") {
|
||||
setSummary(s);
|
||||
setSummaryIsSaved(true);
|
||||
}
|
||||
})
|
||||
.catch(() => {}); // calibrations block surfaces endpoint failures already
|
||||
return () => {
|
||||
alive = false;
|
||||
};
|
||||
}, [projectId, group, open]);
|
||||
|
||||
/** The route's videos = current group, ignored ones excluded. */
|
||||
const groupVideos = useMemo(
|
||||
@@ -180,6 +202,7 @@ export function ChainagePanel({
|
||||
setError(null);
|
||||
try {
|
||||
setSummary(await fn());
|
||||
setSummaryIsSaved(false);
|
||||
await loadPoints();
|
||||
onChanged();
|
||||
} catch (e) {
|
||||
@@ -429,6 +452,11 @@ export function ChainagePanel({
|
||||
<div key={c.road_type || "(any)"} className="dim" style={{ fontSize: 12 }}>
|
||||
<b>{c.road_type || "(ungrouped)"}</b> · route {fmtChainage(c.route_len_m)} km
|
||||
· {c.anchor_count} anchor(s) · computed by {c.computed_by} · {fmtWhen(c.computed_at)}
|
||||
{!c.has_summary && (
|
||||
<span className="err-tag" title="This calibration predates saved results — select its group and hit 'Recompute from points' once (same points ⇒ same values); after that every admin sees the full result here.">
|
||||
{" "}· result not saved yet — recompute once
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -582,9 +610,19 @@ export function ChainagePanel({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Result summary */}
|
||||
{/* Result summary — freshly run, or the saved result of the last recompute */}
|
||||
{summary && (
|
||||
<div className="chainage-block">
|
||||
{summaryIsSaved && (() => {
|
||||
const c = calibs.find((x) => x.road_type === group);
|
||||
return (
|
||||
<div className="dim" style={{ fontSize: 12, marginBottom: 4 }}>
|
||||
Saved result of the last compute
|
||||
{c ? <> — by <b>{c.computed_by}</b> · {fmtWhen(c.computed_at)}</> : null}
|
||||
{" "}(recompute only if points or videos changed)
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
<div className="block-label">
|
||||
Route <b>{(summary.route_len_m / 1000).toFixed(3)} km</b> (GPS-measured)
|
||||
· {summary.points_used} point(s) used
|
||||
|
||||
Reference in New Issue
Block a user