Lotus.Dashboards (Lotus v0.16.5)

Copy Markdown View Source

Service functions for managing dashboards in Lotus.

Provides CRUD operations for dashboards, cards, filters, and filter mappings, as well as execution functions for running all cards in a dashboard.

Dashboard Structure

Dashboards contain:

  • Cards - Query results, text, links, or headings arranged in a 12-column grid
  • Filters - User inputs that control query variables across multiple cards
  • Filter Mappings - Connections between dashboard filters and card query variables

Execution

Use run_dashboard/2 to execute all query cards in a dashboard simultaneously. Filter values are resolved and passed to each card's query variables via the configured mappings.

Summary

Functions

Creates a new dashboard.

Creates a new card for a dashboard.

Creates a new filter for a dashboard.

Creates a filter mapping connecting a dashboard filter to a card's query variable.

Deletes a dashboard.

Deletes a card.

Deletes a filter mapping.

Disables public sharing for a dashboard by removing its token.

Enables public sharing for a dashboard by generating a unique token.

Gets a single dashboard by ID.

Gets a single dashboard by ID.

Gets a dashboard by its public sharing token.

Gets a single card by ID.

Gets a single card by ID.

Gets a single filter by ID.

Gets a single filter by ID.

Lists all filter mappings for a card.

Lists all cards for a dashboard.

Lists all filters for a dashboard.

Lists all dashboards.

Lists dashboards with optional filtering.

Reorders cards in a dashboard.

Runs all query cards in a dashboard and returns their results.

Runs a single dashboard card and returns its result.

Updates a dashboard.

Types

attrs()

@type attrs() :: map()

id()

@type id() :: integer() | binary()

Functions

create_dashboard(attrs)

@spec create_dashboard(attrs()) ::
  {:ok, Lotus.Storage.Dashboard.t()} | {:error, Ecto.Changeset.t()}

Creates a new dashboard.

Examples

iex> create_dashboard(%{name: "Sales Dashboard"})
{:ok, %Dashboard{}}

iex> create_dashboard(%{})
{:error, %Ecto.Changeset{}}

create_dashboard_card(dashboard_id, attrs)

@spec create_dashboard_card(Lotus.Storage.Dashboard.t() | id(), attrs()) ::
  {:ok, Lotus.Storage.DashboardCard.t()} | {:error, Ecto.Changeset.t()}

Creates a new card for a dashboard.

Examples

iex> create_dashboard_card(dashboard, %{
...>   card_type: :query,
...>   query_id: 123,
...>   position: 0,
...>   layout: %{x: 0, y: 0, w: 6, h: 4}
...> })
{:ok, %DashboardCard{}}

create_dashboard_filter(dashboard_id, attrs)

@spec create_dashboard_filter(Lotus.Storage.Dashboard.t() | id(), attrs()) ::
  {:ok, Lotus.Storage.DashboardFilter.t()} | {:error, Ecto.Changeset.t()}

Creates a new filter for a dashboard.

Examples

iex> create_dashboard_filter(dashboard, %{
...>   name: "date_range",
...>   label: "Date Range",
...>   filter_type: :date_range,
...>   widget: :date_range_picker,
...>   position: 0
...> })
{:ok, %DashboardFilter{}}

create_filter_mapping(card, filter, variable_name, opts \\ [])

Creates a filter mapping connecting a dashboard filter to a card's query variable.

Options

  • :transform - Optional transformation config for the filter value

Examples

iex> create_filter_mapping(card, filter, "start_date")
{:ok, %DashboardCardFilterMapping{}}

iex> create_filter_mapping(card, filter, "end_date", transform: %{type: "date_range_end"})
{:ok, %DashboardCardFilterMapping{}}

delete_dashboard(dashboard)

@spec delete_dashboard(Lotus.Storage.Dashboard.t()) ::
  {:ok, Lotus.Storage.Dashboard.t()} | {:error, Ecto.Changeset.t()}

Deletes a dashboard.

Also deletes all associated cards, filters, and filter mappings.

Examples

iex> delete_dashboard(dashboard)
{:ok, %Dashboard{}}

delete_dashboard_card(card)

