Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
7f7291b
remove from function names when not necessary
GuzekAlan May 19, 2025
ea30c2e
dont remove table when any process is watching
GuzekAlan May 19, 2025
3a95124
add specs
GuzekAlan May 20, 2025
a336e20
properly send events and delete state server record
GuzekAlan May 20, 2025
cbc4fe6
add indicator, change state names
GuzekAlan May 22, 2025
2f1ccbf
add styling
GuzekAlan May 22, 2025
752c460
add flag for dead view mode
GuzekAlan May 22, 2025
37239dc
add docs, conditional using `watch` function
GuzekAlan May 22, 2025
fb2e7c1
fix tests
GuzekAlan May 22, 2025
9c57cc3
make dead view mode default
GuzekAlan May 22, 2025
4f5725c
add tests
GuzekAlan May 22, 2025
2cc66b7
remove unnecessary config
GuzekAlan May 22, 2025
b46e2c3
fix e2e tests
GuzekAlan May 22, 2025
8c1a7a4
end gitignore with newline
GuzekAlan May 22, 2025
7d2b7bb
manually compile deploy assets
GuzekAlan May 22, 2025
cc01357
Merge branch 'main' into 252-add-mode-for-disconnected-liveview
kraleppa May 23, 2025
a9153c6
Changed sidebar icon
kraleppa May 23, 2025
0703cb5
Moved sidebar to right
kraleppa May 23, 2025
6276a8c
Applied single column layout
kraleppa May 23, 2025
002903a
Changed long assign example
kraleppa May 23, 2025
42b79ee
Added navigation bar
kraleppa May 23, 2025
0aa21cd
Added separator between theme and sidebar icons
kraleppa May 23, 2025
d97d3d7
Bigger bap between connected and logo
kraleppa May 23, 2025
908b067
Changed info in the sidebar
kraleppa May 23, 2025
65fcabd
Updated LiveDropdown
kraleppa May 23, 2025
4e1019a
Added base for menu dropdown
kraleppa May 23, 2025
41b371e
remove from function names when not necessary
GuzekAlan May 19, 2025
47c82f2
dont remove table when any process is watching
GuzekAlan May 19, 2025
b61e38e
add specs
GuzekAlan May 20, 2025
c3cc531
properly send events and delete state server record
GuzekAlan May 20, 2025
07109a0
add indicator, change state names
GuzekAlan May 22, 2025
8ba3630
add styling
GuzekAlan May 22, 2025
3ff952f
add flag for dead view mode
GuzekAlan May 22, 2025
48c5536
add docs, conditional using `watch` function
GuzekAlan May 22, 2025
d439894
fix tests
GuzekAlan May 22, 2025
4f836ab
make dead view mode default
GuzekAlan May 22, 2025
f3608f8
add tests
GuzekAlan May 22, 2025
31fa112
remove unnecessary config
GuzekAlan May 22, 2025
0e1c0bd
fix e2e tests
GuzekAlan May 22, 2025
583d1f4
end gitignore with newline
GuzekAlan May 22, 2025
92fcf76
manually compile deploy assets
GuzekAlan May 22, 2025
1fb0880
use LiveDebugger.Feature module
GuzekAlan May 26, 2025
9d74ac4
add docs
GuzekAlan May 26, 2025
80b8482
add tooltip:
GuzekAlan May 26, 2025
38d7765
remove from docs
GuzekAlan May 26, 2025
4653515
fetch if not cached
GuzekAlan May 26, 2025
fd89332
change tooltip info
GuzekAlan May 26, 2025
3e63b5b
Moved navigation menu to separate module
kraleppa May 26, 2025
12bb0b6
add config for disabling redirects in devtools
GuzekAlan May 26, 2025
f671b40
Fixed icons
kraleppa May 26, 2025
5d6fcb1
Added dropdown options
kraleppa May 26, 2025
3915592
Correct routing in dropdown
kraleppa May 26, 2025
199b171
Fixed navbar
kraleppa May 26, 2025
b8374b5
Fixed most of tests
kraleppa May 26, 2025
8bdbf04
Fixed updating module on changing tree elements
kraleppa May 26, 2025
4357513
Merge branch '252-add-mode-for-disconnected-liveview' into apply-new-…
kraleppa May 26, 2025
0a64397
Added missing attr
kraleppa May 26, 2025
3e31038
Merge branch 'main' into apply-new-navigation
kraleppa May 26, 2025
adc8948
Removed readme updates
kraleppa May 26, 2025
6686666
Removed config
kraleppa May 26, 2025
16802ae
Removed deadview from docs
kraleppa May 26, 2025
3928269
Removed spec
kraleppa May 27, 2025
9e1708c
Removed post merge artifact
kraleppa May 27, 2025
bb79157
Hide return link for window liveview in iframe
kraleppa May 27, 2025
e5f52e9
Added truncate
kraleppa May 27, 2025
2ad7087
Fixed tooltip
kraleppa May 27, 2025
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
3 changes: 3 additions & 0 deletions assets/icons/globe.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/icons/info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/icons/panel-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion dev/live_views/main.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ defmodule LiveDebuggerDev.LiveViews.Main do
|> assign(list: [%Phoenix.LiveComponent.CID{cid: 1}, %Phoenix.LiveComponent.CID{cid: 2}])
|> assign(
long_assign:
"flex items-center gap-2 flex grow flex-col xl:flex-row flex items-center gap-2 flex grow flex-col xl:flex-row gap-4 xl:gap-8 p-8 overflow-y-auto xl:overflow-y-hidden max-w-screen-2xl mx-auto"
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
)

