Current section

43 Versions

Jump to

Compare versions

14 files changed
+503 additions
-108 deletions
  @@ -1,5 +1,12 @@
1 1 # CHANGELOG
2 2
3 + ## v0.3.0 (2020-10-16)
4 +
5 + * Use `$initial_call` from process dictionary as the initial call whenever available
6 + * Allow custom pages via `Phoenix.LiveDashboard.PageBuilder`
7 + * Allow processes to be killed when `:allow_destructive_actions` is enabled
8 + * Add an Ecto Stats page that shows stats from PSQL databases
9 +
3 10 ## v0.2.10 (2020-10-13)
4 11
5 12 * Support `:request_logger_cookie_domain` configuration
  @@ -24,6 +24,8 @@ LiveDashboard provides real-time performance monitoring and debugging tools for
24 24
25 25 * ETS - See, filter, and search ETS tables (in-memory storage) in the current node
26 26
27 + * Ecto Stats - Shows index, table, and general usage about the underlying Ecto Repo storage
28 +
27 29 The dashboard also works across nodes. If your nodes are connected via Distributed Erlang, then you can access information from node B while accessing the dashboard on node A.
28 30
29 31 ![screenshot](https://github.com/phoenixframework/phoenix_live_dashboard/raw/master/screenshot.png)
  @@ -38,6 +38,7 @@
38 38 <<"lib/phoenix/live_dashboard/application.ex">>,
39 39 <<"lib/phoenix/live_dashboard/telemetry_listener.ex">>,
40 40 <<"lib/phoenix/live_dashboard/pages">>,
41 + <<"lib/phoenix/live_dashboard/pages/ecto_stats_page.ex">>,
41 42 <<"lib/phoenix/live_dashboard/pages/metrics_page.ex">>,
42 43 <<"lib/phoenix/live_dashboard/pages/ets_page.ex">>,
43 44 <<"lib/phoenix/live_dashboard/pages/request_logger_page.ex">>,
  @@ -71,5 +72,10 @@
71 72 {<<"name">>,<<"phoenix_html">>},
72 73 {<<"optional">>,false},
73 74 {<<"repository">>,<<"hexpm">>},
74 - {<<"requirement">>,<<"~> 2.14.1 or ~> 2.15">>}]]}.
75 - {<<"version">>,<<"0.2.10">>}.
75 + {<<"requirement">>,<<"~> 2.14.1 or ~> 2.15">>}],
76 + [{<<"app">>,<<"ecto_psql_extras">>},
77 + {<<"name">>,<<"ecto_psql_extras">>},
78 + {<<"optional">>,true},
79 + {<<"repository">>,<<"hexpm">>},
80 + {<<"requirement">>,<<"~> 0.2">>}]]}.
81 + {<<"version">>,<<"0.3.0">>}.
  @@ -120,7 +120,7 @@ defmodule Phoenix.LiveDashboard.NavBarComponent do