@spec delete_dashboard_card(Lotus.Storage.DashboardCard.t() | id()) ::
  {:ok, Lotus.Storage.DashboardCard.t()}
  | {:error, Ecto.Changeset.t() | :not_found}

Deletes a card.

Also deletes all associated filter mappings.

delete_dashboard_filter(filter)

@spec delete_dashboard_filter(Lotus.Storage.DashboardFilter.t() | id()) ::
  {:ok, Lotus.Storage.DashboardFilter.t()}
  | {:error, Ecto.Changeset.t() | :not_found}

Deletes a filter.

Also deletes all associated filter mappings.

delete_filter_mapping(mapping)

@spec delete_filter_mapping(Lotus.Storage.DashboardCardFilterMapping.t() | id()) ::
  {:ok, Lotus.Storage.DashboardCardFilterMapping.t()}
  | {:error, Ecto.Changeset.t() | :not_found}

Deletes a filter mapping.

disable_public_sharing(dashboard)

@spec disable_public_sharing(Lotus.Storage.Dashboard.t()) ::
  {:ok, Lotus.Storage.Dashboard.t()} | {:error, Ecto.Changeset.t()}

Disables public sharing for a dashboard by removing its token.

Examples

iex> disable_public_sharing(dashboard)
{:ok, %Dashboard{public_token: nil}}

enable_public_sharing(dashboard)

@spec enable_public_sharing(Lotus.Storage.Dashboard.t()) ::
  {:ok, Lotus.Storage.Dashboard.t()} | {:error, Ecto.Changeset.t()}

Enables public sharing for a dashboard by generating a unique token.

The token can be used to access the dashboard without authentication via get_dashboard_by_token/1.

Examples

iex> enable_public_sharing(dashboard)
{:ok, %Dashboard{public_token: "abc123..."}}

get_dashboard(id)

@spec get_dashboard(id()) :: Lotus.Storage.Dashboard.t() | nil

Gets a single dashboard by ID.

Returns nil if the dashboard does not exist.

get_dashboard!(id)

@spec get_dashboard!(id()) :: Lotus.Storage.Dashboard.t() | no_return()

Gets a single dashboard by ID.

Raises Ecto.NoResultsError if the dashboard does not exist.

get_dashboard_by_token(token)

@spec get_dashboard_by_token(String.t()) :: Lotus.Storage.Dashboard.t() | nil

Gets a dashboard by its public sharing token.

Returns nil if no dashboard has the given token.

get_dashboard_card(id, opts \\ [])

@spec get_dashboard_card(
  id(),
  keyword()
) :: Lotus.Storage.DashboardCard.t() | nil

Gets a single card by ID.

Returns nil if the card does not exist.

Options

  • :preload - A list of associations to preload

get_dashboard_card!(id, opts \\ [])

@spec get_dashboard_card!(
  id(),
  keyword()
) :: Lotus.Storage.DashboardCard.t() | no_return()

Gets a single card by ID.

Raises Ecto.NoResultsError if the card does not exist.

Options

  • :preload - A list of associations to preload

get_dashboard_filter(id)

@spec get_dashboard_filter(id()) :: Lotus.Storage.DashboardFilter.t() | nil

Gets a single filter by ID.

Returns nil if the filter does not exist.

get_dashboard_filter!(id)

@spec get_dashboard_filter!(id()) :: Lotus.Storage.DashboardFilter.t() | no_return()

Gets a single filter by ID.

Raises Ecto.NoResultsError if the filter does not exist.

list_card_filter_mappings(card_id)

@spec list_card_filter_mappings(Lotus.Storage.DashboardCard.t() | id()) :: [
  Lotus.Storage.DashboardCardFilterMapping.t()
]

Lists all filter mappings for a card.

list_dashboard_cards(dashboard_or_id, opts \\ [])

@spec list_dashboard_cards(
  Lotus.Storage.Dashboard.t() | id(),
  keyword()
) :: [Lotus.Storage.DashboardCard.t()]

Lists all cards for a dashboard.

Returns cards ordered by position, then by id.

Options

  • :preload - A list of associations to preload (e.g., [:query, :filter_mappings])

Examples

iex> list_dashboard_cards(dashboard)
[%DashboardCard{}, ...]

