Skip to content

Commit 751bc0d

Browse files
committed
Style and layout work for cron detail component
1 parent 59b1701 commit 751bc0d

File tree

5 files changed

+137
-168
lines changed

5 files changed

+137
-168
lines changed

lib/oban/web/components/icons.ex

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,11 @@ defmodule Oban.Web.Components.Icons do
170170
def cog_8_tooth(assigns) do
171171
~H"""
172172
<.svg_outline {@rest}>
173-
<path stroke-linecap="round" stroke-linejoin="round" d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 0 1 1.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.559.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.894.149c-.424.07-.764.383-.929.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 0 1-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.398.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 0 1-.12-1.45l.527-.737c.25-.35.272-.806.108-1.204-.165-.397-.506-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.108-1.204l-.526-.738a1.125 1.125 0 0 1 .12-1.45l.773-.773a1.125 1.125 0 0 1 1.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894Z" />
173+
<path
174+
stroke-linecap="round"
175+
stroke-linejoin="round"
176+
d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 0 1 1.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.559.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.894.149c-.424.07-.764.383-.929.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 0 1-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.398.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 0 1-.12-1.45l.527-.737c.25-.35.272-.806.108-1.204-.165-.397-.506-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.108-1.204l-.526-.738a1.125 1.125 0 0 1 .12-1.45l.773-.773a1.125 1.125 0 0 1 1.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894Z"
177+
/>
174178
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
175179
</.svg_outline>
176180
"""
@@ -580,7 +584,11 @@ defmodule Oban.Web.Components.Icons do
580584
def pencil_square(assigns) do
581585
~H"""
582586
<.svg_outline {@rest}>
583-
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
587+
<path
588+
stroke-linecap="round"
589+
stroke-linejoin="round"
590+
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
591+
/>
584592
</.svg_outline>
585593
"""
586594
end

lib/oban/web/components/sidebar_components.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ defmodule Oban.Web.SidebarComponents do
2828
<h3 class="dark:text-gray-200 font-bold">{String.capitalize(@name)}</h3>
2929
3030
<div class="ml-auto flex space-x-2 text-right text-xs tracking-tight text-gray-600 dark:text-gray-400 uppercase">
31-
<span :for={header <- @headers} class="w-10">{header}</span>
31+
<span :for={header <- @headers} class="w-12">{header}</span>
3232
</div>
3333
</header>
3434

lib/oban/web/live/crons/detail_component.ex

Lines changed: 84 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
defmodule 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

Comments
 (0)