diff --git a/lib/towerops_web/live/device_live/index.ex b/lib/towerops_web/live/device_live/index.ex index 16431385..cd8c0db2 100644 --- a/lib/towerops_web/live/device_live/index.ex +++ b/lib/towerops_web/live/device_live/index.ex @@ -12,36 +12,19 @@ defmodule ToweropsWeb.DeviceLive.Index do organization = socket.assigns.current_organization device = Devices.list_organization_devices(organization.id) sites = Sites.list_organization_sites(organization.id) + grouped_devices = group_devices_by_site(device) {:ok, socket |> assign(:page_title, "Devices") |> assign(:device, device) + |> assign(:grouped_devices, grouped_devices) |> assign(:has_sites, sites != [])} end @impl true - def handle_params(params, _url, socket) do - tab = Map.get(params, "tab", "existing") - {:noreply, apply_action(socket, socket.assigns.live_action, params, tab)} - end - - defp apply_action(socket, :index, _params, tab) do - organization = socket.assigns.current_organization - - case tab do - "discovered" -> - discovered = Snmp.list_discovered_devices_for_organization(organization.id) - - socket - |> assign(:active_tab, "discovered") - |> assign(:discovered_devices, discovered) - - _ -> - socket - |> assign(:active_tab, "existing") - |> assign(:discovered_devices, []) - end + def handle_params(_params, _url, socket) do + {:noreply, assign(socket, :live_action, :index)} end @impl true @@ -83,15 +66,24 @@ defmodule ToweropsWeb.DeviceLive.Index do end end - # Device type icon helpers - defp device_type_icon(:router), do: "hero-signal" - defp device_type_icon(:switch), do: "hero-squares-2x2" - defp device_type_icon(:wireless), do: "hero-wifi" - defp device_type_icon(:server), do: "hero-server" - defp device_type_icon(:workstation), do: "hero-computer-desktop" - defp device_type_icon(_), do: "hero-question-mark-circle" + # Group devices by site with statistics + defp group_devices_by_site(devices) do + devices + |> Enum.group_by(& &1.site) + |> Enum.map(fn {site, site_devices} -> + {site, site_devices, calculate_site_stats(site_devices)} + end) + |> Enum.sort_by(fn {site, _devices, _stats} -> site.name end, :asc) + end - defp device_type_label(type) do - type |> to_string() |> String.capitalize() + defp calculate_site_stats(devices) do + status_counts = Enum.frequencies_by(devices, & &1.status) + + %{ + total: length(devices), + up: Map.get(status_counts, :up, 0), + down: Map.get(status_counts, :down, 0), + unknown: Map.get(status_counts, :unknown, 0) + } end end diff --git a/lib/towerops_web/live/device_live/index.html.heex b/lib/towerops_web/live/device_live/index.html.heex index 793aa122..d6d37cb9 100644 --- a/lib/towerops_web/live/device_live/index.html.heex +++ b/lib/towerops_web/live/device_live/index.html.heex @@ -27,247 +27,158 @@ - - -
- Before adding device, you need to create at least one site location. -
-- Sites help you organize your devices by physical location. -
-+ Before adding device, you need to create at least one site location. +
++ Sites help you organize your devices by physical location. +
++ Get started by adding your first device. +
+| + Name + | ++ IP Address + | ++ Status + | ++ Last Checked + | +
|---|---|---|---|
|
+
+
+
+ <.link
+ navigate={~p"/sites/#{site.id}"}
+ class="text-sm font-semibold text-gray-900 dark:text-white hover:text-blue-600 dark:hover:text-blue-400"
+ >
+ {site.name}
+
+ ยท
+
+ {stats.total} {if stats.total == 1, do: "device", else: "devices"}
+
+ 0}
+ class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"
+ >
+ {stats.up} up
+
+ 0}
+ class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"
+ >
+ {stats.down} down
+
+
+ + <.icon name="hero-map-pin" class="inline h-3 w-3" /> {site.location} + + |
+ |||
| + {device.name} + | ++ {device.ip_address} + | ++ + {device.status |> to_string() |> String.upcase()} + + | ++ <.timestamp datetime={device.last_checked_at} timezone={@timezone} /> + | +
- Get started by adding your first device. -
-- All discovered devices have been added, or no devices have been discovered yet via LLDP, CDP, or ARP. -
-