Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions lib/live_debugger_web/components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ defmodule LiveDebuggerWeb.Components do

use Phoenix.Component

import Phoenix.HTML

alias Phoenix.LiveView.JS
alias LiveDebuggerWeb.Helpers.RoutesHelper

Expand Down Expand Up @@ -72,6 +74,50 @@ defmodule LiveDebuggerWeb.Components do
"""
end

@doc """
Renders an input with label.
"""
attr(:field, Phoenix.HTML.FormField, required: true)
attr(:label_text, :string, default: nil)
attr(:label_raw, :boolean, default: false)
attr(:type, :string, default: "text")

attr(:wrapper_class, :any, default: nil)
attr(:input_class, :any, default: nil)
attr(:label_class, :any, default: nil)
attr(:rest, :global, include: ~w(min max))

def input(assigns) do
assigns =
assigns
|> assign(:errors, assigns.field.errors)

~H"""
<div phx-feedback-for={@field.name} class={["" | List.wrap(@wrapper_class)]}>
<label for={@field.id} class={["block font-medium text-xs" | List.wrap(@label_class)]}>
Comment thread
hhubert6 marked this conversation as resolved.
<%= if @label_raw, do: raw(@label_text), else: @label_text %>
</label>
<input
type={@type}
name={@field.name}
id={@field.id}
value={Phoenix.HTML.Form.normalize_value(@type, @field.value)}
class={[
"mt-2 block w-full rounded-lg bg-surface-1-bg focus:ring-0 text-xs",
"phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400",
@errors == [] && "border-default-border focus:border-secondary-text",
@errors != [] && "border-error-text focus:border-error-text"
| List.wrap(@input_class)
]}
{@rest}
/>
<p :for={msg <- @errors} class="mt-2 block text-error-text">
<%= msg %>
</p>
</div>
"""
end

@doc """
Renders a button.

Expand Down
4 changes: 2 additions & 2 deletions lib/live_debugger_web/helpers/tracing_helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ defmodule LiveDebuggerWeb.Helpers.TracingHelper do
lv_process = socket.assigns.lv_process
node_id = socket.assigns.node_id