{:ok, socket}
Expand Down
23 changes: 23 additions & 0 deletions lib/live_debugger_web/components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,29 @@ defmodule LiveDebuggerWeb.Components do
"""
end

@doc """
Renders an icon with navbar styles.
"""
attr(:icon, :string, required: true, doc: "Icon to be displayed.")
attr(:class, :any, default: nil, doc: "Additional classes to add to the nav icon.")

attr(:rest, :global, include: ~w(id))

def nav_icon(assigns) do
~H"""
<button
aria-label={Parsers.kebab_to_text(@icon)}
class={[
"w-8! h-8! px-[0.25rem] py-[0.25rem] w-max h-max rounded text-xs font-semibold text-navbar-icon hover:text-navbar-icon-hover hover:bg-navbar-icon-bg-hover"
| List.wrap(@class)
]}
{@rest}
>
<.icon name={@icon} class="h-6 w-6" />
</button>
"""
end

attr(:variant, :string, required: true, values: ["danger"])

defp alert_icon(assigns) do
Expand Down
33 changes: 5 additions & 28 deletions lib/live_debugger_web/components/navbar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ defmodule LiveDebuggerWeb.Components.Navbar do

use LiveDebuggerWeb, :component

alias LiveDebugger.Utils.Parsers

@doc """
Renders base navbar component.
"""
Expand Down Expand Up @@ -55,11 +53,13 @@ defmodule LiveDebuggerWeb.Components.Navbar do
@doc """
Renders a link to return to the previous page.
"""
attr(:link, :any, required: true, doc: "Link to navigate to.")

attr(:return_link, :any, required: true, doc: "Link to navigate to.")
attr(:class, :any, default: nil, doc: "Additional classes to add to the link.")

def return_link(assigns) do
~H"""
<.link patch={@link}>
<.link patch={@return_link} class={@class}>
<.nav_icon icon="icon-arrow-left" />
</.link>
"""
Expand All @@ -82,29 +82,6 @@ defmodule LiveDebuggerWeb.Components.Navbar do
"""
end

@doc """
Renders an icon with navbar styles.
"""
attr(:icon, :string, required: true, doc: "Icon to be displayed.")
attr(:class, :any, default: nil, doc: "Additional classes to add to the nav icon.")

