defmodule Runbox.Scenario.UIAction do
@moduledoc """
Definition of action to be fired from UI.
In scenario list of `Runbox.Scenario.UIAction`s is defined and stored in asset
map entity. When action is fired from UI, scenario receives `Runbox.Scenario.UserAction`.
"""
alias Runbox.Scenario.UserAction
import Runbox.Utils.Enum, only: [map_while_ok: 2]
@typedoc """
UI action definition.
Properties `topic`, `type` and `details` are serialized to JWT token and used for
routing of fired action. Property `topic` is name of raw topic where fired actions
are pushed, property `type` is type to be used in `Runbox.Message` as `type` and
property `details` is stored in resulting message `body` as `details` property.
Properties `name` and `description` are only metadata for UI.
"""
@type t :: %__MODULE__{
topic: String.t(),
type: String.t(),
details: map,
name: String.t(),
description: String.t()
}
defstruct [:topic, :type, :details, :name, :description]
@doc """
Converts list of UI actions to actions property.
Map in resulting list contains two properties:
* `action` - action (`topic`, `type`, `details`) encoded to JWT.
* `meta` - metadata (`name`, `description`) to be used in UI.
Resulting list of maps should be stored to some entity in asset map.
"""
@spec actions([t]) :: {:ok, [map]} | {:error, Joken.error_reason()}
def actions(ui_actions) when is_list(ui_actions) do
map_while_ok(ui_actions, &encode/1)
end
defp encode(action) do
with {:ok, token} <- UserAction.pack(action.topic, action.type, action.details) do
{:ok, %{action: token, meta: %{name: action.name, description: action.description}}}
end
end
end