Skip to content
GitHub

LiveReportArtefact

LiveReportArtefact manifests define production-ready web applications that serve multiple ReportArtefacts as navigable pages with support for dynamic query parameter substitution.

apiVersion: bino.bi/v1alpha1
kind: LiveReportArtefact
metadata:
  name: sales-dashboard
spec:
  title: "Sales Dashboard"
  description: "Interactive sales reporting application"
  routes:
    "/":
      artefact: overview-report
      queryParams:
        - name: YEAR
          default: "2024"
          description: "Year to display"
    "/sales":
      artefact: sales-report
      title: "Sales Analysis"
      queryParams:
        - name: REGION
          description: "Region filter (required)"
    "/regions":
      artefact: region-report
      title: "Regional Breakdown"
    "/quick-view":
      # Alternative: use layoutPages instead of artefact
      layoutPages:
        - summary-page
        - charts-page

Human-readable title of the live report application.

Optional description of the application.

Map of URL paths to route configurations. The root route / is mandatory.

Each route must specify either artefact or layoutPages (but not both):

  • artefact – name of a ReportArtefact to render for this route.
  • layoutPages – name of a LayoutPage or an array of LayoutPage names to render directly (without a ReportArtefact wrapper).
  • title – optional page title override.
  • queryParams – array of query parameters allowed for this route.

Routes are accessible at their defined paths, e.g., /sales renders sales-report.

Using artefact:

routes:
  "/":
    artefact: overview-report

Using layoutPages (single page):

routes:
  "/":
    layoutPages: overview-page

Using layoutPages (multiple pages):

routes:
  "/":
    layoutPages:
      - page-1
      - page-2
      - page-3

The layoutPages option is useful when you want to serve individual LayoutPage documents directly without defining a full ReportArtefact.

Array of query parameters allowed for this specific route.

Each parameter has:

  • name (required) – parameter name, used as ${name} in documents.
  • type – input type for the serve UI. One of: string (default), number, number_range, select, date, date_time.
  • default – default value if parameter is not provided.
  • optional – if true, the parameter is optional even without a default value. The parameter will be empty if not provided.
  • description – human-readable description.
  • options – configuration for select, number, and number_range types.

Important: If a parameter has no default and optional is not true, the server returns HTTP 400 with a JSON error listing the missing parameters.

TypeInput controlDescription
stringText inputDefault type. Free-text input.
numberNumber inputNumeric input with optional min/max/step.
number_rangeDual range sliderFor min/max range filtering. Creates two parameters: {name} and {name}_max.
selectDropdownSelection from predefined options (static or from a DataSet).
dateDate pickerDate selection (YYYY-MM-DD format).
date_timeDateTime pickerDate and time selection (ISO 8601 format).

The options object supports different settings depending on the parameter type:

For select type:

queryParams:
  - name: REGION
    type: select
    description: "Select region"
    options:
      items:
        - value: "EU"
          label: "Europe"
        - value: "US"
          label: "United States"
        - value: "APAC"
          label: "Asia Pacific"

For select parameters with static items, you can access both the value and label:

  • ${REGION} – the value (e.g., "EU")
  • ${REGION_LABEL} – the label (e.g., "Europe")

This is useful for displaying human-readable text while using the value for data filtering.

For select with DataSet:

queryParams:
  - name: CATEGORY
    type: select
    description: "Select category"
    options:
      dataset: category_list
      valueColumn: category_id
      labelColumn: category_name

The referenced DataSet should return rows with the specified columns. If labelColumn is omitted, valueColumn is used for both.

For number and number_range types:

queryParams:
  - name: YEAR
    type: number
    default: "2024"
    options:
      min: 2000
      max: 2030
      step: 1
  - name: PRICE
    type: number_range
    description: "Price range filter"
    options:
      min: 0
      max: 10000
      step: 100

Query parameters are substituted into your report documents using the same ${VAR} syntax as environment variables. This allows dynamic filtering of data.

Example DataSet using a query parameter:

apiVersion: bino.bi/v1alpha1
kind: DataSet
metadata:
  name: filtered_sales
spec:
  type: query
  query: |
    SELECT * FROM sales
    WHERE year = ${YEAR}
    AND region = '${REGION}'

