# `MishkaBlog.Dashboard.Actions`
[🔗](https://github.com/mishka-group/mishka_blog/blob/v0.0.3-alpha.2/lib/mishka_blog/dashboard/actions.ex#L5)

The buttons an extension adds to the header of the blog dashboard, on the
`"blog:dashboard:actions"` mishka_installer event, as a card is added to the settings page on
`"account:security:cards"`. The blog adds none itself beyond its own, which the page draws.

An action is `%{id: String.t(), label: String.t(), icon: String.t(), priority: integer()}` plus
where it goes, one of:

  * `path: String.t()` — a link that navigates to that path of the admin;
  * `js: Phoenix.LiveView.JS.t()` — a button that runs that command when pressed, such as
    `JS.push("open_import", target: "#import-modal")`.

Low `priority` comes first, before the blog's own buttons. An action with a missing field, an `id`
already taken, or neither (or both) of `path` and `js` is dropped.

A plugin is handed `%{actions: [], current_user: user}` and answers `{:reply, %{actions: actions}}`
with its own added. It sees who is asking, so it may answer nothing for a user who may not use
its button.

    use MishkaInstaller.Event.Hook, event: "blog:dashboard:actions"

    def call(%{actions: actions} = data) do
      action = %{id: "import", label: "Import", icon: "hero-arrow-down-tray", priority: 10, path: "/admin/dashboard/import"}
      {:reply, %{data | actions: actions ++ [action]}}
    end

# `t`

```elixir
@type t() :: %{
  :id =&gt; String.t(),
  :label =&gt; String.t(),
  :icon =&gt; String.t(),
  :priority =&gt; integer(),
  optional(:path) =&gt; String.t(),
  optional(:js) =&gt; Phoenix.LiveView.JS.t()
}
```

# `collect`

```elixir
@spec collect(map() | nil) :: [t()]
```

The actions to draw for `user`, low priority first.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