120 120 </ul>
121 121 </div>
122 122 </div>
123 - <%= render_content(@socket, @page, @items, @current) %>
123 + <%= render_content(@socket, @page, @items[@current][:render]) %>
124 124 </div>
125 125 """
126 126 end
  @@ -139,14 +139,17 @@ defmodule Phoenix.LiveDashboard.NavBarComponent do
139 139 defp maybe_put(keyword, _key, nil), do: keyword
140 140 defp maybe_put(keyword, key, value), do: [{key, value} | keyword]
141 141
142 - defp render_content(socket, page, items, current) do
143 - case items[current][:render] do
142 + defp render_content(socket, page, component_or_fun) do
143 + case component_or_fun do
144 144 {component, component_assigns} ->
145 145 live_component(socket, component, Map.put(component_assigns, :page, page))
146 146
147 - # Needed for the metrics page, should be removed soon
148 147 fun when is_function(fun, 0) ->
149 - fun.()
148 + render_content(socket, page, fun.())
149 +
150 + # TODO: Remove me once we port metrics
151 + %Phoenix.LiveView.Rendered{} = other ->
152 + other
150 153 end
151 154 end
152 155 end
  @@ -7,7 +7,8 @@ defmodule Phoenix.LiveDashboard.TableComponent do
7 7 limit: pos_integer(),
8 8 sort_by: :atom,
9 9 sort_dir: :desc | :asc,
10 - search: binary()
10 + search: binary(),
11 + hint: binary() | nil
11 12 }
12 13
13 14 @impl true
  @@ -19,8 +20,10 @@ defmodule Phoenix.LiveDashboard.TableComponent do
19 20 params
20 21 |> validate_required([:columns, :id, :row_fetcher, :title])
21 22 |> normalize_columns()
22 - |> Map.put_new(:limit_options, @limit)
23 + |> Map.put_new(:search, true)
24 + |> Map.put_new(:limit, @limit)
23 25 |> Map.put_new(:row_attrs, [])
26 + |> Map.put_new(:hint, nil)
24 27 |> Map.put_new_lazy(:rows_name, fn ->
25 28 Phoenix.Naming.humanize(params.title) |> String.downcase()
26 29 end)
  @@ -84,11 +87,7 @@ defmodule Phoenix.LiveDashboard.TableComponent do
84 87 end
85 88
86 89 defp normalize_table_params(assigns) do
87 - %{
88 - columns: columns,
89 - page: %{params: all_params},
90 - limit_options: limit_options
91 - } = assigns
90 + %{columns: columns, page: %{params: all_params}} = assigns
92 91
93 92 sortable_columns = sortable_columns(columns)
94 93
  @@ -102,8 +101,15 @@ defmodule Phoenix.LiveDashboard.TableComponent do
102 101 |> get_in_or_first("sort_dir", sortable_dirs(columns, sort_by))
103 102 |> String.to_atom()
104 103
105 - limit_options = Enum.map(limit_options, &to_string/1)
106 - limit = all_params |> get_in_or_first("limit", limit_options) |> String.to_integer()
104 + limit =
105 + if assigns.limit do
106 + all_params
107 + |> get_in_or_first("limit", Enum.map(assigns.limit, &to_string/1))
108 + |> String.to_integer()
109 + else
110 + nil
111 + end
112 +
107 113 search = all_params["search"]
108 114 search = if search == "", do: nil, else: search
109 115
  @@ -131,31 +137,39 @@ defmodule Phoenix.LiveDashboard.TableComponent do
131 137 def render(assigns) do
132 138 ~L"""
133 139 <div class="tabular-page">
134 - <h5 class="card-title"><%= @title %></h5>
140 + <h5 class="card-title"><%= @title %> <%= @hint && hint(do: @hint) %></h5>
135 141
136 - <div class="tabular-search">
137 - <form phx-change="search" phx-submit="search" phx-target="<%= @myself %>" class="form-inline">
138 - <div class="form-row align-items-center">
139 - <div class="col-auto">
140 - <input type="search" name="search" class="form-control form-control-sm" value="<%= @table_params.search %>" placeholder="Search" phx-debounce="300">
142 + <%= if @search do %>
143 + <div class="tabular-search">
144 + <form phx-change="search" phx-submit="search" phx-target="<%= @myself %>" class="form-inline">
145 + <div class="form-row align-items-center">
146 + <div class="col-auto">
147 + <input type="search" name="search" class="form-control form-control-sm" value="<%= @table_params.search %>" placeholder="Search" phx-debounce="300">
148 + </div>
141 149 </div>
142 - </div>
143 - </form>
144 - </div>
150 + </form>
151 + </div>
152 + <% end %>
145 153
146 154 <form phx-change="select_limit" phx-target="<%= @myself %>" class="form-inline">
147 155 <div class="form-row align-items-center">
148 - <div class="col-auto">Showing at most</div>
149 - <div class="col-auto">
150 - <div class="input-group input-group-sm">
151 - <select name="limit" class="custom-select" id="limit-select">
152 - <%= options_for_select(@limit_options, @table_params.limit) %>
153 - </select>
156 + <%= if @limit do %>
157 + <div class="col-auto">Showing at most</div>
158 + <div class="col-auto">
159 + <div class="input-group input-group-sm">
160 + <select name="limit" class="custom-select" id="limit-select">
161 + <%= options_for_select(@limit, @table_params.limit) %>
162 + </select>
163 + </div>
154 164 </div>
155 - </div>
156 - <div class="col-auto">
157 - <%= @rows_name %> out of <%= @total %>
158 - </div>
165 + <div class="col-auto">
166 + <%= @rows_name %> out of <%= @total %>
167 + </div>
168 + <% else %>
169 + <div class="col-auto">
170 + Showing <%= @total %> <%= @rows_name %>
171 + </div>
172 + <% end %>
159 173 </div>
160 174 </form>
161 175
  @@ -246,7 +260,7 @@ defmodule Phoenix.LiveDashboard.TableComponent do
246 260 [link_name | sort_link_icon(sort_dir)]
247 261 end
248 262
249 - defp sort_link_icon(:asc) do
263 + defp sort_link_icon(:desc) do
250 264 {:safe,
251 265 """
252 266 <div class="dash-table-icon">
  @@ -255,7 +269,7 @@ defmodule Phoenix.LiveDashboard.TableComponent do
255 269 """}
256 270 end
257 271
258 - defp sort_link_icon(:desc) do
272 + defp sort_link_icon(:asc) do
259 273 {:safe,
260 274 """
261 275 <div class="dash-table-icon">
Loading more files…