When accessed with ?YEAR=2024&REGION=EU, the query becomes:

SELECT * FROM sales
WHERE year = 2024
AND region = 'EU'

For select parameters with static items, use ${PARAM_LABEL} to show the human-readable label:

apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
  name: sales-page
spec:
  children:
    - kind: Text
      spec:
        # Shows "Sales Report for Europe" instead of "Sales Report for EU"
        value: "Sales Report for ${REGION_LABEL}"
---
apiVersion: bino.bi/v1alpha1
kind: ReportArtefact
metadata:
  name: main-report
spec:
  filename: main.pdf
  title: "Main Report"
---
apiVersion: bino.bi/v1alpha1
kind: LiveReportArtefact
metadata:
  name: dashboard
spec:
  title: "Dashboard"
  routes:
    "/":
      artefact: main-report

Serve with:

bino serve --live dashboard
---
apiVersion: bino.bi/v1alpha1
kind: ReportArtefact
metadata:
  name: overview
spec:
  filename: overview.pdf
  title: "Overview"
---
apiVersion: bino.bi/v1alpha1
kind: ReportArtefact
metadata:
  name: sales
spec:
  filename: sales.pdf
  title: "Sales Detail"
---
apiVersion: bino.bi/v1alpha1
kind: ReportArtefact
metadata:
  name: regions
spec:
  filename: regions.pdf
  title: "Regional Analysis"
---
apiVersion: bino.bi/v1alpha1
kind: LiveReportArtefact
metadata:
  name: sales-app
spec:
  title: "Sales Application"
  routes:
    "/":
      artefact: overview
      queryParams:
        - name: YEAR
          default: "2024"
          description: "Reporting year"
    "/sales":
      artefact: sales
      title: "Sales Details"
    "/regions":
      artefact: regions
      title: "Regions"
---
apiVersion: bino.bi/v1alpha1
kind: DataSet
metadata:
  name: year_sales
spec:
  type: query
  query: |
    SELECT * FROM raw_sales
    WHERE extract(year from sale_date) = ${YEAR:2024}
---
apiVersion: bino.bi/v1alpha1
kind: DataSet
metadata:
  name: department_list
spec:
  type: query
  query: |
    SELECT DISTINCT department_id, department_name FROM departments ORDER BY department_name
---
apiVersion: bino.bi/v1alpha1
kind: LiveReportArtefact
metadata:
  name: dynamic-report
spec:
  title: "Dynamic Report"
  routes:
    "/":
      artefact: main-report
      queryParams:
        - name: YEAR
          type: number
          default: "2024"
          description: "Year for analysis"
          options:
            min: 2000
            max: 2030
        - name: DEPARTMENT
          type: select
          description: "Department (required)"
          options:
            dataset: department_list
            valueColumn: department_id
            labelColumn: department_name
        - name: START_DATE
          type: date
          description: "Start date for report period"
        - name: AMOUNT_RANGE
          type: number_range
          description: "Filter by amount"
          options:
            min: 0
            step: 100

Access patterns:

  • / – uses default YEAR=2024, but requires DEPARTMENT
  • /?DEPARTMENT=sales – works, uses default YEAR
  • /?YEAR=2023&DEPARTMENT=marketing – overrides YEAR
  • /?YEAR=2023 – returns HTTP 400: missing DEPARTMENT

LiveReportArtefact applications include built-in navigation. When navigating between routes:

  1. The browser URL updates via History API.
  2. Only the report content is fetched and swapped.
  3. Assets (CSS, fonts, scripts) are not reloaded.

This provides a smooth single-page application experience while maintaining proper URL routing.

When using layoutPages in a route, you can pass parameters to LayoutPages that define them. This combines the power of LayoutPage parameters with dynamic query parameters.

apiVersion: bino.bi/v1alpha1
kind: LiveReportArtefact
metadata:
  name: regional-dashboard
