Skip to content

Commit 46ce84a

Browse files
authored
Refactor: Update layout of LiveDebugger (#859)
* change monitored pid style * layout updates * change sidebar orientation * update sidebar menu * move node basic info * move dropdown to new sidebar * change disconnected state indicator * move parent pid section * update parent live view link and fix e2e tests
1 parent 67e9df8 commit 46ce84a

File tree

16 files changed

+425
-228
lines changed

16 files changed

+425
-228
lines changed

assets/app/styles/themes/dark.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,14 @@
9393
--diff-negative-bg: var(--red-900);
9494
--diff-positive-bg: rgb(from var(--swm-green-100) r g b / 0.3);
9595

96+
--monitored-pid-bg: var(--swm-green-60);
97+
--disconnected-bg: var(--swm-pink-60);
98+
--disconnected-text: var(--slate-900);
99+
96100
--status-dot-success-bg: var(--swm-green-100);
97101
--status-dot-warning-bg: var(--swm-yellow-100);
98102
--status-dot-error-bg: var(--swm-pink-100);
103+
104+
--navbar-selected-bg: var(--swm-sea-blue-60);
99105
}
100106
}

assets/app/styles/themes/light.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,13 @@
9292
--diff-negative-bg: var(--red-300);
9393
--diff-positive-bg: var(--swm-green-60);
9494

95+
--monitored-pid-bg: var(--swm-green-40);
96+
--disconnected-bg: var(--swm-pink-40);
97+
--disconnected-text: var(--slate-900);
98+
9599
--status-dot-success-bg: var(--swm-green-100);
96100
--status-dot-warning-bg: var(--swm-yellow-100);
97101
--status-dot-error-bg: var(--swm-pink-100);
102+
103+
--navbar-selected-bg: var(--swm-brand);
98104
}

