Superset wears the new design; site charts sit as boxes (PD-24 to PD-26)

Theme tokens for the slate surfaces and borders, the logo with the green Y, chart boxes at 16 px
with the card shadow. Full figures with the unit in the subheader; every layer of the tabs
transparent, so the site's charts sit as boxes in Firefox and Safari too. The Overview gets a Sites
filter and the period's scope returns to the time charts (PD-25). The embedded frame can shrink again.
A change to the image's inputs: Superset rebuilds on the next deploy.

Bands: Superset. Rules: 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nasim SadatandClaude Opus 5.5 committed 2026-10-31 01:29:57 +01:00
1 parent 78a498f1ce
commit d95e6e184a
5 files changed
+91 -24

No files matched your search

+6 -4
View File
@@ -566,10 +566,10 @@ The Petrolyst app (petrolyst-platform `app/`, PD-12) shows Superset dashboards i
Insights lens, with guest passes from the Petrolyst server (petrolyst-platform `server/`).
`build_bundle.py` builds them (since PD-13 the only dashboards in the bundle):
| Slug | Content | Filters (set by the app; Superset's filter column is hidden) |
| Slug | Content | Filters (preset by the app's filter row, PD-25; Superset's filter column is hidden) |
|---|---|---|
| `atoma-overview` | O1–O6: sites by pilot status and by baseline status, litres delivered, fuel cost by currency, electricity billed by currency and basis, litres delivered per month | Viewing period on O3–O6 |
| `atoma-site` | the four §4 detail tabs as Superset's own tabs, the same rows and charts; no D0 (the app shows the site's header) | Site (all charts), Viewing period (as §4: fuel and runtime charts only) |
| `overview` | O1–O6: sites by pilot status and by baseline status, litres delivered, fuel cost by currency, electricity billed by currency and basis, litres delivered per month | Sites (`NATIVE_FILTER-sites`, any number, none is all; every chart), Viewing period on O3–O6 |
| `site` | the four §4 detail tabs as Superset's own tabs, the same rows and charts; no D0 (the app shows the site's header) | Site (all charts), Viewing period (as §4: fuel and runtime charts only) |
- **One site dashboard with tabs** *(owner, 29 Oct: "move it back inside the dashboard and make
the tab as they were")*: replaces the four one-tab dashboards `atoma-site-summary`, `-fuel`,
@@ -582,7 +582,9 @@ Insights lens, with guest passes from the Petrolyst server (petrolyst-platform `
recorded values across sites (`OVERVIEW_METRICS`); per-site rates (L/h, L/day) are never
averaged; money is grouped by `currency_text`, a missing currency is its own row, and no
total crosses currencies. `build_bundle.py` checks both.
- They carry no CSS.
- **Dashboard CSS** (`EMBEDDED_CSS` and the site dashboard's tab rule in `build_bundle.py`): Superset's roots at their
content's height, so the app's frame can shrink again (PD-25); the site dashboard's tab layers transparent, so its
charts sit as boxes like the Overview's (PD-24); the chart boxes with 16 px corners and the card shadow (PD-26).
- `import_bundle.py --embedded-out FILE --embed-domain URL` makes them embeddable from the app's
origin and writes `{slug: embedding id}` for the Petrolyst server.
- Embedding is switched on in the local stack only (`.local/fmdb-scratch`,
@@ -456,7 +456,8 @@ def big_number(key: str, title: str, view: str, metric: dict[str, Any], *,
"subheader": subheader,
"header_font_size": 0.4,
"subheader_font_size": 0.15,
"y_axis_format": "SMART_NUMBER",
# The brand's number conventions (PD-24): "59,312", never "59.3k"; the unit is named in the subheader.
"y_axis_format": ",d",
"time_format": "smart_date",
"force_timestamp_formatting": False,
}
@@ -487,7 +488,8 @@ def timeseries_common(x: str, metrics: list[Any], groupby: list[str], grain: str
"y_axis_title_margin": 40,
"y_axis_title_position": "Left",
"x_axis_time_format": "%Y-%m-%d",
"y_axis_format": "SMART_NUMBER",
# Full figures, as the brand's conventions want (PD-24): one decimal for a rate, none for litres and counts.
"y_axis_format": ",.1f" if "/" in y_title else ",d",
"rich_tooltip": True,
"tooltipTimeFormat": "%Y-%m-%d",
"truncateXAxis": True,
@@ -523,7 +525,7 @@ def overview_charts() -> list[Chart]:
return [
big_number("O3", "Litres delivered", "v_delivery", m("SUM(delivered_l)", "Litres delivered"),
period="delivery_date", subheader="all sites, in the viewing period",
period="delivery_date", subheader="litres, the chosen sites, in the viewing period",
description="Recorded deliveries. Deliveries are not consumption."),
summary_table("O1", "Sites by pilot status", "v_site", ["pilot_status"],
[m("COUNT(*)", "Sites")]),
@@ -552,8 +554,9 @@ def overview_charts() -> list[Chart]:
OVERVIEW_NOTES = ("**Reading this page.** All sites together, from recorded values only: "
"deliveries are not consumption, and site rates (L/h, L/day) are never averaged "
"here; each site's own page has them. Money is shown per currency and never added "
"up across currencies. The viewing period narrows the deliveries, the costs and "
"the monthly bars; the site counts are always the current state.")
"up across currencies. The Sites filter narrows every figure to the chosen sites "
"(none chosen: all); the viewing period narrows the deliveries, the costs and "
"the monthly bars, while the site counts are always the current state.")
OVERVIEW_ROWS = [
[("MARKDOWN:notes-overview", 12, 14)],
[("O3", 4, 40), ("O1", 4, 40), ("O2", 4, 40)],
@@ -561,6 +564,17 @@ OVERVIEW_ROWS = [
[("O6", 12, 60)],
]
OVERVIEW_PERIOD_SCOPE = {"O3", "O4", "O5", "O6"}
SITES_FILTER = "NATIVE_FILTER-sites"
def overview_filters(ids: dict[str, int]) -> list[dict[str, Any]]:
"""Sites (any number, none is all) and the Viewing period (PD-25: both in Superset's column)."""
sites = select_filter(SITES_FILTER, "Sites", "v_site", "site_label", multi=True,
required=False, excluded=[])
sites["description"] = "Any number of sites; none chosen is all sites. Search by code or name."
period = period_filter(ids, OVERVIEW_PERIOD_SCOPE,
"Narrows the deliveries, the costs and the monthly bars.")
return [sites, period]
# --- Site Detail -----------------------------------------------------------------------
@@ -699,7 +713,7 @@ def detail_charts() -> list[Chart]:
"show_legend": True,
"legendType": "scroll",
"legendOrientation": "top",
"y_axis_format": "SMART_NUMBER",
"y_axis_format": ",.1f",
"rich_tooltip": True,
"x_axis_time_format": "%Y-%m-%d",
"y_axis_title": "L/h",
@@ -947,6 +961,20 @@ def dashboard_yaml(key: str, title: str, slug: str, layout: Layout, metadata: di
}
# Dashboard CSS for the app's frame (PD-12): the app grows the frame to the page's scroll height,
# and Superset's page stretches to the frame, so without this the frame could only ever grow (a
# taller tab, once opened, left empty space under every other tab: measured 1438 → 2174 → 3158,
# never back). With the roots at their content's height the frame shrinks again.
EMBEDDED_CSS = ("html, body, #app, #app > div, #app > div > div, .dashboard, .dashboard-content "
"{ height: auto !important; min-height: 0 !important; } "
# Chart boxes as the app's cards (PD-26); dashboard CSS cannot read the brand's tokens,
# so these are --radius-md and the light --shadow-card written out.
".dashboard-component-chart-holder, .dashboard-markdown { border-radius: 16px !important; box-shadow: "
"0 2px 4px rgb(11 29 51 / 0.04), 0 12px 28px -8px rgb(11 29 51 / 0.12) !important; } "
# A notes block's wrapper clips what is inside it, so the wrapper carries the shadow.
".dashboard-markdown .dashboard-component-chart-holder { box-shadow: none !important; } ")
def base_metadata(layout: Layout, filters: list[dict[str, Any]], cross_filters: bool) -> dict[str, Any]:
return {
"color_scheme": "supersetColors",
@@ -959,8 +987,8 @@ def base_metadata(layout: Layout, filters: list[dict[str, Any]], cross_filters:
"map_label_colors": {},
"color_scheme_domain": [],
"cross_filters_enabled": cross_filters,
# Filters in Superset's left column (owner, 29 Oct); the Petrolyst app hides the column
# when it embeds a dashboard and sets the filters itself.
# Filters in Superset's left column (owner, 29 Oct) for admins; the Petrolyst app hides
# the column when it embeds a dashboard and sets the filters itself (PD-25).
"filter_bar_orientation": "VERTICAL",
"native_filter_configuration": filters,
"chart_configuration": {},
@@ -1010,16 +1038,26 @@ def build(database_uuid: str, columns_path: Path) -> dict[str, Any]:
page.markdown["notes-overview"] = OVERVIEW_NOTES
if key == OVERVIEW_SLUG:
page.rows(OVERVIEW_ROWS, "GRID_ID", "overview")
filters = [period_filter(page.ids, OVERVIEW_PERIOD_SCOPE,
"Narrows the deliveries, the costs and the monthly bars.")]
filters = overview_filters(page.ids)
css = EMBEDDED_CSS
else:
page.tabs(DETAIL_TABS, "GRID_ID", "TABS-detail")
filters = detail_filters(page.ids)
# Superset paints its tab container white, which swallows the charts' own boxes; the
# Overview has no tabs and shows each chart as a box on the page (PD-24). Every layer
# of the tabs is named, with !important, because Superset 6.1 paints the holder white
# with a two-class rule, and Firefox and Safari also paint the outer container white
# where Chrome does not (measured in all three).
css = EMBEDDED_CSS + (
".dashboard-component-tabs, .dashboard-component-tabs-content, "
".dashboard-component-tabs .ant-tabs, .dashboard-component-tabs .ant-tabs-content-holder, "
".dashboard-component-tabs .ant-tabs-content, .dashboard-component-tabs .ant-tabs-tabpane "
"{ background: transparent !important; }")
placed = {k: all_charts[k] for k in page.ids}
page_metadata = base_metadata(page, filters, cross_filters=False)
page_metadata["label_colors"].update(STOCK_STATUS_COLOURS)
files[f"dashboards/{key}.yaml"] = dashboard_yaml(key, title, key, page,
page_metadata)
page_metadata, css=css)
dashboards.append((page, placed, page_metadata))
for chart in all_charts.values():