@@ -3,7 +3,7 @@ defmodule Oban.Web.CronsPage do
33
44 use Oban.Web , :live_component
55
6- alias Oban.Web.Page
6+ alias Oban.Web . { Cron , CronQuery , Page , Timing }
77
88 @ impl Phoenix.LiveComponent
99 def render ( assigns ) do
@@ -15,11 +15,7 @@ defmodule Oban.Web.CronsPage do
1515 class = "pr-3 flex items-center border-b border-gray-200 dark:border-gray-700 "
1616 >
1717 < div class = "flex-none flex items-center pr-12 " >
18- < Core . all_checkbox
19- click = "toggle-select-all "
20- checked = { :none }
21- myself = { @ myself }
22- />
18+ < Core . all_checkbox click = "toggle-select-all " checked = { :none } myself = { @ myself } />
2319
2420 < h2 class = "text-lg dark:text-gray-200 leading-4 font-bold " > Crons</ h2 >
2521 </ div >
@@ -30,7 +26,8 @@ defmodule Oban.Web.CronsPage do
3026 < . header label = "name " class = "ml-12 w-1/3 text-left " />
3127 < div class = "ml-auto flex items-center space-x-6 " >
3228 < . header label = "schedule " class = "w-32 text-right " />
33- < . header label = "activity " class = "w-24 text-right " />
29+ < . header label = "last run " class = "w-32 text-right " />
30+ < . header label = "next run " class = "w-32 text-right " />
3431 < . header label = "status " class = "w-20 pr-3 text-right " />
3532 </ div >
3633 </ ul >
@@ -42,20 +39,16 @@ defmodule Oban.Web.CronsPage do
4239 </ div >
4340
4441 < ul class = "divide-y divide-gray-100 dark:divide-gray-800 " >
45- < . cron_row
46- :for = { { expr , worker , opts } <- @ crontab }
47- expr = { expr }
48- worker = { worker }
49- opts = { opts }
50- myself = { @ myself }
51- />
42+ < . cron_row :for = { cron <- @ crontab } cron = { cron } myself = { @ myself } />
5243 </ ul >
5344 </ div >
5445 </ div >
5546 </ div >
5647 """
5748 end
5849
50+ # Components
51+
5952 attr :label , :string , required: true
6053 attr :class , :string , default: ""
6154
@@ -67,47 +60,49 @@ defmodule Oban.Web.CronsPage do
6760 """
6861 end
6962
70- attr :expr , :string
71- attr :worker , :string
72- attr :opts , :map
63+ attr :cron , Cron
7364 attr :myself , :any
7465
7566 defp cron_row ( assigns ) do
7667 ~H"""
7768 < li
78- id = { "cron-#{ cron_name ( @ worker , @ opts ) } " }
69+ id = { "cron-#{ Cron . name ( @ cron ) } " }
7970 class = "flex items-center hover:bg-gray-50 dark:hover:bg-gray-950/30 "
8071 >
81- < Core . row_checkbox
82- click = "toggle-select "
83- value = { @ worker }
84- checked = { false }
85- myself = { @ myself }
86- />
72+ < Core . row_checkbox click = "toggle-select " value = { @ cron . worker } checked = { false } myself = { @ myself } />
8773
8874 < div class = "py-2.5 flex flex-grow items-center " >
8975 < div class = "w-1/3 " >
9076 < span class = "block font-semibold text-sm text-gray-700 dark:text-gray-300 " >
91- { @ worker }
77+ { @ cron . worker }
9278 </ span >
9379
9480 < samp class = "font-mono truncate text-xs text-gray-500 dark:text-gray-400 " >
95- { format_opts ( @ opts ) }
81+ { format_opts ( @ cron . opts ) }
9682 </ samp >
9783 </ div >
9884
9985 < div class = "ml-auto flex items-center space-x-6 tabular text-gray-500 dark:text-gray-300 " >
10086 < span class = "w-32 text-right font-mono text-sm " >
101- { @ expr }
87+ { @ cron . expression }
88+ </ span >
89+
90+ < span class = "w-32 text-right text-sm " >
91+ { Timing . datetime_to_words ( @ cron . last_at ) }
10292 </ span >
10393
104- < span class = "w-24 text-right " >
105- -
94+ < span class = "w-32 text-right text-sm " >
95+ { Timing . datetime_to_words ( @ cron . next_at ) }
10696 </ span >
10797
10898 < div class = "w-20 pr-3 flex justify-end items-center space-x-1 " >
109- < span class = "py-1.5 px-2 text-xs rounded-md bg-gray-100 dark:bg-gray-950 " >
110- Active
99+ < span
100+ id = { "cron-state-icon-#{ @ cron . worker } " }
101+ class = "py-1.5 px-2 text-xs "
102+ phx-hook = "Tippy "
103+ data-title = { state_title ( @ cron ) }
104+ >
105+ < . state_icon state = { @ cron . last_state } />
111106 </ span >
112107 </ div >
113108 </ div >
@@ -116,16 +111,40 @@ defmodule Oban.Web.CronsPage do
116111 """
117112 end
118113
119- defp cron_name ( worker , opts ) do
120- base = String . replace ( worker , "." , "-" )
121- hash = :erlang . phash2 ( opts )
114+ attr :state , :string , required: true
115+
116+ defp state_icon ( assigns ) do
117+ ~H"""
118+ <%= case @ state do %>
119+ <% "available" -> %>
120+ < Icons . pause_circle class = "w-5 h-5 text-teal-400 " />
121+ <% "cancelled" - > %>
122+ < Icons . x_circle class = "w-5 h-5 text-violet-400 " />
123+ <% "completed" - > %>
124+ < Icons . check_circle class = "w-5 h-5 text-cyan-400 " />
125+ <% "discarded" - > %>
126+ < Icons . exclamation_circle class = "w-5 h-5 text-rose-400 " />
127+ <% "executing" - > %>
128+ < Icons . play_circle class = "w-5 h-5 text-orange-400 " />
129+ <% "retryable" - > %>
130+ < Icons . arrow_path class = "w-5 h-5 text-yellow-400 " />
131+ <% "scheduled" -> %>
132+ < Icons . play_circle class = "w-5 h-5 text-emerald-400 " />
133+ <% _ -> %>
134+ < Icons . minus_circle class = "w-5 h-5 text-gray-400 " />
135+ <% end %>
136+ """
137+ end
122138
123- "#{ base } -#{ hash } "
139+ defp state_title ( cron ) do
140+ case cron . last_state do
141+ nil -> "Unknown, no previous runs"
142+ state -> "#{ String . capitalize ( state ) } as of #{ NaiveDateTime . truncate ( cron . last_at , :second ) } "
143+ end
124144 end
125145
126146 @ impl Page
127147 def handle_mount ( socket ) do
128-
129148 assign_new ( socket , :crontab , fn -> crontab ( socket . assigns . conf ) end )
130149 end
131150
@@ -136,6 +155,8 @@ defmodule Oban.Web.CronsPage do
136155
137156 @ impl Page
138157 def handle_params ( _params , _uri , socket ) do
158+ socket = assign ( socket , page_title: page_title ( "Crons" ) )
159+
139160 { :noreply , socket }
140161 end
141162
@@ -156,13 +177,15 @@ defmodule Oban.Web.CronsPage do
156177 { :noreply , socket }
157178 end
158179
159- defp crontab ( conf ) , do: Oban.Met . crontab ( conf . name )
180+ defp crontab ( conf ) do
181+ CronQuery . all_crons ( % { } , conf )
182+ end
160183
161- defp format_opts ( opts ) when map_size ( opts ) == 0 , do: "%{} "
184+ defp format_opts ( opts ) when map_size ( opts ) == 0 , do: "[] "
162185
163186 defp format_opts ( opts ) do
164187 opts
165- |> inspect ( charlists: :as_lists , limit: :infinity )
188+ |> Enum . map_join ( ", " , fn { key , val } -> " #{ key } : #{ inspect ( val ) } " end )
166189 |> truncate ( 0 .. 98 )
167190 end
168191end
0 commit comments