From a5060eb09d446caa6a473d71fe0e9ad1c3f31b02 Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 12:31:35 +0100 Subject: [PATCH 01/11] Separate scrolls for pinned assigns and all assigns --- .../app/debugger/node_state/web/components.ex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/components.ex b/lib/live_debugger/app/debugger/node_state/web/components.ex index 67ee43b82..cddf152bd 100644 --- a/lib/live_debugger/app/debugger/node_state/web/components.ex +++ b/lib/live_debugger/app/debugger/node_state/web/components.ex @@ -59,14 +59,14 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do class="w-full h-max max-h-full overflow-y-auto" data-search_phrase={@assigns_search_phrase} > -
+
<.pinned_assigns_section id="pinned-" term_node={@term_node} pinned_assigns={@pinned_assigns} />
-
+
<.assigns_sizes_section assigns_sizes={@assigns_sizes} id="display-container-size-label" />
@@ -80,14 +80,14 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do />
-
+
<.pinned_assigns_section id="pinned-fullscreen-" term_node={@term_node} pinned_assigns={@pinned_assigns} />
-
+
<.assigns_sizes_section assigns_sizes={@assigns_sizes} id="display-fullscreen-size-label" />
From 352b058d0ab8fda44a49adfb7f6200d800549a01 Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 12:32:23 +0100 Subject: [PATCH 02/11] Long pinned assigns have fixed space size on the left --- lib/live_debugger/app/debugger/node_state/web/components.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/components.ex b/lib/live_debugger/app/debugger/node_state/web/components.ex index cddf152bd..dd14c0fd8 100644 --- a/lib/live_debugger/app/debugger/node_state/web/components.ex +++ b/lib/live_debugger/app/debugger/node_state/web/components.ex @@ -111,7 +111,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do :if={pinned} class="flex min-h-4.5 [&>div>button]:hidden hover:[&>div>button]:block" > -
+
-
+
<.assigns_sizes_section assigns_sizes={@assigns_sizes} id="display-container-size-label" /> - +
+ +
@@ -87,9 +89,11 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do pinned_assigns={@pinned_assigns} />
-
+
<.assigns_sizes_section assigns_sizes={@assigns_sizes} id="display-fullscreen-size-label" /> - +
+ +
From 7516e2d4b07a2f412fcd5ee9333e58c0cdbcbbd5 Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 12:46:49 +0100 Subject: [PATCH 04/11] Adjusted section title size for assigns --- lib/live_debugger/app/debugger/node_state/web/components.ex | 2 +- lib/live_debugger/app/web/components.ex | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/components.ex b/lib/live_debugger/app/debugger/node_state/web/components.ex index e46ceb091..356811bdb 100644 --- a/lib/live_debugger/app/debugger/node_state/web/components.ex +++ b/lib/live_debugger/app/debugger/node_state/web/components.ex @@ -42,7 +42,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do ~H"""
- <.section id="assigns" class="h-max overflow-y-hidden" title="Assigns"> + <.section id="assigns" class="h-max overflow-y-hidden" title="Assigns" title_class="!min-w-14"> <:right_panel>
-
<%= @title %>
+
<%= @title %>
<%= render_slot(@right_panel) %>
From e870a62c43cf31daba0ee0bd801961ead918fd0a Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 15:41:18 +0100 Subject: [PATCH 05/11] Extended async loading for assigns --- .../debugger/node_state/web/hooks/node_assigns.ex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex b/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex index 3e7f2dcc0..9b9b3609b 100644 --- a/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex +++ b/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex @@ -30,8 +30,8 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Hooks.NodeAssigns do |> attach_hook(:node_assigns, :handle_async, &handle_async/3) |> attach_hook(:node_assigns, :handle_event, &handle_event/3) |> register_hook(:node_assigns) - |> assign(:node_assigns_info, AsyncResult.loading()) - |> assign(:assigns_sizes, AsyncResult.loading()) + |> assign(:node_assigns_info, AsyncResult.loading(%{stage: :init})) + |> assign(:assigns_sizes, AsyncResult.loading(%{stage: :init})) |> assign(:pinned_assigns, %{}) |> put_private(:pulse_cleared?, true) |> assign_async_node_assigns() @@ -55,16 +55,16 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Hooks.NodeAssigns do when not is_nil(node_id) do node_assigns_info = if Keyword.get(opts, :reset, false) do - AsyncResult.loading() + AsyncResult.loading(stage: :initial) else - socket.assigns.node_assigns_info + AsyncResult.loading(socket.assigns.node_assigns_info, stage: :update) end assigns_sizes = if Keyword.get(opts, :reset, false) do - AsyncResult.loading() + AsyncResult.loading(stage: :initial) else - socket.assigns.assigns_sizes + AsyncResult.loading(socket.assigns.assigns_sizes, stage: :update) end socket From c640b9123c0514b5d96f83b97ca645bb3d2448c2 Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 15:41:54 +0100 Subject: [PATCH 06/11] Fix assigns sizes async result stage initialization --- .../app/debugger/node_state/web/hooks/node_assigns.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex b/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex index 9b9b3609b..ac8f119bd 100644 --- a/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex +++ b/lib/live_debugger/app/debugger/node_state/web/hooks/node_assigns.ex @@ -30,8 +30,8 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Hooks.NodeAssigns do |> attach_hook(:node_assigns, :handle_async, &handle_async/3) |> attach_hook(:node_assigns, :handle_event, &handle_event/3) |> register_hook(:node_assigns) - |> assign(:node_assigns_info, AsyncResult.loading(%{stage: :init})) - |> assign(:assigns_sizes, AsyncResult.loading(%{stage: :init})) + |> assign(:node_assigns_info, AsyncResult.loading(stage: :init)) + |> assign(:assigns_sizes, AsyncResult.loading(stage: :init)) |> assign(:pinned_assigns, %{}) |> put_private(:pulse_cleared?, true) |> assign_async_node_assigns() From 77b1ae64b43be131ca167858f09e93e62330c4dd Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 15:42:23 +0100 Subject: [PATCH 07/11] Added colors for status dot --- assets/app/styles/themes/dark.css | 4 ++++ assets/app/styles/themes/light.css | 4 ++++ assets/app/tailwind.config.js | 3 +++ 3 files changed, 11 insertions(+) diff --git a/assets/app/styles/themes/dark.css b/assets/app/styles/themes/dark.css index 4957a6cf8..5ad888aa3 100644 --- a/assets/app/styles/themes/dark.css +++ b/assets/app/styles/themes/dark.css @@ -90,5 +90,9 @@ --diff-pulse-text: var(--gray-900); --diff-negative-bg: var(--red-900); --diff-positive-bg: rgb(from var(--swm-green-100) r g b / 0.3); + + --status-dot-success-bg: var(--swm-green-100); + --status-dot-warning-bg: var(--swm-yellow-100); + --status-dot-error-bg: var(--swm-pink-100); } } diff --git a/assets/app/styles/themes/light.css b/assets/app/styles/themes/light.css index 6a7aa49ef..62492ee2b 100644 --- a/assets/app/styles/themes/light.css +++ b/assets/app/styles/themes/light.css @@ -89,4 +89,8 @@ --diff-pulse-text: var(--slate-900); --diff-negative-bg: var(--red-300); --diff-positive-bg: var(--swm-green-60); + + --status-dot-success-bg: var(--swm-green-100); + --status-dot-warning-bg: var(--swm-yellow-100); + --status-dot-error-bg: var(--swm-pink-100); } diff --git a/assets/app/tailwind.config.js b/assets/app/tailwind.config.js index eb550b51d..0ddc8e2a8 100644 --- a/assets/app/tailwind.config.js +++ b/assets/app/tailwind.config.js @@ -69,6 +69,9 @@ module.exports = { 'diff-border': 'var(--diff-border)', 'diff-negative-bg': 'var(--diff-negative-bg)', 'diff-positive-bg': 'var(--diff-positive-bg)', + 'status-dot-success-bg': 'var(--status-dot-success-bg)', + 'status-dot-warning-bg': 'var(--status-dot-warning-bg)', + 'status-dot-error-bg': 'var(--status-dot-error-bg)', }, screens: { xs: '380px' }, fontFamily: { From 2d35b4a9ed22bc4f8c6b5dd5e816cb2c5378ec29 Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 15:42:59 +0100 Subject: [PATCH 08/11] Status dot component --- .../app/debugger/node_state/web/components.ex | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/live_debugger/app/debugger/node_state/web/components.ex b/lib/live_debugger/app/debugger/node_state/web/components.ex index 356811bdb..913830b4e 100644 --- a/lib/live_debugger/app/debugger/node_state/web/components.ex +++ b/lib/live_debugger/app/debugger/node_state/web/components.ex @@ -213,4 +213,29 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do
""" end + + attr(:status, :atom, required: true) + attr(:pulse?, :boolean, default: false) + + def status_dot(assigns) do + assigns = + case assigns.status do + :success -> assign(assigns, :bg_class, "bg-status-dot-success-bg") + :warning -> assign(assigns, :bg_class, "bg-status-dot-warning-bg") + :error -> assign(assigns, :bg_class, "bg-status-dot-error-bg") + end + + ~H""" + <.tooltip id="loading-dot-tooltip" content="Updating assigns sizes"> + + + + + + + """ + end end From 4d9684ad4f95d8e666f53b6b3113a8dc550010cc Mon Sep 17 00:00:00 2001 From: kraleppa Date: Tue, 25 Nov 2025 16:03:50 +0100 Subject: [PATCH 09/11] Added status dot --- .../app/debugger/node_state/web/components.ex | 25 ++++++++++++++++--- .../node_state/web/node_state_live.ex | 1 + lib/live_debugger/app/web/components.ex | 9 ++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/components.ex b/lib/live_debugger/app/debugger/node_state/web/components.ex index 913830b4e..ee7351ad0 100644 --- a/lib/live_debugger/app/debugger/node_state/web/components.ex +++ b/lib/live_debugger/app/debugger/node_state/web/components.ex @@ -33,6 +33,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do attr(:assigns_sizes, AsyncResult, required: true) attr(:assigns_search_phrase, :string, default: "") attr(:pinned_assigns, :map, default: %{}) + attr(:node_assigns_loading_status, :list, required: true) def assigns_section(assigns) do opened_term_node = @@ -42,7 +43,15 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do ~H"""
- <.section id="assigns" class="h-max overflow-y-hidden" title="Assigns" title_class="!min-w-14"> + <.section id="assigns" class="h-max overflow-y-hidden" title="Assigns" title_class="!min-w-18"> + <:title_sub_panel> + <.status_dot + status={status_dot_status(@node_assigns_loading_status)} + pulse?={status_dot_pulse?(@node_assigns_loading_status)} + tooltip={status_dot_tooltip(@node_assigns_loading_status)} + /> + + <:right_panel>
assign(assigns, :bg_class, "bg-status-dot-success-bg") @@ -226,7 +236,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do end ~H""" - <.tooltip id="loading-dot-tooltip" content="Updating assigns sizes"> + <.tooltip id="loading-dot-tooltip" content={@tooltip}> """ end + + defp status_dot_status(stage: :update), do: :warning + defp status_dot_status(_), do: :success + + defp status_dot_pulse?(stage: :update), do: true + defp status_dot_pulse?(_), do: false + + defp status_dot_tooltip(stage: :update), do: "Updating assigns..." + defp status_dot_tooltip(_), do: "Assigns are up to date." end diff --git a/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex b/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex index 844096e6f..e91b6441a 100644 --- a/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex +++ b/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex @@ -89,6 +89,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.NodeStateLive do assigns_sizes={@assigns_sizes} pinned_assigns={@pinned_assigns} assigns_search_phrase={@assigns_search_phrase} + node_assigns_loading_status={@node_assigns_info.loading} />
-
<%= @title %>
+
+

<%= @title %>

+ <%= render_slot(@title_sub_panel) %> +
<%= render_slot(@right_panel) %>
From 07c8fda61bc22ae22dc71a1f887f598d888e0377 Mon Sep 17 00:00:00 2001 From: kraleppa Date: Thu, 27 Nov 2025 13:05:33 +0100 Subject: [PATCH 10/11] Red dot in case of DeadView mode or error --- .../app/debugger/node_state/web/components.ex | 51 +++++++------------ .../node_state/web/node_state_live.ex | 16 +++++- lib/live_debugger/app/web/components.ex | 30 +++++++++++ 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/components.ex b/lib/live_debugger/app/debugger/node_state/web/components.ex index ee7351ad0..3ff5f98f6 100644 --- a/lib/live_debugger/app/debugger/node_state/web/components.ex +++ b/lib/live_debugger/app/debugger/node_state/web/components.ex @@ -33,7 +33,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do attr(:assigns_sizes, AsyncResult, required: true) attr(:assigns_search_phrase, :string, default: "") attr(:pinned_assigns, :map, default: %{}) - attr(:node_assigns_loading_status, :list, required: true) + attr(:node_assigns_status, :atom, required: true) def assigns_section(assigns) do opened_term_node = @@ -45,11 +45,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do
<.section id="assigns" class="h-max overflow-y-hidden" title="Assigns" title_class="!min-w-18"> <:title_sub_panel> - <.status_dot - status={status_dot_status(@node_assigns_loading_status)} - pulse?={status_dot_pulse?(@node_assigns_loading_status)} - tooltip={status_dot_tooltip(@node_assigns_loading_status)} - /> + <.assigns_status_indicator node_assigns_status={@node_assigns_status} /> <:right_panel> @@ -223,38 +219,29 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.Components do """ end - attr(:status, :atom, required: true) - attr(:pulse?, :boolean, default: false) - attr(:tooltip, :string, required: true) + attr(:node_assigns_status, :atom, required: true) - defp status_dot(assigns) do - assigns = - case assigns.status do - :success -> assign(assigns, :bg_class, "bg-status-dot-success-bg") - :warning -> assign(assigns, :bg_class, "bg-status-dot-warning-bg") - :error -> assign(assigns, :bg_class, "bg-status-dot-error-bg") - end + defp assigns_status_indicator(assigns) do + assigns = assign(assigns, get_status_indicator_params(assigns.node_assigns_status)) ~H""" - <.tooltip id="loading-dot-tooltip" content={@tooltip}> - - - - - - + <.status_dot status={@status} pulse?={@pulse?} tooltip={@tooltip} /> """ end - defp status_dot_status(stage: :update), do: :warning - defp status_dot_status(_), do: :success + defp get_status_indicator_params(:updating) do + [status: :warning, pulse?: true, tooltip: "Updating assigns..."] + end - defp status_dot_pulse?(stage: :update), do: true - defp status_dot_pulse?(_), do: false + defp get_status_indicator_params(:loaded) do + [status: :success, pulse?: false, tooltip: "Assigns are up to date."] + end + + defp get_status_indicator_params(:error) do + [status: :error, pulse?: false, tooltip: "Error while fetching assigns."] + end - defp status_dot_tooltip(stage: :update), do: "Updating assigns..." - defp status_dot_tooltip(_), do: "Assigns are up to date." + defp get_status_indicator_params(:disconnected) do + [status: :error, pulse?: false, tooltip: "Disconnected from the LiveView process."] + end end diff --git a/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex b/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex index e91b6441a..0fb8a2af8 100644 --- a/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex +++ b/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex @@ -13,8 +13,11 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.NodeStateLive do alias LiveDebugger.Bus alias LiveDebugger.App.Debugger.Events.NodeIdParamChanged + alias LiveDebugger.App.Debugger.Events.DeadViewModeEntered alias LiveDebugger.Services.CallbackTracer.Events.StateChanged + alias Phoenix.LiveView.AsyncResult + @doc """ Renders the `NodeStateLive` as a nested LiveView component. @@ -89,7 +92,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.NodeStateLive do assigns_sizes={@assigns_sizes} pinned_assigns={@pinned_assigns} assigns_search_phrase={@assigns_search_phrase} - node_assigns_loading_status={@node_assigns_info.loading} + node_assigns_status={assigns_status(@lv_process, @node_assigns_info)} /> noreply() end + def handle_info(%DeadViewModeEntered{debugger_pid: pid}, socket) do + socket + |> assign(:lv_process, LvProcess.set_alive(socket.assigns.lv_process, false)) + |> noreply() + end + def handle_info(_, socket), do: {:noreply, socket} + + defp assigns_status(%LvProcess{alive?: false}, _), do: :disconnected + defp assigns_status(_, %AsyncResult{loading: [stage: :update]}), do: :updating + defp assigns_status(_, %AsyncResult{ok?: true}), do: :loaded + defp assigns_status(_, _), do: :error end diff --git a/lib/live_debugger/app/web/components.ex b/lib/live_debugger/app/web/components.ex index 23c532d0d..8186e7581 100644 --- a/lib/live_debugger/app/web/components.ex +++ b/lib/live_debugger/app/web/components.ex @@ -631,6 +631,36 @@ defmodule LiveDebugger.App.Web.Components do """ end + @doc """ + Renders a status dot with a tooltip. + """ + + attr(:status, :atom, required: true) + attr(:pulse?, :boolean, default: false) + attr(:tooltip, :string, required: true) + + def status_dot(assigns) do + assigns = + case assigns.status do + :success -> assign(assigns, :bg_class, "bg-status-dot-success-bg") + :warning -> assign(assigns, :bg_class, "bg-status-dot-warning-bg") + :error -> assign(assigns, :bg_class, "bg-status-dot-error-bg") + end + + ~H""" + <.tooltip id="loading-dot-tooltip" content={@tooltip}> + + + + + + + """ + end + @doc """ Renders a tooltip using Tooltip hook. """ From 5dc6554b179df104b17637f9e8454f59b2e008b4 Mon Sep 17 00:00:00 2001 From: kraleppa Date: Thu, 27 Nov 2025 13:14:06 +0100 Subject: [PATCH 11/11] Removed warning --- .../app/debugger/node_state/web/node_state_live.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex b/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex index 0fb8a2af8..37558f20e 100644 --- a/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex +++ b/lib/live_debugger/app/debugger/node_state/web/node_state_live.ex @@ -135,7 +135,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.NodeStateLive do |> noreply() end - def handle_info(%DeadViewModeEntered{debugger_pid: pid}, socket) do + def handle_info(%DeadViewModeEntered{}, socket) do socket |> assign(:lv_process, LvProcess.set_alive(socket.assigns.lv_process, false)) |> noreply()