Skip to content

Feat/survey drawer - #156

Merged
bvkay merged 3 commits into
mainfrom
feat/survey-drawer
Aug 18, 2026
Merged

Feat/survey drawer#156
bvkay merged 3 commits into
mainfrom
feat/survey-drawer

Conversation

@bvkay

@bvkay bvkay commented Aug 18, 2026

Copy link
Copy Markdown
Owner

No description provided.

bvkay added 3 commits August 18, 2026 15:33
…026-08-18)

Downloads (ruling 1) keeps the three whole-survey bundles and nothing that
competes with them. "All EDIs (select and download)" is gone: the EDI bundle
already covers the whole survey, and per-station selection belongs to the
station drawers. The select-and-download LENS itself is unchanged and still
reached from the survey card's Download button.

"View on map" (ruling 2) leaves Downloads for the drawer HEADER beside the
survey name, which is now sticky so the control does not scroll away from a
long record. It no longer scopes the rail tree: focusing a survey used to
filter every other survey off the map, which cost the reader the national
context that makes a position meaningful and left the map filtered after the
drawer shut. Option A instead: other surveys stay VISIBLE but dimmed, opacity
only, so nothing reloads when the focus lifts. The fit is padded on the right
by the drawer's measured width, because the drawer is absolutely positioned
over the map and an unpadded fit lands half the survey under the panel.

"Related surveys" (ruling 3) is removed with its scorer. The score mixed
same-org, bbox overlap and same-country into one unexplained ranking, so it
asserted a relationship the corpus does not record. Related PUBLICATIONS, a
declared and citable relation, are untouched.

The survey persistent-identifiers rollup (ruling 4, as amended) becomes a
DATA-LEVEL tile grid in the Downloads tile treatment: six fixed slots in the
citable NCI scheme of Rees et al. 2019, the same family the station Files tab
already speaks, with the Files tab's own glosses carried verbatim where the
two name the same level. The slot keys ARE the shipped `identifies` enum, so
a slot cannot drift from what the survey validator permits to publish. An
unrecorded level renders muted but VISIBLE (hollow dot, "not yet recorded")
so the deposit chain has the same shape on every survey and a gap reads as a
gap. An identifier that maps to no slot is never silently dropped: it renders
as an extra tile below the six, and the "N of 6" counter tallies only the six
fixed slots. Instruments stay as one compact footer line. The Organisation ROR
row goes; the ROR still reaches the reader on the organisation name in the
header subline.

Close behaviour (ruling 5): a click on the map BACKGROUND closes an open
drawer, while a click that lands on a station marker still opens that station.
Markers set bubblingMouseEvents:false so Leaflet's own hit-testing is the
discriminator; DOM-target discrimination cannot do this job because the map is
preferCanvas and every marker shares one canvas as the event target. An armed
draw is excluded, since mid-rectangle a click is placing a corner.

And the stale-hash fix: closeDrawer cleared only the station prefix, so a
survey opened by the survey route left its hash behind after the drawer shut.
The URL then claimed a survey was open when nothing was, reload and Back
re-opened a drawer the reader had deliberately closed, and a copied URL shared
a state the page was not in. Both prefixes now clear from one list. openSurvey
also owns its route the way openStation always has, which closes the same
defect one step along: opening survey B over survey A used to leave survey A's
hash in the address bar.

RED-proven before the fix: the stale survey hash reproduced in the interaction
driver, and ten further mutations of this change (unpadded fit, dim reverted to
filtering, dim hiding rather than dimming, dim not cleared on close, hidden
unrecorded slots, dropped extra tile, removed citation line, the map action put
back in Downloads, background click during an armed draw, and the hash list
itself) each fail an assertion.

HONESTY NOTE on what the new tests prove: Leaflet is STUBBED in the jsdom
interaction harness, so the map legs assert the ARGUMENTS the app hands the map
and the PURE decision functions. Leaflet's real hit-testing, projection and
pointer capture are exercised only in a browser.

The identifiersHtml rollup is untouched and still renders on the STATION
drawer, so the render pins for its rows now assert against that surface and
gain survey-grid pins beside them. Nothing was weakened to go green.
…mmary

Owner amendment 2 (2026-08-18), the ONE scoped exception to "station drawers
are untouched" in the survey-drawer lane.

The Station summary group carried a "Transfer function / Download" product
tile that duplicated the Files tab's Level 2 EDI row: same gated descriptor,
same bytes, same embargo wording. Two tabs then answered the same question in
two places, which is exactly the summary-vs-downloads separation the tab split
exists to draw. A summary states facts about the station; the Files tab serves
its files.

Nothing about EDI ACCESS changes. ediDescriptor and its C1b embargo posture are
untouched, and the EDI is still offered by the two surfaces that own downloads:
the sticky-header Download EDI action and the Files tab's Level 2 EDI row.
overviewDownload() is deleted along with its only call site rather than left
unreferenced, since dead render code is the trap test_no_dead_prov_feature.py
exists to catch.

