diff --git a/assets/icons/globe.svg b/assets/icons/globe.svg new file mode 100644 index 000000000..ddd917e2c --- /dev/null +++ b/assets/icons/globe.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/info.svg b/assets/icons/info.svg new file mode 100644 index 000000000..d5880065d --- /dev/null +++ b/assets/icons/info.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/panel-right.svg b/assets/icons/panel-right.svg new file mode 100644 index 000000000..804ab3775 --- /dev/null +++ b/assets/icons/panel-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/dev/live_views/main.ex b/dev/live_views/main.ex index b9757d9a2..206f877a6 100644 --- a/dev/live_views/main.ex +++ b/dev/live_views/main.ex @@ -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} diff --git a/lib/live_debugger_web/components.ex b/lib/live_debugger_web/components.ex index a8058277f..8132a1dc2 100644 --- a/lib/live_debugger_web/components.ex +++ b/lib/live_debugger_web/components.ex @@ -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""" + + """ + end + attr(:variant, :string, required: true, values: ["danger"]) defp alert_icon(assigns) do diff --git a/lib/live_debugger_web/components/navbar.ex b/lib/live_debugger_web/components/navbar.ex index 2cd9c4a52..f17b92f17 100644 --- a/lib/live_debugger_web/components/navbar.ex +++ b/lib/live_debugger_web/components/navbar.ex @@ -5,8 +5,6 @@ defmodule LiveDebuggerWeb.Components.Navbar do use LiveDebuggerWeb, :component - alias LiveDebugger.Utils.Parsers - @doc """ Renders base navbar component. """ @@ -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" /> """ @@ -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""" - - """ - 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. @@ -126,7 +103,7 @@ defmodule LiveDebuggerWeb.Components.Navbar do ) } > -
+
<.status_icon connected?={@connected?} /> <%= if @connected? do %> Monitored PID diff --git a/lib/live_debugger_web/components/navigation_menu.ex b/lib/live_debugger_web/components/navigation_menu.ex new file mode 100644 index 000000000..118acba23 --- /dev/null +++ b/lib/live_debugger_web/components/navigation_menu.ex @@ -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""" +
+ <.nav_icon icon="icon-info" /> + <.nav_icon icon="icon-globe" /> +
+ """ + 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" /> + +
+ <.link navigate={@return_link}> + + + + + +
+ + """ + end +end diff --git a/lib/live_debugger_web/live/channel_dashboard_live.ex b/lib/live_debugger_web/live/channel_dashboard_live.ex index 667e34e45..18d8da8d8 100644 --- a/lib/live_debugger_web/live/channel_dashboard_live.ex +++ b/lib/live_debugger_web/live/channel_dashboard_live.ex @@ -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 @@ -31,22 +32,38 @@ defmodule LiveDebuggerWeb.ChannelDashboardLive do def render(assigns) do ~H"""
- - + + <.async_result :let={lv_process} assign={@lv_process}> <:loading> @@ -55,32 +72,32 @@ defmodule LiveDebuggerWeb.ChannelDashboardLive do
- - -
+
diff --git a/lib/live_debugger_web/live/sidebar_live.ex b/lib/live_debugger_web/live/sidebar_live.ex index 890707da6..7db60f34b 100644 --- a/lib/live_debugger_web/live/sidebar_live.ex +++ b/lib/live_debugger_web/live/sidebar_live.ex @@ -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 @@ -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() @@ -90,6 +92,7 @@ defmodule LiveDebuggerWeb.SidebarLive do node_id={@node_id} highlight?={@highlight?} parent_lv_process={@parent_lv_process} + node_module={@node_module} />
<.sidebar_slide_over :if={not @hidden?}> @@ -101,6 +104,7 @@ defmodule LiveDebuggerWeb.SidebarLive do node_id={@node_id} highlight?={@highlight?} parent_lv_process={@parent_lv_process} + node_module={@node_module} />
@@ -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 @@ -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"""
<.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"} @@ -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""" -
+
<.async_result :let={parent_lv_process} assign={@parent_lv_process}> <:loading>
<.spinner size="sm" />
-
- <%= text %> - <%= value %> +
+ Type: + <%= node_type(@node_type) %> +
+
+ Module: + + <.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) %> +
Parent LiveView Process @@ -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 @@ -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 diff --git a/lib/live_debugger_web/live/state_live.ex b/lib/live_debugger_web/live/state_live.ex index 28833fc5d..3bc492a54 100644 --- a/lib/live_debugger_web/live/state_live.ex +++ b/lib/live_debugger_web/live/state_live.ex @@ -8,7 +8,6 @@ defmodule LiveDebuggerWeb.StateLive do alias Phoenix.LiveView.AsyncResult alias LiveDebuggerWeb.Components.ElixirDisplay - alias LiveDebugger.Utils.Parsers alias LiveDebugger.Structs.TreeNode alias LiveDebugger.Services.ChannelService alias LiveDebugger.Utils.TermParser @@ -78,7 +77,6 @@ defmodule LiveDebuggerWeb.StateLive do - <.info_section node={node} node_type={@node_type.result} nested?={@lv_process.nested?} /> <.assigns_section assigns={node.assigns} /> <.fullscreen id="assigns-display-fullscreen" title="Assigns"> noreply() end - attr(:node, :any, required: true) - attr(:node_type, :atom, required: true) - attr(:nested?, :boolean, default: false) - - defp info_section(assigns) do - ~H""" - <.section id="info" title={title(@node_type)}> - <:right_panel> - <.badge :if={@node_type == :live_view and @nested?} text="Nested" icon="icon-nested" /> - -
- <.info_row name="Module" value={Parsers.module_to_string(@node.module)} /> - <.info_row name={id_type(@node_type)} value={TreeNode.display_id(@node)} /> -
- - """ - end - - attr(:name, :string, required: true) - attr(:value, :any, required: true) - - defp info_row(assigns) do - ~H""" -
-
- <%= @name %> -
-
- <%= @value %> -
-
- """ - end - attr(:assigns, :list, required: true) defp assigns_section(assigns) do @@ -195,10 +159,4 @@ defmodule LiveDebuggerWeb.StateLive do |> assign(:node, AsyncResult.failed(%AsyncResult{}, :no_node_id)) |> assign(:node_type, AsyncResult.failed(%AsyncResult{}, :no_node_id)) end - - defp title(:live_component), do: "LiveComponent" - defp title(:live_view), do: "LiveView" - - defp id_type(:live_component), do: "CID" - defp id_type(:live_view), do: "PID" end diff --git a/lib/live_debugger_web/live/traces_live.ex b/lib/live_debugger_web/live/traces_live.ex index 585aba915..d0bbb5eb7 100644 --- a/lib/live_debugger_web/live/traces_live.ex +++ b/lib/live_debugger_web/live/traces_live.ex @@ -95,9 +95,11 @@ defmodule LiveDebuggerWeb.TracesLive do module={LiveDebuggerWeb.LiveComponents.LiveDropdown} id="filters-dropdown" > - <:button class="flex gap-2"> - <.icon name="icon-filters" class="w-4 h-4" /> - + <:button> + <.button class="flex gap-2" variant="secondary" size="sm"> + <.icon name="icon-filters" class="w-4 h-4" /> + + <.live_component module={LiveDebuggerWeb.LiveComponents.FiltersForm} @@ -109,7 +111,7 @@ defmodule LiveDebuggerWeb.TracesLive do
-
+