attr(:rest, :global, include: ~w(id))

def nav_icon(assigns) do
~H"""
<button
aria-label={Parsers.kebab_to_text(@icon)}
class={[
"w-8! h-8! px-[0.25rem] py-[0.25rem] w-max h-max rounded text-xs font-semibold text-navbar-icon hover:text-navbar-icon-hover hover:bg-navbar-icon-bg-hover"
| List.wrap(@class)
]}
{@rest}
>
<.icon name={@icon} class="h-6 w-6" />
</button>
"""
end

@doc """
Component for displaying the connection status of a LiveView.
When button is clicked, it will trigger a `find-successor` event with the PID of the LiveView.
Expand All @@ -126,7 +103,7 @@ defmodule LiveDebuggerWeb.Components.Navbar do
)
}
>
<div id={@id} class="flex items-center gap-1 text-xs text-primary">
<div id={@id} class="flex items-center gap-1 text-xs text-primary ml-1">
<.status_icon connected?={@connected?} />
<%= if @connected? do %>
<span class="font-medium">Monitored PID </span>
Expand Down
48 changes: 48 additions & 0 deletions lib/live_debugger_web/components/navigation_menu.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule LiveDebuggerWeb.Components.NavigationMenu do
@moduledoc """
Set of components used in the navigation menu.
"""
use LiveDebuggerWeb, :component

alias LiveDebuggerWeb.LiveComponents.LiveDropdown

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

def sidebar(assigns) do
~H"""
<div class={[
"flex flex-col gap-3 bg-sidebar-bg shadow-custom h-full p-2 border-r border-default-border"
| List.wrap(@class)
]}>
<.nav_icon icon="icon-info" />
<.nav_icon icon="icon-globe" />
</div>
"""
end

attr(:class, :any, default: nil, doc: "Additional classes to add to the navigation bar.")
attr(:return_link, :any, required: true, doc: "Link to navigate to.")

def dropdown(assigns) do
~H"""
<.live_component
module={LiveDropdown}
id="navigation-bar-dropdown"
class={@class}
direction="right"
>
<:button>
<.nav_icon icon="icon-menu-hamburger" />
</:button>
<div class="min-w-44 flex flex-col p-1">
<.link navigate={@return_link}>
<LiveDropdown.dropdown_item icon="icon-arrow-left" label="Back to Home" />
</.link>
<span class="w-full border-b border-default-border my-1"></span>
<LiveDropdown.dropdown_item icon="icon-info" label="Node Inspector" />
<LiveDropdown.dropdown_item icon="icon-globe" label="Global Callbacks" />
</div>
</.live_component>
"""
end
end
59 changes: 38 additions & 21 deletions lib/live_debugger_web/live/channel_dashboard_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ defmodule LiveDebuggerWeb.ChannelDashboardLive do
alias LiveDebuggerWeb.SidebarLive
alias LiveDebugger.Utils.PubSub, as: PubSubUtils
alias LiveDebugger.Utils.Parsers
alias LiveDebuggerWeb.Components.NavigationMenu

@impl true
def handle_params(params, url, socket) do
Expand All @@ -31,22 +32,38 @@ defmodule LiveDebuggerWeb.ChannelDashboardLive do
def render(assigns) do
~H"""
<div id="channel-dashboard" class="w-screen h-screen grid grid-rows-[auto_1fr]">
<Navbar.navbar class="grid grid-cols-[auto_auto_1fr_auto_auto]">
<Navbar.return_link link={get_return_link(@lv_process, @in_iframe?)} />
<Navbar.navbar class="grid grid-cols-[auto_auto_1fr_auto] pl-2 lg:pr-4">
<Navbar.return_link
return_link={get_return_link(@lv_process, @in_iframe?)}
class="hidden sm:block"
/>
<NavigationMenu.dropdown
return_link={get_return_link(@lv_process, @in_iframe?)}
class="sm:hidden"
/>
<Navbar.live_debugger_logo_icon />
<div
:if={not @lv_process.ok?}
class="animate-pulse w-36 bg-surface-1-bg rounded text-surface-1-bg"
>
Loading...
</div>
<Navbar.connected
:if={@lv_process.ok?}
id="navbar-connected"
connected?={@lv_process.result.alive?}
pid={Parsers.pid_to_string(@lv_process.result.pid)}
/>
<Navbar.theme_toggle />
<Navbar.nav_icon
:if={@lv_process.ok?}
phx-click={JS.push("open-sidebar", target: "#sidebar")}
class="flex lg:hidden"
icon="icon-menu-hamburger"
/>
<div class="flex items-center gap-2">
<Navbar.theme_toggle />
<span :if={@lv_process.ok?} class="h-5 border-r border-default-border lg:hidden"></span>
<.nav_icon
:if={@lv_process.ok?}
phx-click={JS.push("open-sidebar", target: "#sidebar")}
class="flex lg:hidden"
icon="icon-panel-right"
/>
</div>
</Navbar.navbar>
<.async_result :let={lv_process} assign={@lv_process}>
<:loading>
Expand All @@ -55,32 +72,32 @@ defmodule LiveDebuggerWeb.ChannelDashboardLive do
</div>
</:loading>
<div class="flex overflow-hidden">
<SidebarLive.live_render
id="sidebar"
class="h-full"
socket={@socket}
lv_process={lv_process}
url={@url}
node_id={@node_id || lv_process.pid}
/>