socket.assigns.current_filters
socket.assigns.current_filters.functions
|> Enum.filter(fn {_, active?} -> active? end)
|> Enum.flat_map(fn {function, _} ->
[
Expand All @@ -164,7 +164,7 @@ defmodule LiveDebuggerWeb.Helpers.TracingHelper do
lv_process = socket.assigns.lv_process
node_id = socket.assigns.node_id

socket.assigns.current_filters
socket.assigns.current_filters.functions
|> Enum.map(fn {function, _} ->
PubSubUtils.tsnf_topic(
lv_process.socket_id,
Expand Down
25 changes: 17 additions & 8 deletions lib/live_debugger_web/live/traces_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -398,17 +398,26 @@ defmodule LiveDebuggerWeb.TracesLive do
end

defp default_filters(node_id) do
node_id
|> TreeNode.type()
|> case do
:live_view -> UtilsCallbacks.live_view_callbacks()
:live_component -> UtilsCallbacks.live_component_callbacks()
end
|> Enum.map(fn {function, _} -> {function, true} end)
functions =
node_id
|> TreeNode.type()
|> case do
:live_view -> UtilsCallbacks.live_view_callbacks()
:live_component -> UtilsCallbacks.live_component_callbacks()
end
|> Enum.map(fn {function, _} -> {function, true} end)

%{
functions: functions,
execution_time: [
{:exec_time_max, ""},
{:exec_time_min, "0"}
]
}
end

defp get_active_functions(socket) do
socket.assigns.current_filters
socket.assigns.current_filters.functions
|> Enum.filter(fn {_, active?} -> active? end)
|> Enum.map(fn {function, _} -> function end)
end
Expand Down
83 changes: 66 additions & 17 deletions lib/live_debugger_web/live_components/filters_form.ex
Comment thread
hhubert6 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ defmodule LiveDebuggerWeb.LiveComponents.FiltersForm do

@impl true
def render(assigns) do
assigns = assign(assigns, :selected_filters_number, calculate_selected_filters(assigns.form))
assigns =
assign(assigns, :selected_filters_number, calculate_selected_filters(assigns.form))

~H"""
<div id={@id <> "-wrapper"}>
Expand All @@ -34,6 +35,23 @@ defmodule LiveDebuggerWeb.LiveComponents.FiltersForm do
<.checkbox field={@form[function]} label={"#{function}/#{arity}"} />
<% end %>
</div>
<p class="font-medium mb-4 mt-6">Callback execution time</p>
<div class="flex flex-col gap-3">
<.input
label_text="max [&micro;s]"
label_raw
field={@form[:exec_time_max]}
type="number"
min="0"
/>
<.input
label_text="min [&micro;s]"
label_raw
field={@form[:exec_time_min]}
type="number"
min="0"
/>
</div>
</div>
<div class="flex py-3 px-4 border-t border-default-border items-center justify-between">
<button
Expand All @@ -59,20 +77,31 @@ defmodule LiveDebuggerWeb.LiveComponents.FiltersForm do

@impl true
def handle_event("submit", params, socket) do
filters = update_filters(socket.assigns.active_filters, params)
case update_filters(socket.assigns.active_filters, params) do
{:ok, filters} ->
send(self(), {:filters_updated, filters})

send(self(), {:filters_updated, filters})
_ ->
nil
end

{:noreply, socket}
socket
|> noreply()
end

@impl true
def handle_event("change", params, socket) do
filters = update_filters(socket.assigns.active_filters, params)
case update_filters(socket.assigns.active_filters, params) do
{:ok, filters} ->
socket
|> assign_form(filters)
|> noreply()

socket
|> assign_form(filters)
|> noreply()
{:error, errors} ->
socket
|> assign(form: to_form(params, errors: errors))
|> noreply()
end
end

@impl true
Expand All @@ -82,11 +111,11 @@ defmodule LiveDebuggerWeb.LiveComponents.FiltersForm do
|> noreply()
end

def assign_form(socket, filters) do
def assign_form(socket, %{functions: functions, execution_time: execution_time}) do
form =
filters
|> Enum.reduce(%{}, fn {function, active}, acc ->
Map.put(acc, Atom.to_string(function), active)
(functions ++ execution_time)
|> Enum.reduce(%{}, fn {filter, value}, acc ->
Map.put(acc, Atom.to_string(filter), value)
end)
|> to_form()

Expand All @@ -103,15 +132,35 @@ defmodule LiveDebuggerWeb.LiveComponents.FiltersForm do
end

defp update_filters(active_filters, params) do
active_filters
|> Enum.map(fn {function, _} ->
{function, Map.has_key?(params, Atom.to_string(function))}
end)
functions =
active_filters.functions
|> Enum.map(fn {function, _} ->
{function, Map.has_key?(params, Atom.to_string(function))}
end)

execution_time =
active_filters.execution_time
|> Enum.map(fn {filter, value} ->
{filter, Map.get(params, Atom.to_string(filter), value)}
end)

min_time = Keyword.get(execution_time, :exec_time_min, 0)
max_time = Keyword.get(execution_time, :exec_time_max, :infinity)

if String.to_integer(min_time) > String.to_integer(max_time) do
{:error, [exec_time_min: "min must be less than max", exec_time_max: ""]}
else
{:ok, %{functions: functions, execution_time: execution_time}}
end
end

defp calculate_selected_filters(form) do
callbacks =
UtilsCallbacks.callbacks_functions()
|> Enum.map(&Atom.to_string/1)

form.params
|> Map.values()
|> Enum.filter(fn {name, value} -> Enum.member?(callbacks, name) && value end)
|> Enum.count(&Function.identity/1)
end
end