spec:
  title: "Regional Dashboard"
  routes:
    "/regional":
      layoutPages:
        - page: regional-sales
          params:
            REGION: ${REGION}      # From query params
            YEAR: ${YEAR}
      queryParams:
        - name: REGION
          type: select
          default: "EU"
          options:
            items:
              - value: "EU"
                label: "Europe"
              - value: "US"
                label: "North America"
              - value: "APAC"
                label: "Asia Pacific"
        - name: YEAR
          type: number
          default: "2024"
          options:
            min: 2020
            max: 2030

When users visit /regional?REGION=US&YEAR=2023, the query params flow into the LayoutPage params, rendering the page with those values.

You can mix static values with dynamic query param references:

routes:
  "/comparison":
    layoutPages:
      # First page: current year, user-selected region
      - page: regional-sales
        params:
          REGION: ${REGION}
          YEAR: "2024"              # Static value
          LABEL: "Current Year"

      # Second page: previous year, same region
      - page: regional-sales
        params:
          REGION: ${REGION}         # Same as user selected
          YEAR: "2023"              # Static: previous year
          LABEL: "Previous Year"
    queryParams:
      - name: REGION
        type: select
        default: "EU"

This creates a comparison view showing two years side by side.

Include the same LayoutPage multiple times with different parameter combinations:

routes:
  "/all-regions":
    layoutPages:
      - page: regional-sales
        params:
          REGION: EU
          YEAR: ${YEAR}
      - page: regional-sales
        params:
          REGION: US
          YEAR: ${YEAR}
      - page: regional-sales
        params:
          REGION: APAC
          YEAR: ${YEAR}
    queryParams:
      - name: YEAR
        type: number
        default: "2024"

This shows all three regions on a single page, with the year controlled by the query parameter.

---
# Define a parameterized LayoutPage
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
  name: department-kpis
  params:
    - name: DEPARTMENT
      type: string
      required: true
    - name: YEAR
      type: number
      default: "2024"
    - name: SHOW_FORECAST
      type: boolean
      default: "false"
spec:
  titleBusinessUnit: "${DEPARTMENT} KPIs"
  pageLayout: 2x2
  children:
    - kind: Text
      spec:
        value: "${DEPARTMENT} Performance - ${YEAR}"
    - kind: ChartStructure
      spec:
        dataset: department-data
        chartTitle: "Revenue"
    - kind: Table
      spec:
        dataset: department-data
        tableTitle: "Details"

---
# Use it in a LiveReportArtefact
apiVersion: bino.bi/v1alpha1
kind: LiveReportArtefact
metadata:
  name: department-dashboard
spec:
  title: "Department Dashboard"
  routes:
    # Single department view
    "/":
      layoutPages:
        - page: department-kpis
          params:
            DEPARTMENT: ${DEPARTMENT}
            YEAR: ${YEAR}
            SHOW_FORECAST: ${SHOW_FORECAST:false}
      queryParams:
        - name: DEPARTMENT
          type: select
          description: "Select department"
          options:
            dataset: department_list
            valueColumn: dept_id
            labelColumn: dept_name
        - name: YEAR
          type: number
          default: "2024"
          options:
            min: 2020
            max: 2030
        - name: SHOW_FORECAST
          type: select
          default: "false"
          options:
            items:
              - value: "true"
                label: "Yes"
              - value: "false"
                label: "No"

    # All departments view
    "/all":
      layoutPages:
        - page: department-kpis
          params:
            DEPARTMENT: "Sales"
            YEAR: ${YEAR}
        - page: department-kpis
          params:
            DEPARTMENT: "Marketing"
            YEAR: ${YEAR}
        - page: department-kpis
          params:
            DEPARTMENT: "Engineering"
            YEAR: ${YEAR}
      queryParams:
        - name: YEAR
          type: number
          default: "2024"

Access patterns:

  • /?DEPARTMENT=Sales – Shows Sales department for 2024
  • /?DEPARTMENT=Marketing&YEAR=2023 – Shows Marketing for 2023
  • /all – Shows all departments for 2024
  • /all?YEAR=2022 – Shows all departments for 2022

The CLI validates LiveReportArtefact manifests at load time:

  • Root route / must be present.
  • All route paths must start with /.
  • All referenced artefact names must correspond to existing ReportArtefact manifests.
  • All referenced LayoutPages in layoutPages must exist.
  • Query parameter names must be unique within each route.

Validation errors are reported before the server starts.