<div class="flex grow flex-col xl:flex-row gap-4 xl:gap-8 p-8 overflow-y-auto xl:overflow-y-hidden max-w-screen-2xl mx-auto scrollbar-main">
<NavigationMenu.sidebar class="hidden sm:flex" />
<div class="flex grow flex-col gap-4 p-8 overflow-y-auto max-w-screen-2xl mx-auto scrollbar-main">
<StateLive.live_render
id="node-state-lv"
class="flex xl:w-1/2"
class="flex"
socket={@socket}
lv_process={lv_process}
node_id={@node_id || lv_process.pid}
/>
<TracesLive.live_render
id="traces-list"
class="flex max-xl:grow xl:w-1/2"
class="flex"
socket={@socket}
lv_process={lv_process}
node_id={@node_id || lv_process.pid}
root_pid={self()}
/>
</div>
<SidebarLive.live_render
id="sidebar"
class="h-full"
socket={@socket}
lv_process={lv_process}
url={@url}
node_id={@node_id || lv_process.pid}
/>
</div>
</.async_result>
</div>
Expand Down
61 changes: 44 additions & 17 deletions lib/live_debugger_web/live/sidebar_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule LiveDebuggerWeb.SidebarLive do

require Logger

alias LiveDebugger.Structs.TreeNode
alias LiveDebugger.Structs.LvProcess
alias LiveDebugger.Structs.Trace
alias LiveDebugger.Utils.Parsers
Expand Down Expand Up @@ -68,6 +69,7 @@ defmodule LiveDebuggerWeb.SidebarLive do
|> assign(:highlight?, false)
|> assign(:hidden?, true)
|> assign_async_tree()
|> assign_async_node_module()
|> assign_async_parent_lv_process()
|> assign_async_existing_node_ids()
|> ok()
Expand All @@ -90,6 +92,7 @@ defmodule LiveDebuggerWeb.SidebarLive do
node_id={@node_id}
highlight?={@highlight?}
parent_lv_process={@parent_lv_process}
node_module={@node_module}
/>
</div>
<.sidebar_slide_over :if={not @hidden?}>
Expand All @@ -101,6 +104,7 @@ defmodule LiveDebuggerWeb.SidebarLive do
node_id={@node_id}
highlight?={@highlight?}
parent_lv_process={@parent_lv_process}
node_module={@node_module}
/>
</.sidebar_slide_over>
</div>
Expand Down Expand Up @@ -139,6 +143,7 @@ defmodule LiveDebuggerWeb.SidebarLive do
def handle_info({:node_changed, node_id}, socket) do
socket
|> assign(:node_id, node_id)
|> assign_async_node_module()
|> noreply()
end

