Current section

Files

Jump to
ex_teal lib ex_teal.ex
Raw

lib/ex_teal.ex

defmodule ExTeal do
@moduledoc false
alias ExTeal.Plugin
alias Plug.Conn
@type record :: map() | Ecto.Schema.t()
@type records :: module | Ecto.Query.t() | list(record)
@spec application_name() :: String.t()
def application_name do
case manifest() do
nil -> "ExTeal"
module -> module.application_name()
end
end
@spec logo_image_path() :: String.t()
def logo_image_path do
case manifest() do
nil -> "/assets/static/images/logo.svg"
module -> module.logo_image_path()
end
end
@spec path() :: String.t()
def path do
case manifest() do
nil -> "/teal"
module -> module.path()
end
end
@spec json_configuration(Plug.Conn.t()) :: map()
def json_configuration(conn) do
case manifest() do
nil -> %{}
module -> module.json_configuration(conn)
end
end
@spec available_resources() :: [ExTeal.Resource.t()]
def available_resources do
case manifest() do
nil -> []
module -> module.resources()
end
end
@spec available_dashboards() :: [module()]
def available_dashboards do
case manifest() do
nil -> []
module -> module.dashboards()
end
end
@spec available_nav_groups(Plug.Conn.t()) :: [String.t()]
def available_nav_groups(conn) do
case manifest() do
nil -> []
module -> module.nav_groups(conn)
end
end
@spec dashboard_for(String.t()) :: {:ok, module()} | {:error, :not_found}
def dashboard_for(uri) do
case Enum.find(available_dashboards(), fn x -> x.uri() == uri end) do
nil -> {:error, :not_found}
module -> {:ok, module}
end
end
@spec dashboard_metric_for(Conn.t(), String.t()) :: {:ok, module} | {:error, :not_found}
def dashboard_metric_for(conn, uri) do
all_metrics =
available_dashboards()
|> Enum.map(& &1.cards(conn))
|> Enum.concat()
case Enum.find(all_metrics, &(&1.uri() == uri)) do
nil -> {:error, :not_found}
module -> {:ok, module}
end
end
@spec resource_metric_for(Conn.t(), String.t(), String.t()) ::
{:ok, module, module} | {:error, :not_found}
def resource_metric_for(conn, resource_name, metric_uri) do
with {:ok, resource} <- resource_for(resource_name),
cards <- resource.cards(conn),
metric when not is_nil(metric) <- Enum.find(cards, &(&1.uri() == metric_uri)) do
{:ok, resource, metric}
else
_ -> {:error, :not_found}
end
end
def auth_provider do
case manifest() do
nil -> []
module -> module.auth_provider()
end
end
def default_policy do
case manifest() do
nil -> ExTeal.OpenEverywherePolicy
module -> module.default_policy()
end
end
@spec resource_for(String.t()) :: {:ok, ExTeal.Resource.t()} | {:error, :not_found}
def resource_for(name) do
case Enum.find(available_resources(), fn x -> x.uri() == name end) do
nil -> {:error, :not_found}
module -> {:ok, module}
end
end
@spec resource_for_field(ExTeal.Field.t()) :: {:ok, ExTeal.Resource.t()} | {:error, :not_found}
def resource_for_field(field) do
case Enum.find(available_resources(), fn x -> x.title() == Inflex.pluralize(field.name) end) do
nil -> {:error, :not_found}
module -> {:ok, module}
end
end
@spec resource_for_model(module) :: {:ok, ExTeal.Resource.t()} | {:error, :not_found}
def resource_for_model(model) do
case Enum.find(available_resources(), &(&1.model() == model)) do
nil -> {:error, :not_found}
module -> {:ok, module}
end
end
@spec searchable_resources() :: [module]
def searchable_resources do
Enum.filter(available_resources(), fn x -> not Enum.empty?(x.search()) end)
end
@spec available_plugins() :: [ExTeal.Plugin.t()]
def available_plugins do
case manifest() do
nil -> []
module -> module.plugins()
end
end
@spec plugin_for(String.t()) :: {:ok, ExTeal.Plugin.t()} | {:error, :not_found}
def plugin_for(name) do
case Enum.find(available_plugins(), fn x -> x.uri() == name end) do
nil -> {:error, :not_found}
module -> {:ok, module}
end
end
@spec all_scripts() :: [ExTeal.Asset.Script.t()]
def all_scripts do
available_plugins()
|> Enum.map(&Plugin.available_scripts/1)
|> List.flatten()
end
@spec resource_for_relationship(ExTeal.Resource.t(), String.t()) ::
{:ok, ExTeal.Resource.t()} | {:error, :not_found}
def resource_for_relationship(resource, relationship) do
rel = String.to_existing_atom(relationship)
assoc = resource.model().__schema__(:association, rel)
case resource_for_model(assoc.queryable) do
{:ok, module} -> {:ok, module}
{:error, :not_found} -> {:error, :not_found}
end
end
@spec theme() :: ExTeal.Theme.t()
def theme do
case manifest() do
nil -> %ExTeal.Theme{}
module -> module.theme()
end
end
def manifest do
Application.fetch_env!(:ex_teal, :manifest)
end
end