feat: enhance active operations display with device context
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2fb0101bab
commit
daa223c49d
3 changed files with 50 additions and 27 deletions
|
|
@ -29,6 +29,7 @@ defmodule Towerops.JobMonitoring do
|
|||
order_by: [asc: j.attempted_at]
|
||||
)
|
||||
|> Repo.all()
|
||||
|> preload_device_context()
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
@ -86,4 +87,13 @@ defmodule Towerops.JobMonitoring do
|
|||
)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
# Add helper to fetch device context
|
||||
defp preload_device_context(jobs) do
|
||||
Enum.map(jobs, fn job ->
|
||||
device_id = get_in(job.args, ["device_id"])
|
||||
device = device_id && Towerops.Repo.get(Towerops.Devices.Device, device_id)
|
||||
Map.put(job, :device, device)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ defmodule ToweropsWeb.Admin.MonitoringLive do
|
|||
socket
|
||||
|> assign(:page_title, "Job Monitoring")
|
||||
|> assign(:active_jobs, [])
|
||||
|> assign(:executing_jobs, [])
|
||||
|> assign(:stuck_jobs_count, 0)
|
||||
|> assign(:failed_jobs_count, 0)
|
||||
|> assign(:recent_jobs, [])
|
||||
|
|
@ -59,15 +60,21 @@ defmodule ToweropsWeb.Admin.MonitoringLive do
|
|||
|
||||
@spec load_monitoring_data(Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
|
||||
defp load_monitoring_data(socket) do
|
||||
executing_jobs = JobMonitoring.list_active_jobs()
|
||||
stuck_jobs = JobMonitoring.list_stuck_jobs()
|
||||
failed_jobs = JobMonitoring.list_failed_jobs()
|
||||
recent_jobs = JobMonitoring.list_recent_completions(20)
|
||||
metrics = Metrics.calculate_all()
|
||||
|
||||
socket
|
||||
|> assign(:executing_jobs, executing_jobs)
|
||||
|> assign(:stuck_jobs_count, length(stuck_jobs))
|
||||
|> assign(:failed_jobs_count, length(failed_jobs))
|
||||
|> assign(:recent_jobs, recent_jobs)
|
||||
|> assign(:health_metrics, metrics)
|
||||
end
|
||||
|
||||
defp worker_name("Towerops.Workers.DevicePollerWorker"), do: "Device Poll"
|
||||
defp worker_name("Towerops.Workers.DiscoveryWorker"), do: "SNMP Discovery"
|
||||
defp worker_name(worker), do: worker
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,35 +49,41 @@
|
|||
</div>
|
||||
|
||||
<!-- Active Operations -->
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">Active Operations</h2>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<%= if @active_jobs == [] do %>
|
||||
<p class="text-gray-500 dark:text-gray-400 text-center py-8">
|
||||
No active jobs
|
||||
</p>
|
||||
<% else %>
|
||||
<div class="space-y-2">
|
||||
<%= for job <- @active_jobs do %>
|
||||
<div class="flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-900/50 rounded">
|
||||
<div>
|
||||
<span class="font-mono text-sm text-gray-900 dark:text-white">
|
||||
{job.worker |> String.split(".") |> List.last()}
|
||||
</span>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400 ml-2">
|
||||
Device ID: {job.device_id}
|
||||
</span>
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-4">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">
|
||||
Active Operations ({length(@executing_jobs)})
|
||||
</h2>
|
||||
|
||||
<%= if length(@executing_jobs) == 0 do %>
|
||||
<p class="text-gray-600 dark:text-gray-400 text-sm">No jobs currently executing</p>
|
||||
<% else %>
|
||||
<div class="space-y-3">
|
||||
<%= for job <- @executing_jobs do %>
|
||||
<div class="border border-gray-200 dark:border-gray-700 rounded p-3">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex-1">
|
||||
<p class="font-medium text-gray-900 dark:text-white">
|
||||
<%= if job.device do %>
|
||||
<%= job.device.name %>
|
||||
<% else %>
|
||||
Device #{get_in(job.args, ["device_id"])}
|
||||
<% end %>
|
||||
</p>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<%= worker_name(job.worker) %>
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-500 mt-1">
|
||||
Started <%= ToweropsWeb.TimeHelpers.format_time_ago(job.attempted_at) %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<.icon name="hero-arrow-path" class="w-4 h-4 animate-spin text-blue-600" />
|
||||
</div>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Started: {Calendar.strftime(job.timestamp, "%H:%M:%S")}
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<!-- Problems -->
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue