BI Dashboard
A flat, server-free dashboard for the Brandize BI webhook
(Summe je Abgangsland). It shows the gross revenue (Brutto inkl. USt) per
departure country for a selected period, with KPI cards, a bar chart and a
detail table.
Run
Just open index.html in a browser (double-click it). No server, no build step.
The page calls the webhook directly:
https://brandize.app.n8n.cloud/webhook/bi-dashboard
via a POST request with a JSON body:
{ "query": "Summe je Abgangsland", "month": "2026-SEP" }
The webhook sends CORS headers (it reflects the request Origin, including
null for file://), so a direct browser call works.
Navigation
The left sidebar groups reports by topic:
- Amazon → Umsatz je Abgangsland (Brutto inkl. USt je Abgangsland)
- Amazon → VAT Summary (USt-Übersicht je Land)
- ODOO → Rechnungen pro Monat (Pivot über Odoo-Rechnungen)
- Gesamt → Alle Rechnungen pro Monat (PivotTable.js-Experiment)
- Schweiz → Quartal Schweiz (AMAZON + ODOO, Lieferung in die Schweiz)
All groups start collapsed, so no submenu is visible when the page opens. Clicking a topic expands its submenu; clicking a submenu item switches the view.
Authentication
The webhooks are protected with HTTP Basic Auth. The dashboard asks for the
credentials when they are needed: the first request is sent without them, and
when the webhook answers 401, a login prompt appears. The entered
credentials are sent as an Authorization: Basic ... header on every request
and kept in sessionStorage for the rest of the browser session (so a reload
does not prompt again). If the webhook rejects them (401), the prompt
reappears. Storage is best-effort: on file:// it may be unavailable, in which
case credentials are kept in memory only.
CSV export
The header has a CSV button that downloads the data of the currently displayed dashboard, as a semicolon-delimited UTF-8 file (with BOM) including a Gesamt row:
- Umsatz je Abgangsland →
umsatz-je-abgangsland_YYYY-MMM.csv - VAT Summary →
vat-summary_YYYY-MMM.csv - Rechnungen pro Monat →
odoo-rechnungen_YYYY-MMM.csv - Alle Rechnungen pro Monat →
gesamt-rechnungen-pivot_YYYY-MMM.csv - Quartal Schweiz →
schweiz-quartal_YYYY-QN.csv
The button is disabled while no dataset is loaded for the current dashboard.
Filter
A shared filter bar sits above every dashboard (labelled Filter with a
funnel icon and the hint gilt für alle Dashboards). It holds the Zeitraum
month + year selector (e.g. 2026-SEP) and the reload button, and stays visible
across all views. The previous month is preselected. The selected period is
sent to the webhook in the POST body as month (e.g. 2026-SEP), matching the
%(month)s parameter used in ../sql/*.sql.
The invoice dashboards (ODOO Rechnungen pro Monat, Alle Rechnungen pro Monat and Quartal Schweiz) have an additional, dashboard-specific filter row. ODOO Rechnungen pro Monat filters by Tag, Bestellnummer, Lieferland and Rechnungsnummer; Alle Rechnungen pro Monat and Quartal Schweiz add a Quelle field. Filtering re-renders the KPIs, chart and pivot live.
For Quartal Schweiz the shared Zeitraum control shows a quarter selector (Q1–Q4) instead of the month selector; the year selector is shared.
Pivot (Experiment)
The three invoice dashboards (ODOO Rechnungen pro Monat, Alle Rechnungen pro Monat and Quartal Schweiz) render their data as an interactive PivotTable.js pivot instead of a detail table. The pivot's rows, columns, values and aggregator are freely configurable in the pivotUI control panel; the renderer is fixed to Table. Each dashboard has its own filter row and Vorlage dropdown with presets:
- ODOO Rechnungen pro Monat: Standard (Rechnungsland rows, no column group, Sum(Gesamtpreis brutto)) and Zahlart.
- Alle Rechnungen pro Monat and Quartal Schweiz: Standard (Quelle rows, no column group, Sum(Gesamtpreis brutto)) and Rechnungsland (Spalten) (adds Rechnungsland as the column group).
Quartal Schweiz is filtered to invoices with a delivery into Switzerland.
Applying a preset also resets the filters. The chosen layout is kept while you type in the filters.
It loads jQuery, jQuery UI and PivotTable.js from public CDNs, so — unlike the
rest of the app — it needs an internet connection to render; offline it shows
a short message instead. To vendor the libraries locally, download them next to
index.html and change the <link>/<script> URLs in the <head>.
Data sources
Because the datasets are large, the dashboard requests only the dataset of
the currently displayed dashboard — one POST per dashboard, sent only when
that dashboard is opened or reloaded. Nothing is prefetched. The dataset is
selected with the query field:
- Umsatz je Abgangsland →
query: "Summe je Abgangsland" - VAT Summary →
query: "VAT Summary" - Rechnungen pro Monat →
query: "ODOO Rechnungen pro Monat" - Alle Rechnungen pro Monat →
query: "Alle Rechnungen pro Monat" - Quartal Schweiz →
query: "Quartal Schweiz"(sendsquarterinstead ofmonth)
Files
| File | Purpose |
|---|---|
index.html |
Dashboard markup |
styles.css |
Styling |
app.js |
Data loading, parsing and rendering |