Expand Down Expand Up @@ -205,14 +210,16 @@ defmodule LiveDebuggerWeb.SidebarLive do
attr(:max_opened_node_level, :any, required: true)
attr(:highlight?, :boolean, required: true)
attr(:parent_lv_process, :any, required: true)
attr(:node_module, :any, required: true)

defp sidebar_content(assigns) do
~H"""
<div class="grid grid-rows-[auto_auto_1fr_auto] h-full">
<.basic_info
pid={@lv_process.pid}
socket_id={@lv_process.socket_id}
id={@id <> "-basic-info"}
module={@node_module}
parent_lv_process={@parent_lv_process}
node_type={TreeNode.type(@node_id)}
/>
<.live_component
id={@id <> "-nested-live-views"}
Expand Down Expand Up @@ -253,28 +260,33 @@ defmodule LiveDebuggerWeb.SidebarLive do
"""
end

attr(:pid, :any, required: true)
attr(:socket_id, :string, required: true)
attr(:parent_lv_process, :any, required: true)
attr(:id, :string, required: true)
attr(:module, :atom, required: true)
attr(:node_type, :atom, required: true)
attr(:parent_lv_process, :map, required: true)

defp basic_info(assigns) do
~H"""
<div class="w-full p-6 shrink-0 flex flex-col gap-2 border-b border-default-border">
<div id={@id} class="w-full p-6 shrink-0 flex flex-col gap-2 border-b border-default-border">
<.async_result :let={parent_lv_process} assign={@parent_lv_process}>
<:loading>
<div class="w-full h-30 flex justify-center items-center"><.spinner size="sm" /></div>
</:loading>
<div
:for={
{text, value} <- [
{"Monitored socket:", @socket_id},
{"Debugged PID:", Parsers.pid_to_string(@pid)}
]
}
class="w-full flex flex-col"
>
<span class="font-medium"><%= text %></span>
<span><%= value %></span>
<div class="w-full flex flex-col">
<span class="font-medium">Type:</span>
<span><%= node_type(@node_type) %></span>
</div>
<div class="w-full flex flex-col">
<span class="font-medium">Module:</span>

<.tooltip
:if={@module.ok?}
id={@id <> "-current-node-module"}
content={Parsers.module_to_string(@module.result)}
class="truncate max-w-[272px]"
>
<%= Parsers.module_to_string(@module.result) %>
</.tooltip>
</div>
<div :if={parent_lv_process} class="w-full flex flex-col">
<span class="font-medium">Parent LiveView Process</span>
Expand Down Expand Up @@ -332,6 +344,18 @@ defmodule LiveDebuggerWeb.SidebarLive do
socket
end

defp assign_async_node_module(%{assigns: %{node_id: node_id, lv_process: %{pid: pid}}} = socket) do
assign_async(socket, :node_module, fn ->
with {:ok, channel_state} <- ChannelService.state(pid),
{:ok, node} <- ChannelService.get_node(channel_state, node_id),
true <- not is_nil(node) do
{:ok, %{node_module: node.module}}
else
err -> err
end
end)
end

defp assign_async_existing_node_ids(socket) do
pid = socket.assigns.lv_process.pid

Expand Down Expand Up @@ -388,4 +412,7 @@ defmodule LiveDebuggerWeb.SidebarLive do

send(state.socket.transport_pid, state.serializer.encode!(message))
end

defp node_type(:live_component), do: "LiveComponent"
defp node_type(:live_view), do: "LiveView"
end
Loading