Change temperature and voltage display to table format

- Replace grid of sensor cards with table format matching device info
- Display sensor name on left, value on right
- Make sensor names clickable links to graph detail page
- Remove generic "Sensors" section from overview
- Cleaner, more scannable layout for temperature and voltage sensors
This commit is contained in:
Graham McIntire 2026-01-05 11:14:59 -06:00
parent ddabb3f030
commit 06a31441f2
No known key found for this signature in database
2 changed files with 75 additions and 92 deletions

View file

@ -55,8 +55,12 @@ defmodule ToweropsWeb.EquipmentLive.Show do
cpu_chart_data = load_sensor_chart_data(equipment_id, ["cpu_load"])
memory_chart_data = load_sensor_chart_data(equipment_id, ["memory_usage"])
storage_chart_data = load_sensor_chart_data(equipment_id, ["disk_usage"])
temperature_chart_data = load_sensor_chart_data(equipment_id, ["temperature", "cpu_temperature", "celsius"])
voltage_chart_data = load_sensor_chart_data(equipment_id, ["voltage", "volts"])
# Filter sensors by type for temperature and voltage
temperature_sensors =
Enum.filter(snmp_data.sensors, &(&1.sensor_type in ["temperature", "cpu_temperature", "celsius"]))
voltage_sensors = Enum.filter(snmp_data.sensors, &(&1.sensor_type in ["voltage", "volts"]))
# Calculate metrics for dashboard
metrics = calculate_metrics(recent_checks, equipment)
@ -73,8 +77,8 @@ defmodule ToweropsWeb.EquipmentLive.Show do
|> assign(:cpu_chart_data, cpu_chart_data)
|> assign(:memory_chart_data, memory_chart_data)
|> assign(:storage_chart_data, storage_chart_data)
|> assign(:temperature_chart_data, temperature_chart_data)
|> assign(:voltage_chart_data, voltage_chart_data)
|> assign(:temperature_sensors, temperature_sensors)
|> assign(:voltage_sensors, voltage_sensors)
end
defp calculate_metrics(checks, _equipment) do

View file

@ -262,100 +262,79 @@
</div>
</div>
<% end %>
<!-- Temperature Chart -->
<%= if @temperature_chart_data do %>
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<.link
navigate={
~p"/orgs/#{@current_organization.slug}/equipment/#{@equipment.id}/graph/temperature"
}
class="block px-4 py-3 border-b border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-750 transition-colors"
>
<div class="flex items-center justify-between">
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
Temperature (24 Hours)
</h3>
<.icon name="hero-arrow-right" class="h-4 w-4 text-zinc-400" />
</div>
</.link>
<div class="p-4">
<div
id="temperature-chart"
phx-hook="SensorChart"
data-chart={@temperature_chart_data}
data-unit="°C"
data-auto-scale="true"
style="height: 300px;"
>
<canvas></canvas>
</div>
</div>
</div>
<% end %>
<!-- Voltage Chart -->
<%= if @voltage_chart_data do %>
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<.link
navigate={
~p"/orgs/#{@current_organization.slug}/equipment/#{@equipment.id}/graph/voltage"
}
class="block px-4 py-3 border-b border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-750 transition-colors"
>
<div class="flex items-center justify-between">
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
Voltage (24 Hours)
</h3>
<.icon name="hero-arrow-right" class="h-4 w-4 text-zinc-400" />
</div>
</.link>
<div class="p-4">
<div
id="voltage-chart"
phx-hook="SensorChart"
data-chart={@voltage_chart_data}
data-unit="V"
data-auto-scale="true"
style="height: 300px;"
>
<canvas></canvas>
</div>
</div>
</div>
<% end %>
<!-- Sensors -->
<%= if @snmp_sensors && length(@snmp_sensors) > 0 do %>
<!-- Temperature Sensors -->
<%= if @temperature_sensors && length(@temperature_sensors) > 0 do %>
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">Sensors</h3>
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
Temperature
</h3>
</div>
<div class="p-4">
<div class="grid grid-cols-2 md:grid-cols-3 gap-3">
<%= for sensor <- @snmp_sensors do %>
<div class="bg-zinc-50 dark:bg-zinc-900 rounded p-2 border border-zinc-200 dark:border-zinc-700">
<div
class="text-xs text-zinc-600 dark:text-zinc-400 truncate"
title={sensor.sensor_descr}
>
{sensor.sensor_descr}
</div>
<%= if sensor.latest_reading do %>
<div class="mt-1 flex items-baseline gap-1">
<span class="text-lg font-bold text-zinc-900 dark:text-zinc-100">
{format_sensor_value(
sensor.latest_reading.value,
sensor.sensor_divisor
)}
</span>
<span class="text-xs text-zinc-600 dark:text-zinc-400">
{sensor.sensor_unit}
</span>
</div>
<% else %>
<div class="mt-1 text-xs text-zinc-500 dark:text-zinc-500">No data</div>
<% end %>
<dl class="space-y-3">
<%= for sensor <- @temperature_sensors do %>
<div class="flex justify-between py-2 border-b border-zinc-100 dark:border-zinc-800">
<dt class="text-sm text-zinc-600 dark:text-zinc-400">
<.link
navigate={
~p"/orgs/#{@current_organization.slug}/equipment/#{@equipment.id}/graph/temperature"
}
class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
>
{sensor.sensor_descr}
</.link>
</dt>
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
<%= if sensor.latest_reading do %>
{format_sensor_value(
sensor.latest_reading.value,
sensor.sensor_divisor
)}
{sensor.sensor_unit}
<% else %>
N/A
<% end %>
</dd>
</div>
<% end %>
</div>
</dl>
</div>
</div>
<% end %>
<!-- Voltage Sensors -->
<%= if @voltage_sensors && length(@voltage_sensors) > 0 do %>
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">Voltage</h3>
</div>
<div class="p-4">
<dl class="space-y-3">
<%= for sensor <- @voltage_sensors do %>
<div class="flex justify-between py-2 border-b border-zinc-100 dark:border-zinc-800">
<dt class="text-sm text-zinc-600 dark:text-zinc-400">
<.link
navigate={
~p"/orgs/#{@current_organization.slug}/equipment/#{@equipment.id}/graph/voltage"
}
class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
>
{sensor.sensor_descr}
</.link>
</dt>
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
<%= if sensor.latest_reading do %>
{format_sensor_value(
sensor.latest_reading.value,
sensor.sensor_divisor
)}
{sensor.sensor_unit}
<% else %>
N/A
<% end %>
</dd>
</div>
<% end %>
</dl>
</div>
</div>
<% end %>