From e52ca44d2cf44a1d282edc990b421c5d63d8b3dd Mon Sep 17 00:00:00 2001 From: Aleksandr Lossenko Date: Mon, 11 Nov 2024 22:31:23 +0100 Subject: [PATCH] Breakdown of jobs by state (#63) Co-authored-by: Marty Zalega --- .formatter.exs | 4 +- lib/oban/live_dashboard.ex | 234 +++++++++++++++++++++--------- test/oban/live_dashboard_test.exs | 51 ++++++- 3 files changed, 219 insertions(+), 70 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index d2cda26..2395471 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,6 @@ # Used by "mix format" [ - inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], + # Need to increase it because of <.label_value_list /> that does a
 tag, which will look broken with extra whitespace.
+  heex_line_length: 300
 ]
diff --git a/lib/oban/live_dashboard.ex b/lib/oban/live_dashboard.ex
index 7e148eb..b295cf6 100644
--- a/lib/oban/live_dashboard.ex
+++ b/lib/oban/live_dashboard.ex
@@ -4,43 +4,41 @@ defmodule Oban.LiveDashboard do
   import Phoenix.LiveDashboard.Helpers, only: [format_value: 2]
   import Ecto.Query
 
-  @impl true
-  def menu_link(_, _) do
-    {:ok, "Oban"}
-  end
+  @per_page_limits [20, 50, 100]
+
+  @oban_sorted_job_states [
+    "executing",
+    "available",
+    "scheduled",
+    "retryable",
+    "cancelled",
+    "discarded",
+    "completed"
+  ]
 
   @impl true
   def render(assigns) do
     ~H"""
-    <.live_table
-      id="oban_jobs"
-      dom_id="oban-jobs"
-      page={@page}
-      row_attrs={&row_attrs/1}
-      row_fetcher={&fetch_jobs/2}
-      title="Oban Jobs"
-      search={false}
-    >
-      <:col field={:id} header="ID" sortable={:desc} />
-      <:col field={:state} sortable={:desc} />
-      <:col field={:queue} sortable={:desc} />
-      <:col field={:worker} sortable={:desc} />
-      <:col :let={job} field={:attempt} header="Attempts" sortable={:desc}>
-        <%= job.attempt %>/<%= job.max_attempts %>
-      
-      <:col :let={job} field={:inserted_at} sortable={:desc}>
-        <%= format_value(job.inserted_at) %>
-      
-      <:col :let={job} field={:scheduled_at} sortable={:desc}>
-        <%= format_value(job.scheduled_at) %>
-      
-    
-    <.live_modal
-      :if={@job != nil}
-      id="modal"
-      title="Job"
-      return_to={live_dashboard_path(@socket, @page, params: %{})}
-    >
+    
Oban
+ <.live_nav_bar id="oban_states" page={@page} nav_param="job_state" style={:bar} extra_params={["nav"]}> + <:item :for={{job_state, count} <- @job_state_counts} name={job_state} label={job_state_label(job_state, count)} method="navigate"> + <.live_table id="oban_jobs" limit={per_page_limits()} dom_id={"oban-jobs-#{job_state}"} page={@page} row_attrs={&row_attrs/1} row_fetcher={&fetch_jobs(&1, &2, job_state)} default_sort_by={@timestamp_field} title="" search={false}> + <:col :let={job} field={:worker} sortable={:desc}> +

<%= job.worker %>

+
<%= truncate(inspect(job.args)) %>
+ + <:col :let={job} field={:attempt} header="Attempt" sortable={:desc}> + <%= job.attempt %>/<%= job.max_attempts %> + + <:col field={:queue} header="Queue" sortable={:desc} /> + <:col :let={job} field={@timestamp_field} sortable={:desc}> + <%= format_value(timestamp(job, @timestamp_field)) %> + + + + + + <.live_modal :if={@job != nil} id="job-modal" title={"Job - #{@job.id}"} return_to={live_dashboard_path(@socket, @page, params: %{})}>