# ATOMA dashboard: Fleet map and Site details **Status: built and tested on a local Superset (P2, 24 Oct 2026); merged into one dashboard with the fleet-map view on 28 Oct 2026 (§9); not imported live.** - `build_bundle.py` generates the dashboard, every dataset and every chart from this specification, as one Superset import bundle; `import_bundle.py` imports it (§6). - The local tests changed parts of this design. Each change is marked *(P2)* and §8 lists them. - The merge of 28 Oct (owner's decisions PD-5 and PD-6, `Petrolist/.context/design-decisions.md`) replaced the Sites Map dashboard by a Fleet tab holding the fleet-map view of petrolyst-platform. Changed parts are marked *(28 Oct)*; §9 lists the results. - Nothing is imported into the live Superset without the owner's go-ahead (phase P3). **Datasets.** The `public.v_*` views of `stacks/fuel-monitoring/fuel-db/migrations/0003_bi_views.sql`, read through Trino as `fuel.public`. **Design and rationale** live in the fuel-monitoring corpus, in `.context/plans/2026-10-24-fuel-db-baseline-dashboard.md`: - its §6 is this specification; - the site-specific facts left out here (positions, distances, pilot sites) are there too; - Q-numbers refer to its §7, and phases P0–P5 to its §8. One dashboard (two until 28 Oct) replaces the earlier tab-per-site design; nothing in it is specific to a site. ## 1. Capabilities of the installed Superset 6.1.0 Source: read-only inspection of `config.py`, `superset_config.py` and the frontend bundle on 24 Oct 2026. The former *(local test)* items were tested in P2 (§8); rows marked *(P2)* changed as a result. | Requirement | What 6.1.0 provides | Choice | |---|---|---| | Map chart | `deck_scatter` (deck.gl Scatterplot): a modern plugin with the InteractiveChart behaviour. Also: deck_multi, deck_screengrid / hex / grid, country_map, world_map, cartodiagram, legacy `mapbox` | **deck.gl Scatterplot** | | Basemap | `DECKGL_BASE_MAP` unset → OSM raster (`tile.openstreetmap.org`), OSM Swiss topo, Mapbox styles. `MAPBOX_API_KEY` is empty, so the Mapbox styles fail. CSP `connect-src` already allows the OSM host; Traefik sets no CSP | set `DECKGL_BASE_MAP` to **OSM only**; "© OpenStreetMap contributors" in a Markdown under the map | | OSM terms | no key, no cost; tile usage policy: light use, attribution, no bulk download, a valid Referer (ours sends the origin) | fine for an internal user base; viewers' browsers reveal the viewed area (tile coordinates) and their IP to OSMF, not our data. Self-hosted tiles later if needed | | Tooltip | "Tooltip contents" (drag columns) plus "Customize tooltips template" (Handlebars). `js_tooltip` exists but `ENABLE_JAVASCRIPT_CONTROLS` is False. The contents show column names, not labels, and leave out the colour column | **contents only** *(P2)*: short tooltip-only calculated columns (`code`, `name`, `l_per_h`, `method`, `status`, `validity`, `latest_record`); no template, no JavaScript | | Marker colour | "Categorical color" by a dimension, from the colour scheme; a fixed colour per label through the dashboard's `label_colors` (confirmed in P2) | colour by `baseline_status_label` | | Marker size | fixed radius, with minimum = maximum pixel radius. No outline: the layer is drawn with `stroked: false` | uniform, no outline *(P2)* | | Text cards | The Handlebars chart compiles its template with `eval`; Superset's own CSP (`script-src 'self' 'strict-dynamic'` + nonce) blocks that, so the chart shows a CSP error instead *(P2)* | **no Handlebars**: one-row tables. The CSP stays as it is | | Chart descriptions | "Show description" (`expanded_slices`) never renders in 6.1: the dashboard loads `description_markeddown`, the chart holder reads `description_markdown` *(P2)* | descriptions stay on the charts; the visible reading notes are a Markdown block at the top of each tab | | Viewport | `autozoom` fits the filtered points | on | | Clustering | none in deck.gl; only the legacy `mapbox` chart (`clustering_radius`, needs a Mapbox key) | **no clustering** (§3) | | Marker click | emits a **cross-filter** on the latitude and longitude columns: the exact point, or a box around the click that shrinks as you zoom in. It applies to other charts on the same dashboard | cross-filters the Sites list | | Navigation | **no chart-to-dashboard navigation.** A dashboard reads `?native_filters=` into preselected native filter values (also `native_filters_key`). Table cells render sanitized HTML (`allow_render_html`) | an "Open site detail" link column in the Sites list | | Native filters | Select (single or multi, required, searchable, "first value by default"), Time range; scoping per chart and tab; cross-filter scoping per chart | §4, §5 | | Markdown iframe *(28 Oct)* | `HTML_SANITIZATION` is on and strips an iframe from a Markdown block; `HTML_SANITIZATION_SCHEMA_EXTENSIONS` lets named tags and attributes through. The CSP (`default-src 'self'`, no `frame-src`) allows frames from this origin only | allow `iframe` with `src`, `title`, `loading`, `style`; the fleet-map view is served on the same origin under `/views` (§3) | | Deep link into a tab *(28 Oct)* | `#TAB-` after the URL opens that tab; it combines with `?native_filters=` (tested 28 Oct) | the "Site details" button opens the Site details tab with the site preset | *(28 Oct)* The map moved out of Superset into the fleet-map view (§3). The rows Map chart, Basemap, Tooltip, Marker colour, Marker size, Viewport, Clustering and Marker click describe the deck.gl option the dashboard used until then; the view's choices are in §3. The Navigation row still holds: the view builds the same `?native_filters=` link. No custom frontend and no patch are needed. ## 2. Navigation flow *(28 Oct)* One dashboard, two top-level tabs. *(29 Oct)* They are named **Map** (`TAB-fleet`) and **Insights** (`TAB-site`), the dashboard's lenses; earlier text in this document calls them Fleet and Site details. Readers see them as a lens switch, centred in the navbar (§6). ``` ATOMA (slug atoma) filters, in Superset's left column: Site (exactly one, searchable) · Viewing period — both out of scope on Map; readers have no column there (§6) [Map] the fleet-map view (iframe, /views/fleet-map/), the page's full width towers fitted to the placed sites ──hover or click──► popup "Find a site" (code or name) ──► the map flies to it ──► its popup └─"Site details"──► /superset/dashboard/atoma/?native_filters=(site preset)#TAB-site sites without an accepted location: counted in the map's key ("Choose them in Insights", the view's tab_label parameter); chosen in the Site filter [Insights] D0 site header, then the tabs Summary · Fuel & Deliveries · Runtime & Electricity · Baseline & Evidence (a row of section buttons, not a second row of tabs: dashboard.css) ``` The filters sit in Superset's left column (`filter_bar_orientation: VERTICAL`) *(owner, 29 Oct; `build_bundle.py` checks it)*. A filter shows in the column on the tabs where it is in scope; the others are listed under "Filters out of scope" (the Viewing period on Summary, for example). No filter applies to the Fleet tab, so readers have no column there and the map takes the full width (`reader.css`, §6); admins keep the column on both tabs. The column opens collapsed, a 32 px strip with an expand button (`FILTERBAR_CLOSED_BY_DEFAULT`, `superset_config.py`; owner, 29 Oct); the selected site shows in the Site table above the sections. So for a reader the tabs move sideways by 32 px between Fleet and Site details, or by the column's width once it is expanded; the owner accepted that. From 28 to 29 Oct the filters sat in a row above the tabs (`HORIZONTAL`). On the Fleet tab that row held only an empty "More filters", and hiding it there made the tabs jump down on Site details. Superset 6.1 has no per-tab setting for the filter bar; it hides it only per link (`?show_filters=0`). Until 28 Oct there were two dashboards: "ATOMA - Sites" (slug `atoma-sites`: a deck.gl map, five filters, a sites list) and "ATOMA - Site Detail" (slug `atoma-site-detail`), linked by "Open site detail" and "← Sites map". ## 3. Fleet tab: the fleet-map view *(28 Oct)* The Fleet tab holds one Markdown block with an iframe of the fleet-map view, a page of petrolyst-platform (`views/src/fleet-map/`) served under `/views/` on Superset's own origin. The view reads the read service's `site_status` operation (`/views/api/v1/site-status`, from `public.v_site`). It is not a Superset chart: it has no dataset and no native filter, and both filters are out of scope on this tab. ``` [Fleet tab: MARKDOWN-fleet-map, w12 h100]