Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.Components.TraceSettings do
@moduledoc """
UI components for trace settings.
"""
use LiveDebugger.App.Web, :component

alias LiveDebugger.App.Web.LiveComponents.LiveDropdown
alias LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents

attr(:class, :any, default: nil, doc: "Additional classes to add to the navigation bar.")
attr(:current_filters, :map, required: true)
attr(:id, :string, required: true)

def node_traces_dropdown_menu(assigns) do
~H"""
<.live_component module={LiveDropdown} id={@id} class={@class} direction={:bottom_left}>
<:button>
<.dropdown_button />
</:button>
<div class="min-w-44 flex flex-col">
<HookComponents.RefreshButton.render display_mode={:dropdown} />

<HookComponents.ClearButton.render display_mode={:dropdown} />

<HookComponents.FiltersFullscreen.filters_button
current_filters={@current_filters}
display_mode={:dropdown}
/>
</div>
</.live_component>
"""
end

attr(:class, :any, default: nil, doc: "Additional classes to add to the navigation bar.")

def global_traces_dropdown_menu(assigns) do
~H"""
<.live_component
module={LiveDropdown}
id="tracing-options-dropdown"
class={@class}
direction={:bottom_left}
>
<:button>
<.dropdown_button />
</:button>
<div class="min-w-44 flex flex-col">
<HookComponents.RefreshButton.render display_mode={:dropdown} />
<HookComponents.ClearButton.render display_mode={:dropdown} />
</div>
</.live_component>
"""
end

attr(:icon, :string, required: true)
attr(:label, :string, required: true)

def dropdown_item(assigns) do
~H"""
<div class="flex gap-1.5 p-2 rounded items-center w-full">
<.icon name={@icon} class="w-4 h-4" />
<span>{@label}</span>
</div>
"""
end

attr(:display_mode, :atom, required: true)
attr(:id, :string, required: true)
attr(:content, :string, required: true)
attr(:position, :string, default: "top-center")

slot(:inner_block, required: true)

def maybe_add_tooltip(assigns) do
~H"""
<%= if @display_mode == :normal do %>
<.tooltip id={@id} content={@content} position={@position}>
<%= render_slot(@inner_block) %>
</.tooltip>
<% else %>
<%= render_slot(@inner_block) %>
<% end %>
"""
end

attr(:display_mode, :atom, required: true)
attr(:icon, :string, required: true)
attr(:label, :string, default: nil)

def action_icon(assigns) do
~H"""
<%= if @display_mode == :normal do %>
<.icon name={@icon} class="w-4 h-4" />
<% else %>
<.dropdown_item icon={@icon} label={@label} />
<% end %>
"""
end

defp dropdown_button(assigns) do
~H"""
<.nav_icon
icon="icon-chevrons-right"
class="border-button-secondary-border border hover:border-button-secondary-border-hover !w-7 !h-7 px-[0.2rem] py-[0.2rem]"
icon_class="!h-4 !w-4"
/>
"""
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
use LiveDebugger.App.Web, :live_view

import LiveDebugger.App.Debugger.CallbackTracing.Web.Components.Trace
import LiveDebugger.App.Debugger.CallbackTracing.Web.Components.TraceSettings

alias LiveDebugger.App.Debugger.CallbackTracing.Web.Assigns.Filters, as: FiltersAssigns
alias LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents
Expand Down Expand Up @@ -121,8 +122,12 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
lv_process_alive?={@lv_process.alive?}
/>
<%= if not @tracing_started? do %>
<HookComponents.RefreshButton.render label_class="hidden @[30rem]/traces:block" />
<HookComponents.ClearButton.render label_class="hidden @[30rem]/traces:block" />
<.global_traces_dropdown_menu class="@[30rem]/traces:hidden" />

<div class="hidden @[30rem]/traces:flex gap-2">
<HookComponents.RefreshButton.render display_mode={:normal} />
<HookComponents.ClearButton.render display_mode={:normal} />
</div>
<% end %>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.ClearButt
use LiveDebugger.App.Web, :hook_component

alias LiveDebugger.API.TracesStorage
alias LiveDebugger.App.Debugger.CallbackTracing.Web.Components.TraceSettings

@required_assigns [:lv_process, :traces_empty?, :node_id]

