defmodule Integrations.Imap.Display do
@moduledoc """
Dashboard panel for `Integrations.Imap` (same package).
Nested under the monitor's own namespace deliberately — the package's
top-level module name never changes, and this module's name is
guaranteed distinct from any separately-published standalone display
package. `Display.BundledDefault` auto-hooks this whenever
`Integrations.Imap` starts, the same as if they were still one module.
"""
use CodeNameRaven.Display, category: :infrastructure, size_hint: :medium
@default_port 993
@impl true
def display_name, do: "IMAP"
@impl true
def compatible_monitors, do: [Integrations.Imap]
@impl true
def render(assigns) do
samples = CodeNameRaven.Runtime.recent_samples(assigns.config.id, limit: 120)
local_id = CodeNameRaven.Runtime.instance_id()
result = assigns[:result]
assigns = Map.merge(assigns, %{
samples: samples,
local_id: local_id,
result: result
})
~H"""
<%!-- Header --%>
<%= @config.name || imap_title(@config.params) %>
<%= @result && @result[:banner] %>
<%!-- Stats --%>
<.stat label="Latency" value={"#{@result.latency_ms} ms"} />
<.stat :if={@result[:auth_ok] == true} label="Auth" value="OK" />
<.stat :if={@result[:auth_ok] == false} label="Auth" value="Failed" />
<.stat :if={@result[:message_count]} label="Messages" value={"#{@result.message_count}"} />
<.stat :if={@result[:mailbox]} label="Mailbox" value={@result.mailbox} />
<%!-- Capability badges --%>
<%= cap %>
<%!-- Latency chart --%>
Checked <%= CodeNameRaven.Timezone.format_datetime(@last_checked_at, __MODULE__) %>
"""
end
# ---------------------------------------------------------------------------
# Private component
# ---------------------------------------------------------------------------
defp stat(assigns) do
~H"""
<%= @label %>
<%= @value %>
"""
end
# ---------------------------------------------------------------------------
# Render helpers
# ---------------------------------------------------------------------------
# Filter capabilities to those worth displaying
defp notable_capabilities(caps) do
notable = ~w[
IMAP4rev1 IMAP4rev2 IDLE MOVE UNSELECT QRESYNC CONDSTORE UIDPLUS
NAMESPACE LITERAL+ SASL-IR STARTTLS
AUTH=PLAIN AUTH=LOGIN AUTH=GSSAPI AUTH=NTLM AUTH=OAUTHBEARER AUTH=XOAUTH2
]
Enum.filter(caps, &(&1 in notable))
end
defp imap_title(params) do
host = params[:host] || params["host"] || "?"
port = parse_int(params[:port] || params["port"], @default_port)
"#{host}:#{port}"
end
defp parse_int(nil, default), do: default
defp parse_int(v, _) when is_integer(v), do: v
defp parse_int(v, default) when is_binary(v) do
case Integer.parse(v) do
{n, _} -> n
:error -> default
end
end
defp parse_int(_, default), do: default
end