iex> list_dashboard_cards(dashboard_id, preload: [:query, :filter_mappings])
[%DashboardCard{query: %Query{}, filter_mappings: [...]}, ...]

list_dashboard_filters(dashboard_id)

@spec list_dashboard_filters(Lotus.Storage.Dashboard.t() | id()) :: [
  Lotus.Storage.DashboardFilter.t()
]

Lists all filters for a dashboard.

Returns filters ordered by position, then by id.

list_dashboards()

@spec list_dashboards() :: [Lotus.Storage.Dashboard.t()]

Lists all dashboards.

Returns dashboards ordered by name.

list_dashboards_by(opts \\ [])

@spec list_dashboards_by(keyword()) :: [Lotus.Storage.Dashboard.t()]

Lists dashboards with optional filtering.

Options

  • :search - Search term to match against dashboard names (case insensitive)

Examples

iex> list_dashboards_by(search: "sales")
[%Dashboard{name: "Sales Overview"}, ...]

reorder_dashboard_cards(dashboard_id, card_ids)

@spec reorder_dashboard_cards(Lotus.Storage.Dashboard.t() | id(), [id()]) :: :ok

Reorders cards in a dashboard.

Accepts a list of card IDs in the desired order. Each card's position will be updated to match its index in the list.

Examples

iex> reorder_dashboard_cards(dashboard, [card3_id, card1_id, card2_id])
:ok

run_dashboard(dashboard, opts \\ [])

@spec run_dashboard(
  Lotus.Storage.Dashboard.t() | id(),
  keyword()
) :: %{required(id()) => {:ok, Lotus.Result.t()} | {:error, term()}}

Runs all query cards in a dashboard and returns their results.

Returns a map of card IDs to their results. By default, cards are executed in parallel for better performance.

Options

  • :filter_values - Map of filter names to their current values
  • :parallel - Whether to run cards in parallel (default: true)
  • :timeout - Timeout per card in milliseconds (default: 30000)

Filter Resolution

Filter values are resolved to query variables through the configured mappings. For each card:

  1. Get all filter mappings for the card
  2. For each mapping, get the filter value from :filter_values
  3. Apply any configured transform to the value
  4. Pass the value to the query as the mapped variable name

Examples

iex> run_dashboard(dashboard, filter_values: %{"date_range" => "2024-01-01"})
%{
  1 => {:ok, %Lotus.Result{}},
  2 => {:ok, %Lotus.Result{}},
  3 => {:error, "Missing required variable: status"}
}

run_dashboard_card(card, opts \\ [])

@spec run_dashboard_card(
  Lotus.Storage.DashboardCard.t() | id(),
  keyword()
) :: {:ok, Lotus.Result.t()} | {:error, term()}

Runs a single dashboard card and returns its result.

Options

  • :filter_values - Map of filter names to their current values
  • :timeout - Query timeout in milliseconds

Examples

iex> run_dashboard_card(card, filter_values: %{"user_id" => "123"})
{:ok, %Lotus.Result{}}

update_dashboard(dashboard, attrs)

@spec update_dashboard(Lotus.Storage.Dashboard.t(), attrs()) ::
  {:ok, Lotus.Storage.Dashboard.t()} | {:error, Ecto.Changeset.t()}

Updates a dashboard.

Examples

iex> update_dashboard(dashboard, %{name: "New Name"})
{:ok, %Dashboard{}}

update_dashboard_card(card, attrs)

@spec update_dashboard_card(Lotus.Storage.DashboardCard.t(), attrs()) ::
  {:ok, Lotus.Storage.DashboardCard.t()} | {:error, Ecto.Changeset.t()}

Updates a card.

Examples

iex> update_dashboard_card(card, %{title: "Revenue Chart"})
{:ok, %DashboardCard{}}

update_dashboard_filter(filter, attrs)

@spec update_dashboard_filter(Lotus.Storage.DashboardFilter.t(), attrs()) ::
  {:ok, Lotus.Storage.DashboardFilter.t()} | {:error, Ecto.Changeset.t()}

Updates a filter.

Examples

iex> update_dashboard_filter(filter, %{label: "Select Period"})
{:ok, %DashboardFilter{}}