Expand All @@ -20,27 +21,37 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.ClearButt
end

attr(:label_class, :string, default: "")
attr(:display_mode, :atom, required: true, values: [:normal, :dropdown])

@impl true
def render(assigns) do
~H"""
<.button
phx-click="clear-traces"
aria-label="Clear traces"
class="flex gap-2"
variant="secondary"
size="sm"
<TraceSettings.maybe_add_tooltip
display_mode={@display_mode}
id="clear-tooltip"
content="Clear"
position="top-center"
>
<.icon name="icon-trash" class="w-4 h-4" />
<div class={[@label_class, "ml-1"]}>
Clear
</div>
</.button>
<.button
phx-click="clear-traces"
aria-label="Clear traces"
class={[
"flex !w-7 !h-7 px-[0.2rem] py-[0.2rem] items-center justify-center",
@label_class,
@display_mode == :dropdown && "!w-full !border-none !h-full"
]}
variant="secondary"
size="sm"
>
<TraceSettings.action_icon display_mode={@display_mode} icon="icon-trash" label="Clear" />
</.button>
</TraceSettings.maybe_add_tooltip>
"""
end

defp handle_event("clear-traces", _, socket) do
TracesStorage.clear!(socket.assigns.lv_process.pid, socket.assigns.node_id)
LiveDebugger.App.Web.LiveComponents.LiveDropdown.close("tracing-options-dropdown")

