Home/ News/ v5.2.8 — /geo + /markups + /resources
Release 2026-05-27 ~3 min read

v5.2.8 — Three first-touch fixes
across Geo, Markups and Resources.

Three visible fixes on top of v5.2.7. The Geo Hub Global / Project / Development tabs always navigate to the right scope instead of being dead links, /markups/takeoff deep links land on the right measurement (resolved by filename, flashed into view), and /resources gets inline pencil + trash icons on every row with a real edit modal and a danger-styled delete confirmation.

v5.2.8

v5.2.7 closed two layout papercuts. v5.2.8 keeps the same first-touch theme and fixes three more — one each on the three pages a new user lands on most often: Geo Hub, Markups, and Resources. None of them are big features. All three remove friction that should never have shipped in the first place.

The three changes

/geo Global / Project / Development tabs always navigate

The Geo Hub mode picker had three tabs (Global / Project / Development). Two of them quietly disabled themselves whenever the page was opened without a projectId or developmentId in scope — which is exactly how most users arrive (from the sidebar shortcut, before having opened a project). v5.2.8 changes the tabs to aria-disabled with a sensible navigate fallback: Project tab on no-scope sends the user to /projects to pick one; Development tab routes to /property-dev. The Cesium viewer also stopped silently swallowing searchPin writes that arrived before cesiumStatus === 'loaded' — those now console.warn and re-fire once the viewer is ready.

/markups → /takeoff deep links land on the measurement

Clicking a markup element on /markups built a URL like /takeoff?tab=measurements&docId=Housing+design+standards.pdf&measurementId=.... Until v5.2.8 the target page rendered blank because nothing knew how to read the query string — the takeoff page only ever booted from localStorage. Now TakeoffPage reads ?docId&?measurementId&?tab, resolves docId first by filename (with an extension-stripped fallback) and then by UUID against serverDocuments, switches to the right tab, scrolls the measurement row into view, and flashes the row with ledger-row-flash (a 1.5-second yellow pulse keyframe) so the user can see exactly which line the deep link refers to.

/resources inline edit + danger-styled delete

/resources shipped with a table that only let you create rows — existing rows were effectively read-only, despite the backend exposing PATCH /resources/{id} and DELETE all along. v5.2.8 adds a pencil icon and a trash icon to every row. The pencil opens an EditResourceModal that calls the existing PATCH endpoint; the trash opens a danger-variant ConfirmDialog before calling DELETE. A data-row-action guard on the icon cells stops the row-click handler from also firing on the same click, which would have re-opened the read drawer behind the modal. The empty-state copy got rewritten from a generic “No resources” to a hint that points at the import-from-Excel path most users start with.

Why this matters

All three of these are first-impression bugs — users hit them in the first session, before they have a mental model of the app. None of them are data-loss bugs; all three are credibility bugs. A tab that does nothing when you click it, a deep link that opens a blank page, a row you can’t edit despite the API supporting it — these read as “this product is half-finished” even when the underlying feature is fully built. The cumulative cost is much higher than the line counts suggest.

The Cesium searchPin race condition deserves a footnote. Cesium boots asynchronously; the viewer DOM exists long before the scene is ready to accept entity additions. Several call sites had been writing pin coordinates into the viewer state machine in useEffect bodies that fired before cesiumStatus flipped to loaded. Those writes silently disappeared. v5.2.8 keeps the writes but adds cesiumStatus to the effect dependency list and a console.warn for diagnosis. The pin now lands as soon as the scene is ready.

Upgrade

pip install --upgrade openconstructionerp

No Alembic migration in this release — head stays at v3144. Frontend ships the new EditResourceModal, the takeoff query-string parser, the Geo tab navigate-fallback, and one keyframe rule (@keyframes ledgerRowFlash) in index.css. CI shipped with a wheel-build fix on the side: the publish workflow was double-vendoring frontend/dist into the wheel (once via cp -r, once via the force-include map in pyproject.toml), and PyPI’s strict mode now rejects archives with duplicate filenames in local headers — that path is fixed so future tags publish themselves.

Try v5.2.8 today.

Live demo in your browser, or self-host in five minutes. AGPL-3.0, no signup required.