RED-proven: restoring a download tile inside the Station summary fails the new
assertions (no .prod tile, no "Transfer function" tile copy, no download
affordance at all), and the leg that asserts the header Download EDI action
SURVIVES guards the removal from becoming an access regression.
…g (change 6)

Owner-approved 2026-08-18.

Leaflet.markercluster is gone: plugin, stylesheet, both vendored files and every
call site. Proximity clustering answered the wrong question. It grouped by what
was near what on screen, so one survey could fragment into several bubbles while
two surveys could merge into one, and the number on a bubble counted a screen
accident rather than anything in the corpus.

A badge names a SURVEY. It sits at the survey's centroid, and there is exactly
one per survey by construction: the router keys a Map by survey name, so a
survey cannot show two badges at any zoom or any filter state. Clicking a badge
opens that survey's drawer through the same openSurvey() the #/survey/<slug>
route uses, so a badge click and a deep link land on identical state and leave
identical URLs. Badge markers set bubblingMouseEvents:false, because change 5's
background-click handler would otherwise close the drawer the badge just opened.

Three thresholds, all named constants rather than inlined literals:

BADGE_MAX_ZOOM 7 keeps the earlier UX4-D3 ruling verbatim ("individual sites
from regional zoom down"), so this change does not quietly re-litigate a settled
call. BADGE_SPAN_PX 64 is the footprint rule expressed where it is decidable, in
SCREEN PIXELS rather than km: a km threshold means a different thing at every
zoom. 64px is two badge-widths, so below it a survey's dots are a smudge no
larger than the badge replacing them, and above it the dots start to carry shape
that a badge would destroy. In km terms that is ~140 km of extent at national
zoom and ~35 km at z6. BADGE_MIN_STATIONS 2 because a badge reading "1" hides
more than it says, and a single-station survey has a zero-span footprint that
could never expand.

AusLAMP keeps its never-collapse privilege: the national LP fabric always reads
as a grid. That rule moved from the old two-container layer split into
shouldBadgeSurvey, and the layer split is gone with the clustering it existed to
withhold.

Dot radii are now a continuous, type-aware ramp with a floor and a ceiling,
replacing the four-step ladder. The ladder rendered the LP fabric and a
broadband survey at the same size, so at national zoom the AusLAMP grid competed
with the surveys a reader was looking for; LP now starts a pixel smaller and
stays proportionally under. The floor stops a dot going sub-pixel at far-out
zoom, where an invisible dot reads as "no coverage here" - a false claim about
the corpus. The ceiling stops close zooms growing discs that hide the site
spacing, which at site zoom is the information.

Select & export EXPANDS every badge (owner item 4, decided). A selection is a
set of stations - the lasso, "select all filtered", the exports and the counts
all operate on stations - and a badge is not one. Left badged, a visitor would
drag a rectangle across three badges and select nothing, with no visible reason
why. Returning to Browse re-badges. The rejected alternative was making a badge
select its whole survey on click, which would overload one gesture with two
meanings and give no way to select part of a compact survey.

The legend row changed with the object it describes: "stations (zoom to expand)"
named a proximity cluster, so it now reads "survey (click to open; zoom to
expand)", stating both things a reader can do with a badge.

Composition with the shipped changes: badges render into their survey's pane, so
change 2's focus dim reaches them with the same single opacity write it uses for
dots; View-on-map fit and padding are untouched; the armed-draw exclusion is
untouched.

RED evidence: thirteen mutations of this change each fail an assertion - the
legend copy reverted, AusLAMP allowed to badge, the min-stations rule dropped,
the span threshold dropped, the zoom ceiling dropped, Select leaving badges up,
placement moved off the centroid, the router keyed per-station instead of per
survey, the radius floor removed, the LP ramp flattened, the markercluster tag
restored, zoomend no longer re-routing, and the badge click allowed to bubble.

TWO DEFECTS THIS CHANGE FOUND IN ITSELF, both worth recording. The mutation
battery caught a VACUOUS test: the bubbling pin matched the explanatory comment
above renderBadges rather than the option, so it passed with the option deleted;
it now strips comments before scanning. And a live browser click-through caught
a real bug the harness could not see: setSidebarMode skipped re-routing on
select->browse on the assumption that restoreSelectLens() refreshes, but that
returns early unless a lens is live, so a visitor who simply clicked Select then
Browse got no badges back. It now re-routes on every real transition, and a new
leg drives that exact no-lens path through the router's own telemetry.

What the tests prove, honestly: the badge rule, the centroid, the threshold
crossing, the conservation invariant and the radius curve all run for real on
plain objects against shipped code (tools/map_badges_test.js). The interaction
driver proves the routing decisions and the mode gate. Leaflet is stubbed in
both, so the removal, the zoomend wiring and the badge click contract are pinned
at the source, and no automated test proves a rendered badge is clickable or
lands where the centroid says. That was verified by hand in a browser against a
staged demo corpus and is the architect's to re-run.
@bvkay
bvkay merged commit d00c3cc into main Aug 18, 2026
11 checks passed
@bvkay
bvkay deleted the feat/survey-drawer branch August 18, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant