defmodule LiveDebuggerWeb.Components.Traces do
@moduledoc """
UI components for the TracesLive module.
"""
use LiveDebuggerWeb, :live_component
alias LiveDebugger.Structs.Trace
alias LiveDebuggerWeb.Components.ElixirDisplay
alias LiveDebugger.Utils.TermParser
alias LiveDebugger.Utils.Parsers
attr(:tracing_started?, :boolean, required: true)
def toggle_tracing_button(assigns) do
~H"""
<.button phx-click="switch-tracing" class="flex gap-2" size="sm">
<%= if @tracing_started? do %>
<.icon name="icon-stop" class="w-4 h-4" />
Stop
<% else %>
<.icon name="icon-play" class="w-3.5 h-3.5" />
Start
<% end %>
"""
end
def clear_button(assigns) do
~H"""
<.button phx-click="clear-traces" class="flex gap-2" variant="secondary" size="sm">
<.icon name="icon-trash" class="w-4 h-4" />
Clear
"""
end
def refresh_button(assigns) do
~H"""
<.button phx-click="refresh-history" class="flex gap-2" variant="secondary" size="sm">
<.icon name="icon-refresh" class="w-4 h-4" />
Refresh
"""
end
attr(:id, :string, required: true)
def separator(assigns) do
~H"""
"""
end
attr(:id, :string, required: true)
attr(:wrapped_trace, :map, required: true, doc: "The Trace to render")
def trace(assigns) do
assigns =
assigns
|> assign(:trace, assigns.wrapped_trace.trace)
|> assign(:render_body?, assigns.wrapped_trace.render_body?)
|> assign(:callback_name, Trace.callback_name(assigns.wrapped_trace.trace))
~H"""
<.collapsible
id={@id}
icon="icon-chevron-right"
chevron_class="w-5 h-5 text-accent-icon"
class="max-w-full border border-default-border rounded last:mb-4"
label_class="font-semibold bg-surface-1-bg h-10 p-2"
phx-click={if(@render_body?, do: nil, else: "toggle-collapsible")}
phx-value-trace-id={@trace.id}
>
<:label>
"-label"}
class="w-[90%] grow flex items-center ml-2 gap-1.5"
phx-update="ignore"
>
<%= @callback_name %>
<.short_trace_content trace={@trace} />
<%= Parsers.parse_timestamp(@trace.timestamp) %>
<.fullscreen_button
id={"trace-fullscreen-#{@id}"}
class="m-2"
phx-click="open-trace"
phx-value-data={@trace.id}
/>
<%= if @render_body? do %>
<%= for {args, index} <- Enum.with_index(@trace.args) do %>
"-#{index}"}
node={TermParser.term_to_display_tree(args)}
level={1}
/>
<% end %>
<% else %>
<.spinner size="sm" />
<% end %>
"""
end
def short_trace_content(assigns) do
assigns = assign(assigns, :content, Enum.map_join(assigns.trace.args, " ", &inspect/1))
~H"""
"""
end
attr(:id, :string, required: true)
attr(:trace, :map, default: nil)
def trace_fullscreen(assigns) do
assigns =
case assigns.trace do
nil ->
assigns
|> assign(:callback_name, "Unknown trace")
|> assign(:trace_args, [])
trace ->
assigns
|> assign(:callback_name, Trace.callback_name(trace))
|> assign(:trace_args, trace.args)
end
~H"""
<.fullscreen id={@id} title={@callback_name}>
<%= for {args, index} <- Enum.with_index(@trace_args) do %>
"-#{index}-fullscreen"}
node={TermParser.term_to_display_tree(args)}
level={1}
/>
<% end %>
"""
end
end