assets/app/tailwind.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,13 @@ module.exports = {
7272
'diff-border': 'var(--diff-border)',
7373
'diff-negative-bg': 'var(--diff-negative-bg)',
7474
'diff-positive-bg': 'var(--diff-positive-bg)',
75+
'monitored-pid-bg': 'var(--monitored-pid-bg)',
76+
'disconnected-bg': 'var(--disconnected-bg)',
77+
'disconnected-text': 'var(--disconnected-text)',
7578
'status-dot-success-bg': 'var(--status-dot-success-bg)',
7679
'status-dot-warning-bg': 'var(--status-dot-warning-bg)',
7780
'status-dot-error-bg': 'var(--status-dot-error-bg)',
81+
'navbar-selected-bg': 'var(--navbar-selected-bg)',
7882
},
7983
screens: { xs: '380px' },
8084
fontFamily: {

lib/live_debugger/app/debugger/callback_tracing/web/global_traces_live.ex

Lines changed: 106 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
2727
alias LiveDebugger.Structs.LvProcess
2828
alias LiveDebugger.Bus
2929
alias LiveDebugger.App.Debugger.Events.DeadViewModeEntered
30+
alias LiveDebugger.App.Debugger.Web.Components.Pages
3031

3132
@live_stream_limit 128
3233
@page_size 25
@@ -35,12 +36,18 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
3536
attr(:id, :string, required: true)
3637
attr(:lv_process, LvProcess, required: true)
3738
attr(:class, :string, default: "", doc: "CSS class for the container")
39+
attr(:url, :string, required: true)
40+
attr(:inspect_mode?, :boolean, required: true)
41+
attr(:return_link, :string, required: true)
3842

3943
def live_render(assigns) do
4044
session = %{
4145
"id" => assigns.id,
4246
"lv_process" => assigns.lv_process,
43-
"parent_pid" => self()
47+
"url" => assigns.url,
48+
"parent_pid" => self(),
49+
"inspect_mode?" => assigns.inspect_mode?,
50+
"return_link" => assigns.return_link
4451
}
4552

4653
assigns = assign(assigns, session: session)
@@ -57,7 +64,14 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
5764
@impl true
5865
def mount(
5966
_params,
60-
%{"parent_pid" => parent_pid, "lv_process" => lv_process, "id" => id},
67+
%{
68+
"parent_pid" => parent_pid,
69+
"lv_process" => lv_process,
70+
"id" => id,
71+
"url" => url,
72+
"inspect_mode?" => inspect_mode?,
73+
"return_link" => return_link
74+
},
6175
socket
6276
) do
6377
if connected?(socket) do
@@ -76,7 +90,10 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
7690
traces_continuation: nil,
7791
sidebar_hidden?: true,
7892
trace_search_phrase: "",
79-
node_id: nil
93+
node_id: nil,
94+
url: url,
95+
inspect_mode?: inspect_mode?,
96+
return_link: return_link
8097
)
8198
|> stream(:existing_traces, [], reset: true)
8299
|> put_private(:page_size, @page_size)
@@ -100,76 +117,84 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
100117
@impl true
101118
def render(assigns) do
102119
~H"""
103-
<div class="grow p-8 overflow-y-auto scrollbar-main">
104-
<div class="w-full min-w-[25rem] max-w-screen-2xl mx-auto">
105-
<div class="flex flex-col gap-1.5 pb-6 px-0.5">
106-
<.h1>Global Callback Traces</.h1>
107-
<span class="text-secondary-text">
108-
This view lists all callbacks inside debugged LiveView and its LiveComponents
109-
</span>
110-
</div>
111-
<div class="@container/traces w-full min-w-[20rem] flex flex-col pt-2 shadow-custom rounded-sm bg-surface-0-bg border border-default-border">
112-
<div class="w-full flex justify-between items-center border-b border-default-border pb-2">
113-
<div class="ml-2">
114-
<HookComponents.SearchInput.render
115-
disabled?={@tracing_started?}
116-
trace_search_phrase={@trace_search_phrase}
117-
/>
118-
</div>
119-
<div class="flex gap-2 items-center h-8 px-2">
120-
<HookComponents.ToggleTracingButton.render
121-
tracing_started?={@tracing_started?}
122-
lv_process_alive?={@lv_process.alive?}
123-
/>
124-
<%= if not @tracing_started? do %>
125-
<.global_traces_dropdown_menu class="@[30rem]/traces:hidden" />
126-
127-
<div class="hidden @[30rem]/traces:flex gap-2">
128-
<HookComponents.RefreshButton.render display_mode={:normal} />
129-
<HookComponents.ClearButton.render display_mode={:normal} />
130-
</div>
131-
<% end %>
132-
</div>
120+
<div class="flex flex-col h-full overflow-x-auto w-full">
121+
<Pages.navbar_menu
122+
url={@url}
123+
return_link={@return_link}
124+
inspect_mode?={@inspect_mode?}
125+
lv_process={@lv_process}
126+
/>
127+
<div class="grow p-8 overflow-y-auto scrollbar-main">
128+
<div class="w-full min-w-[25rem] max-w-screen-2xl mx-auto">
129+
<div class="flex flex-col gap-1.5 pb-6 px-0.5">
130+
<.h1>Global Callback Traces</.h1>
131+
<span class="text-secondary-text">
132+
This view lists all callbacks inside debugged LiveView and its LiveComponents
133+
</span>
133134
</div>
134-
<div class="flex flex-1 overflow-auto rounded-sm bg-surface-0-bg p-4">
135-
<div class="w-full h-full flex flex-col gap-4">
136-
<HookComponents.Stream.render
137-
id={@id}
138-
existing_traces_status={@existing_traces_status}
139-
existing_traces={@streams.existing_traces}
140-
>
141-
<:trace :let={{id, trace_display}}>
142-
<HookComponents.TraceWrapper.render id={id} trace_display={trace_display}>
143-
<:label>
144-
<.trace_label
145-
id={id <> "-label"}
146-
trace_display={trace_display}
147-
search_phrase={@trace_search_phrase}
148-
short_content_full?={true}
149-
show_subtitle?={true}
150-
/>
151-
</:label>
152-
153-
<:body>
154-
<.trace_body
155-
id={id <> "-body"}
156-
trace_display={trace_display}
157-
search_phrase={@trace_search_phrase}
158-
/>
159-
</:body>
160-
</HookComponents.TraceWrapper.render>
161-
</:trace>
162-
</HookComponents.Stream.render>
163-
<HookComponents.LoadMoreButton.render
164-
:if={not @tracing_started? and not @traces_empty?}
165-
traces_continuation={@traces_continuation}
166-
/>
167-
<.trace_fullscreen
168-
:if={@displayed_trace}
169-
id="trace-fullscreen"
170-
displayed_trace={@displayed_trace}
171-
search_phrase={@trace_search_phrase}
172-
/>
135+
<div class="@container/traces w-full min-w-[20rem] flex flex-col pt-2 shadow-custom rounded-sm bg-surface-0-bg border border-default-border">
136+
<div class="w-full flex justify-between items-center border-b border-default-border pb-2">
137+
<div class="ml-2">
138+
<HookComponents.SearchInput.render
139+
disabled?={@tracing_started?}
140+
trace_search_phrase={@trace_search_phrase}
141+
/>
142+
</div>
143+
<div class="flex gap-2 items-center h-8 px-2">
144+
<HookComponents.ToggleTracingButton.render
145+
tracing_started?={@tracing_started?}
146+
lv_process_alive?={@lv_process.alive?}
147+
/>
148+
<%= if not @tracing_started? do %>
149+
<.global_traces_dropdown_menu class="@[30rem]/traces:hidden" />
150+
151+
<div class="hidden @[30rem]/traces:flex gap-2">
152+
<HookComponents.RefreshButton.render display_mode={:normal} />
153+
<HookComponents.ClearButton.render display_mode={:normal} />
154+
</div>
155+
<% end %>
156+
</div>
157+
</div>
158+
<div class="flex flex-1 overflow-auto rounded-sm bg-surface-0-bg p-4">
159+
<div class="w-full h-full flex flex-col gap-4">
160+
<HookComponents.Stream.render
161+
id={@id}
162+
existing_traces_status={@existing_traces_status}
163+
existing_traces={@streams.existing_traces}
164+
>
165+
<:trace :let={{id, trace_display}}>
166+
<HookComponents.TraceWrapper.render id={id} trace_display={trace_display}>
167+
<:label>
168+
<.trace_label
169+
id={id <> "-label"}
170+
trace_display={trace_display}
171+
search_phrase={@trace_search_phrase}
172+
short_content_full?={true}
173+
show_subtitle?={true}
174+
/>
175+
</:label>
176+
177+
<:body>
178+
<.trace_body
179+
id={id <> "-body"}
180+
trace_display={trace_display}
181+
search_phrase={@trace_search_phrase}
182+
/>
183+
</:body>
184+
</HookComponents.TraceWrapper.render>
185+
</:trace>
186+
</HookComponents.Stream.render>
187+
<HookComponents.LoadMoreButton.render
188+
:if={not @tracing_started? and not @traces_empty?}
189+
traces_continuation={@traces_continuation}
190+
/>
191+
<.trace_fullscreen
192+
:if={@displayed_trace}
193+
id="trace-fullscreen"
194+
displayed_trace={@displayed_trace}
195+
search_phrase={@trace_search_phrase}
196+
/>
197+
</div>
173198
</div>
174199
</div>
175200
</div>
@@ -195,4 +220,13 @@ defmodule LiveDebugger.App.Debugger.CallbackTracing.Web.GlobalTracesLive do
195220
end
196221

197222
def handle_info(_, socket), do: {:noreply, socket}
223+
224+
@impl true
225+
def handle_event("switch-inspect-mode", _, socket) do
226+
send(socket.assigns.parent_pid, :switch_inspect_mode)
227+
228+
socket
229+
|> assign(:inspect_mode?, !socket.assigns.inspect_mode?)
230+
|> noreply()
231+
end
198232
end

lib/live_debugger/app/debugger/nested_live_view_links/web/nested_live_view_links_live.ex

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ defmodule LiveDebugger.App.Debugger.NestedLiveViewLinks.Web.NestedLiveViewLinksL
55

66
use LiveDebugger.App.Web, :live_view
77

8+
alias Phoenix.LiveView.AsyncResult
9+
810
alias LiveDebugger.Structs.LvProcess
911
alias LiveDebugger.API.LiveViewDiscovery
1012
alias LiveDebugger.App.Debugger.Web.Components, as: DebuggerComponents
1113

1214
alias LiveDebugger.App.Debugger.NestedLiveViewLinks.Queries,
1315
as: NestedLiveViewLinksQueries
1416

17+
alias LiveDebugger.App.Debugger.Queries.LvProcess, as: LvProcessQueries
18+
1519
alias LiveDebugger.Bus
1620
alias LiveDebugger.Services.ProcessMonitor.Events.LiveViewDied
1721
alias LiveDebugger.Services.ProcessMonitor.Events.LiveViewBorn
@@ -56,18 +60,30 @@ defmodule LiveDebugger.App.Debugger.NestedLiveViewLinks.Web.NestedLiveViewLinksL
5660
socket
5761
|> assign(lv_process: lv_process)
5862
|> assign_async_nested_lv_processes()
63+
|> assign_async_parent_lv_process()
5964
|> ok()
6065
end
6166

6267
@impl true
6368
def render(assigns) do
6469
~H"""
65-
<div class="w-full px-4 py-3 gap-3 flex flex-col border-b border-default-border">
70+
<div class="w-full px-4 pt-4 pb-5 gap-3 flex flex-col border-b border-default-border mt-1 z">
71+
<.async_result :let={parent_lv_process} assign={@parent_lv_process}>
72+
<p :if={parent_lv_process} class="pl-2 shrink-0 font-medium text-secondary-text pb-1 pt-1">
73+
Parent LiveView
74+
</p>
75+
<div :if={parent_lv_process} class="pl-2 flex flex-col gap-1">
76+
<DebuggerComponents.live_view_link
77+
lv_process={parent_lv_process}
78+
id="parent-live-view-link"
79+
/>
80+
</div>
81+
</.async_result>
6682
<.async_result :let={nested_lv_processes} assign={@nested_lv_processes}>
6783
<:loading>
6884
<.spinner size="sm" class="m-auto" />
6985
</:loading>
70-
<p class="pl-2 shrink-0 font-medium text-secondary-text">
86+
<p class="pl-2 shrink-0 font-medium text-secondary-text pb-1 pt-1">
7187
<%= if Enum.empty?(nested_lv_processes), do: "No nested LiveViews", else: "Nested LiveViews" %>
7288
</p>
7389
<%= if not Enum.empty?(nested_lv_processes) do %>
@@ -114,6 +130,20 @@ defmodule LiveDebugger.App.Debugger.NestedLiveViewLinks.Web.NestedLiveViewLinksL
114130
)
115131
end
116132

133+
defp assign_async_parent_lv_process(socket) do
134+
parent_pid = socket.assigns.lv_process.parent_pid
135+
136+
case parent_pid do
137+
nil ->
138+
assign(socket, :parent_lv_process, AsyncResult.ok(nil))
139+
140+
pid ->
141+
assign_async(socket, :parent_lv_process, fn ->
142+
{:ok, %{parent_lv_process: LvProcessQueries.get_lv_process_with_retries(pid)}}
143+
end)
144+
end
145+
end
146+
117147
defp known_child_lv_process?(socket, pid) do
118148
case socket.assigns.nested_lv_processes.result do
119149
nil -> false

lib/live_debugger/app/debugger/node_state/web/node_state_live.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ defmodule LiveDebugger.App.Debugger.NodeState.Web.NodeStateLive do
7676
@impl true
7777
def render(assigns) do
7878
~H"""
79-
<div class="flex-1 max-w-full flex flex-col gap-4">
79+
<div class="flex-1 w-full flex flex-col gap-4">
8080
<.async_result :let={{_node_assigns, term_node, copy_string}} assign={@node_assigns_info}>
8181
<:loading>
8282
<NodeStateComponents.loading />

0 commit comments

Comments
 (0)