11defmodule Oban.Web.Crons.DetailComponent do
22 use Oban.Web , :live_component
33
4- alias Oban.Web.Resolver
5-
64 @ impl Phoenix.LiveComponent
75 def render ( assigns ) do
86 ~H"""
@@ -16,165 +14,142 @@ defmodule Oban.Web.Crons.DetailComponent do
1614 phx-hook = "Tippy "
1715 >
1816 < Icons . arrow_left class = "w-5 h-5 " />
19- < span class = "text-lg font-bold ml-2 " > Cron Details </ span >
17+ < span class = "text-lg font-bold ml-2 " > { @ cron . worker } </ span >
2018 </ . link >
2119
22- < div class = "flex " >
23- <%= if @ cron . dynamic? do %>
24- < button
25- id = "detail-edit "
26- class = "group flex items-center ml-4 text-sm text-gray-600 dark:text-gray-400 bg-white dark:bg-gray-800 px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-md focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 hover:text-blue-500 hover:border-blue-600 "
27- phx-target = { @ myself }
28- phx-click = "edit "
29- type = "button "
30- >
31- < Icons . pencil_square class = "-ml-1 mr-1 h-5 w-5 text-gray-500 group-hover:text-blue-500 " />
32- Edit
33- </ button >
34- <% end %>
20+ < div class = "flex space-x-3 " >
21+ < div class = "flex " >
22+ < span class = "flex items-center text-sm text-gray-600 dark:text-gray-400 bg-white dark:bg-gray-800 px-4 py-2 border border-gray-300 dark:border-gray-700 rounded-md focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 hover:text-blue-500 hover:border-blue-600 " >
23+ < Icons . pause_circle class = "mr-2 h-5 w-5 " /> Pause
24+ </ span >
25+ </ div >
26+
27+ < div class = "flex " >
28+ < span class = "inline-flex items-center px-2.5 py-0.5 rounded-md text-sm font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300 " >
29+ < Icons . sparkles class = "mr-1 h-4 w-4 " /> Dynamic
30+ </ span >
31+ </ div >
3532 </ div >
3633 </ div >
3734
38- < div class = "grid grid-cols-5 gap-6 border-b border-gray-200 dark:border-gray-700 px-3 py-6 " >
39- <!-- Header section (2fr equivalent) -->
40- < div class = "col-span-2 " >
41- < div class = "flex items-start justify-between mb-4 " >
42- < h2 class = "text-xl font-bold text-gray-900 dark:text-gray-200 " >
43- { @ cron . worker }
44- </ h2 >
45- < Icons . sparkles
46- :if = { @ cron . dynamic? }
47- id = "cron-dynamic-indicator "
48- class = "w-6 h-6 text-amber-500 "
49- phx-hook = "Tippy "
50- data-title = "Dynamic cron "
51- />
35+ < div class = "grid grid-cols-4 gap-6 px-3 py-6 " >
36+ < div class = "col-span-3 " >
37+ < div class = "h-48 bg-gray-50 dark:bg-gray-800 rounded-md flex items-center justify-center " >
38+ < span class = "text-gray-400 text-sm " >
39+ Spark chart placeholder - execution history will be displayed here
40+ </ span >
5241 </ div >
42+ </ div >
5343
54- < div class = "space-y-3 " >
55- < div class = "flex flex-col " >
56- < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 " >
57- Schedule
58- </ span >
59- < code class = "font-mono text-sm text-gray-900 dark:text-gray-200 " > { @ cron . expression } </ code >
60- </ div >
61-
62- < div class = "flex flex-col " >
63- < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 " >
64- Type
65- </ span >
66- < span class = "text-sm text-gray-900 dark:text-gray-200 " >
67- { if @ cron . dynamic? , do: "Dynamic" , else: "Static" }
68- </ span >
69- </ div >
70-
44+ < div class = "col-span-1 " >
45+ < div class = "flex space-x-12 mb-6 " >
7146 < div class = "flex flex-col " >
72- < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 " >
47+ < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 mb-1 " >
7348 Last Run
7449 </ span >
75- < span class = "text-sm text-gray-900 dark:text-gray-200 " >
50+ < span class = "text-base text-gray-800 dark:text-gray-200 " >
7651 < span
77- :if = { @ cron . last_at }
7852 id = "cron-last-time "
7953 data-timestamp = { maybe_to_unix ( @ cron . last_at ) }
8054 phx-hook = "Relativize "
8155 phx-update = "ignore "
8256 >
8357 -
8458 </ span >
85- < span :if = { is_nil ( @ cron . last_at ) } class = "text-gray-400 " > Never</ span >
8659 </ span >
8760 </ div >
8861
8962 < div class = "flex flex-col " >
90- < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 " >
63+ < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 mb-1 " >
9164 Next Run
9265 </ span >
93- < span class = "text-sm text-gray-900 dark:text-gray-200 " >
66+ < span class = "text-base text-gray-800 dark:text-gray-200 " >
9467 < span
95- :if = { @ cron . next_at }
9668 id = "cron-next-time "
9769 data-timestamp = { maybe_to_unix ( @ cron . next_at ) }
9870 phx-hook = "Relativize "
9971 phx-update = "ignore "
10072 >
10173 -
10274 </ span >
103- < span :if = { is_nil ( @ cron . next_at ) } class = "text-gray-400 " > Not scheduled</ span >
10475 </ span >
10576 </ div >
77+ </ div >
10678
107- < div class = "flex flex-col " >
108- < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 " >
109- Status
110- </ span >
111- < span class = "flex items-center space-x-1 text-sm text-gray-900 dark:text-gray-200 " >
112- < . state_icon state = { @ cron . last_state } />
113- < span class = "capitalize " > { @ cron . last_state || "unknown" } </ span >
114- </ span >
115- </ div >
79+ < div class = "flex flex-col mb-6 " >
80+ < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 mb-1 " >
81+ Schedule
82+ </ span >
83+ < span class = "text-base text-gray-800 dark:text-gray-200 " >
84+ Every two minutes
85+ < code class = "font-mono text-gray-500 dark:text-gray-400 " > ({ @ cron . expression } )</ code >
86+ </ span >
11687 </ div >
117- </ div >
11888
119- <!-- Execution History section (3fr equivalent) -->
120- < div class = "col-span-3 " >
121- < h3 class = "flex font-semibold mb-3 space-x-2 text-gray-700 dark:text-gray-300 " >
122- < Icons . chart_bar_square />
123- < span > Execution History</ span >
124- </ h3 >
125- < div class = "h-32 bg-gray-50 dark:bg-gray-800 rounded-md flex items-center justify-center " >
126- < span class = "text-gray-400 text-sm " > Spark chart placeholder - execution history will be displayed here</ span >
89+ < div class = "flex flex-col mb-6 " >
90+ < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 mb-1 " >
91+ Timezone
92+ </ span >
93+ < span class = "text-base text-gray-800 dark:text-gray-200 " >
94+ America/Chicago
95+ </ span >
12796 </ div >
128- </ div >
129- </ div >
13097
131- <!-- Placeholder for dynamic cron edit form -->
132- <%= if @ cron . dynamic? do %>
133- < div class = "px-3 py-6 border-t border-gray-200 dark:border-gray-700 " >
134- < h3 class = "flex font-semibold mb-3 space-x-2 text-gray-400 " >
135- < Icons . cog_8_tooth />
136- < span > Configuration</ span >
137- </ h3 >
138- < div class = "bg-gray-50 dark:bg-gray-800 rounded-md p-4 " >
139- < span class = "text-gray-400 text-sm " > Dynamic cron edit form placeholder - configuration options will be displayed here</ span >
98+ < div class = "flex flex-col " >
99+ < span class = "uppercase font-semibold text-xs text-gray-500 dark:text-gray-400 mb-1 " >
100+ Last Status
101+ </ span >
102+
103+ < div class = "flex items-center space-x-1 " >
104+ < Icons . check_circle class = "w-5 h-5 text-cyan-400 " />
105+ < span class = "text-base text-gray-800 dark:text-gray-200 " >
106+ Completed
107+ </ span >
108+ </ div >
140109 </ div >
141110 </ div >
142- <% end % >
111+ </ div >
143112
144113 < div class = "px-3 py-6 border-t border-gray-200 dark:border-gray-700 " >
145114 < h3 class = "flex font-semibold mb-3 space-x-2 text-gray-400 " >
146- < Icons . command_line />
147- < span > Job Options </ span >
115+ < Icons . pencil_square />
116+ < span > Edit Configuration </ span >
148117 </ h3 >
149- < pre class = "font-mono text-sm text-gray-500 dark:text-gray-400 whitespace-pre-wrap break-all " > { format_opts ( @ cron . opts , @ resolver ) } </ pre >
118+ < form
119+ id = "cron-form "
120+ class = "grid grid-cols-3 gap-6 bg-gray-50 dark:bg-gray-800 rounded-md p-4 "
121+ phx-change = "form-change "
122+ phx-submit = "local-submit "
123+ >
124+ < . field label = "Schedule " />
125+
126+ < . field label = "Tags " />
127+
128+ < . field label = "Queue " />
129+
130+ < . field label = "Priority " />
131+
132+ < . field label = "Max Attempts " />
133+
134+ < . field label = "Guaranteed " />
135+
136+ < . field label = "Name " />
137+
138+ < . field label = "Args " colspan = "col-span-2 " />
139+ </ form >
150140 </ div >
151141 </ div >
152142 """
153143 end
154144
155- attr :state , :string , required: true
156- attr :rest , :global
145+ attr :colspan , :string , default: "col-span-1"
146+ attr :label , :string
157147
158- defp state_icon ( assigns ) do
148+ def field ( assigns ) do
159149 ~H"""
160- <%= case @ state do %>
161- <% "available" -> %>
162- < Icons . pause_circle class = "w-4 h-4 text-teal-400 " />
163- <% "cancelled" - > %>
164- < Icons . x_circle class = "w-4 h-4 text-violet-400 " />
165- <% "completed" - > %>
166- < Icons . check_circle class = "w-4 h-4 text-cyan-400 " />
167- <% "discarded" - > %>
168- < Icons . exclamation_circle class = "w-4 h-4 text-rose-400 " />
169- <% "executing" - > %>
170- < Icons . play_circle class = "w-4 h-4 text-orange-400 " />
171- <% "retryable" - > %>
172- < Icons . arrow_path class = "w-4 h-4 text-yellow-400 " />
173- <% "scheduled" -> %>
174- < Icons . play_circle class = "w-4 h-4 text-emerald-400 " />
175- <% _ -> %>
176- < Icons . minus_circle class = "w-4 h-4 text-gray-400 " />
177- <% end %>
150+ < div class = { [ @ colspan , "bg-green-100" ] } >
151+ < label > { @ label } </ label >
152+ </ div >
178153 """
179154 end
180155
@@ -188,13 +163,6 @@ defmodule Oban.Web.Crons.DetailComponent do
188163
189164 # Helpers
190165
191- defp format_opts ( opts , resolver ) do
192- case opts do
193- opts when map_size ( opts ) == 0 -> "{}"
194- opts -> Resolver . call_with_fallback ( resolver , :format_cron_opts , [ opts ] )
195- end
196- end
197-
198166 defp maybe_to_unix ( nil ) , do: ""
199167
200168 defp maybe_to_unix ( timestamp ) do
0 commit comments