socket
|> stream(:existing_traces, [], reset: true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.FiltersFu
alias LiveDebugger.App.Debugger.CallbackTracing.Web.LiveComponents.FiltersForm
alias LiveDebugger.App.Debugger.CallbackTracing.Web.Helpers.Filters, as: FiltersHelpers

alias LiveDebugger.App.Debugger.CallbackTracing.Web.Components.TraceSettings
@required_assigns [:current_filters, :node_id]

@fullscreen_id "filters-fullscreen"
Expand Down Expand Up @@ -51,6 +52,7 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.FiltersFu
attr(:current_filters, :map, required: true)
attr(:node_id, :any, default: nil)
attr(:label_class, :string, default: "")
attr(:display_mode, :atom, required: true, values: [:normal, :dropdown])

def filters_button(assigns) do
filters_number =
Expand All @@ -62,19 +64,31 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.FiltersFu

~H"""
<div class="flex">
<.button
variant="secondary"
aria-label="Open filters"
size="sm"
class={["flex gap-1", if(@applied_filters_number > 0, do: "rounded-r-none")]}
phx-click="open-filters"
<TraceSettings.maybe_add_tooltip
display_mode={@display_mode}
id="filters-tooltip"
content="Filters"
position="top-center"
>
<.icon name="icon-filters" class="w-4 h-4" />
<span class={["ml-1", @label_class]}>Filters</span>
<span :if={@applied_filters_number > 0}>
(<%= @applied_filters_number %>)
</span>
</.button>
<.button
variant="secondary"
aria-label="Open filters"
size="sm"
class={[
"flex !w-7 !h-7 px-[0.2rem] py-[0.2rem] items-center justify-center",
if(@applied_filters_number > 0, do: "rounded-r-none"),
@label_class,
@display_mode == :dropdown && "!w-full !border-none !h-full"
]}
phx-click="open-filters"
>
<TraceSettings.action_icon display_mode={@display_mode} icon="icon-filters" label="Filters" />

<span :if={@applied_filters_number > 0}>
(<%= @applied_filters_number %>)
</span>
</.button>
</TraceSettings.maybe_add_tooltip>
<.icon_button
:if={@applied_filters_number > 0}
icon="icon-cross"
Expand Down Expand Up @@ -102,6 +116,8 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.FiltersFu
reset_form?: true
)

LiveDebugger.App.Web.LiveComponents.LiveDropdown.close("tracing-options-dropdown")

socket
|> push_event("#{@fullscreen_id}-open", %{})
|> halt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.RefreshBu
use LiveDebugger.App.Web, :hook_component

alias LiveDebugger.App.Debugger.CallbackTracing.Web.Hooks
alias LiveDebugger.App.Debugger.CallbackTracing.Web.Components.TraceSettings

@impl true
def init(socket) do
Expand All @@ -17,26 +18,37 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.RefreshBu
end

attr(:label_class, :string, default: "")
attr(:display_mode, :atom, required: true, values: [:normal, :dropdown])

@impl true
def render(assigns) do
~H"""
<.button
phx-click="refresh-history"
aria-label="Refresh traces"
class="flex gap-2"
variant="secondary"
size="sm"
<TraceSettings.maybe_add_tooltip
display_mode={@display_mode}
id="refresh-tooltip"
content="Refresh"
position="top-center"
>
<.icon name="icon-refresh" class="w-4 h-4" />
<div class={@label_class}>
Refresh
</div>
</.button>
<.button
phx-click="refresh-history"
aria-label="Refresh traces"
class={[
"flex !w-7 !h-7 px-[0.2rem] py-[0.2rem] items-center justify-center",
@label_class,
@display_mode == :dropdown && "!w-full !border-none !h-full"
]}
variant="secondary"
size="sm"
>
<TraceSettings.action_icon display_mode={@display_mode} icon="icon-refresh" label="Refresh" />
</.button>
</TraceSettings.maybe_add_tooltip>
"""
end

defp handle_event("refresh-history", _, socket) do
LiveDebugger.App.Web.LiveComponents.LiveDropdown.close("tracing-options-dropdown")

socket
|> Hooks.ExistingTraces.assign_async_existing_traces()
|> halt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.HookComponents.ToggleTra
@impl true
def render(assigns) do
~H"""
<.button phx-click="switch-tracing" class="flex gap-2" size="sm" disabled={!@lv_process_alive?}>
<div class="flex gap-1.5 items-center w-12">
<%= if @tracing_started? do %>
<.icon name="icon-stop" class="w-4 h-4" />
<div>Stop</div>
<% else %>
<.icon name="icon-play" class="w-3.5 h-3.5" />
<div>Start</div>
<% end %>
</div>
</.button>
<.tooltip
id="tracing-tooltip"
content={if @tracing_started?, do: "Stop", else: "Start"}
position="top-center"
>
<.button
phx-click="switch-tracing"
class="flex w-7! h-7! px-[0.2rem] py-[0.2rem] items-center justify-center"
size="sm"
disabled={!@lv_process_alive?}
>
<.icon name={if @tracing_started?, do: "icon-stop", else: "icon-play"} class="w-4 h-4" />
</.button>
</.tooltip>
"""
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.NodeTracesLive do
alias LiveDebugger.App.Debugger.Events.NodeIdParamChanged

import LiveDebugger.App.Debugger.CallbackTracing.Web.Components.Trace
import LiveDebugger.App.Debugger.CallbackTracing.Web.Components.TraceSettings

@live_stream_limit 128
@page_size 25
Expand Down Expand Up @@ -99,23 +100,33 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.NodeTracesLive do
<div class="max-w-full @container/traces flex flex-1">
<.section title="Callback traces" id="traces" inner_class="mx-0 my-4 px-4" class="flex-1">
<:right_panel>
<div class="flex gap-2 items-center">
<div class="flex gap-2 !h-7">
<HookComponents.SearchInput.render
disabled?={@tracing_started?}
trace_search_phrase={@trace_search_phrase}
class="h-7! w-full! @[47rem]/traces:w-64!"
/>

<HookComponents.ToggleTracingButton.render
tracing_started?={@tracing_started?}
lv_process_alive?={@lv_process.alive?}
/>

<%= if not @tracing_started? do %>
<HookComponents.RefreshButton.render label_class="hidden @[40rem]/traces:block" />
<HookComponents.ClearButton.render label_class="hidden @[40rem]/traces:block" />
<HookComponents.FiltersFullscreen.filters_button
label_class="hidden @[40rem]/traces:block"
<.node_traces_dropdown_menu
id="tracing-options-dropdown"
class="@[30rem]/traces:hidden"
current_filters={@current_filters}
/>

<div class="hidden @[30rem]/traces:flex gap-2">
<HookComponents.RefreshButton.render display_mode={:normal} />
<HookComponents.ClearButton.render display_mode={:normal} />
<HookComponents.FiltersFullscreen.filters_button
current_filters={@current_filters}
display_mode={:normal}
/>
</div>
<% end %>
</div>
</:right_panel>
Expand Down
Loading