towerops/lib/towerops_web/live/equipment_live/form.ex
2026-01-03 14:41:28 -06:00

156 lines
5 KiB
Elixir

defmodule ToweropsWeb.EquipmentLive.Form do
@moduledoc false
use ToweropsWeb, :live_view
alias Towerops.Equipment
alias Towerops.Equipment.Equipment, as: EquipmentSchema
alias Towerops.Sites
alias Towerops.Snmp
@impl true
def mount(params, _session, socket) do
organization = socket.assigns.current_organization
sites = Sites.list_organization_sites(organization.id)
{:ok,
socket
|> assign(:organization, organization)
|> assign(:available_sites, sites)
|> assign(:preselected_site_id, params["site_id"])
|> assign(:snmp_test_result, nil)}
end
@impl true
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end
defp apply_action(socket, :new, _params) do
equipment_attrs = %{
monitoring_enabled: true,
check_interval_seconds: 300,
snmp_enabled: true,
snmp_version: "2c",
snmp_port: 161
}
equipment_attrs =
if socket.assigns.preselected_site_id do
Map.put(equipment_attrs, :site_id, socket.assigns.preselected_site_id)
else
equipment_attrs
end
changeset = Equipment.change_equipment(%EquipmentSchema{}, equipment_attrs)
socket
|> assign(:page_title, "New Equipment")
|> assign(:equipment, %EquipmentSchema{})
|> assign(:form, to_form(changeset))
end
defp apply_action(socket, :edit, %{"id" => id}) do
equipment = Equipment.get_equipment!(id)
changeset = Equipment.change_equipment(equipment)
socket
|> assign(:page_title, "Edit Equipment")
|> assign(:equipment, equipment)
|> assign(:form, to_form(changeset))
end
@impl true
def handle_event("validate", %{"equipment" => equipment_params}, socket) do
changeset =
socket.assigns.equipment
|> Equipment.change_equipment(equipment_params)
|> Map.put(:action, :validate)
{:noreply, assign(socket, :form, to_form(changeset))}
end
@impl true
def handle_event("save", %{"equipment" => equipment_params}, socket) do
save_equipment(socket, socket.assigns.live_action, equipment_params)
end
@impl true
def handle_event("test_snmp", _params, socket) do
form_data = socket.assigns.form.data
params = socket.assigns.form.params
ip_address = params["ip_address"] || form_data.ip_address
snmp_community = params["snmp_community"] || form_data.snmp_community
snmp_version = params["snmp_version"] || form_data.snmp_version
snmp_port = params["snmp_port"] || form_data.snmp_port || 161
snmp_port =
case snmp_port do
port when is_integer(port) -> port
port when is_binary(port) -> String.to_integer(port)
_ -> 161
end
result =
case Snmp.test_connection(ip_address, snmp_community, snmp_version, snmp_port) do
{:ok, message} ->
%{success: true, message: message}
{:error, reason} ->
%{success: false, message: "Connection failed: #{inspect(reason)}"}
end
{:noreply, assign(socket, :snmp_test_result, result)}
end
defp save_equipment(socket, :new, equipment_params) do
case Equipment.create_equipment(equipment_params) do
{:ok, equipment} ->
# Start SNMP discovery in background if enabled
flash_message =
if equipment.snmp_enabled do
Task.start(fn -> Snmp.discover_equipment(equipment) end)
"Equipment created successfully. SNMP discovery started in background."
else
"Equipment created successfully"
end
{:noreply,
socket
|> put_flash(:info, flash_message)
|> push_navigate(to: ~p"/orgs/#{socket.assigns.organization.slug}/equipment/#{equipment.id}")}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :form, to_form(changeset))}
end
end
defp save_equipment(socket, :edit, equipment_params) do
old_equipment = socket.assigns.equipment
case Equipment.update_equipment(old_equipment, equipment_params) do
{:ok, equipment} ->
# Start SNMP discovery if SNMP was just enabled or configuration changed
flash_message =
if equipment.snmp_enabled and
(!old_equipment.snmp_enabled or
equipment.snmp_community != old_equipment.snmp_community or
equipment.snmp_version != old_equipment.snmp_version or
equipment.snmp_port != old_equipment.snmp_port or
equipment.ip_address != old_equipment.ip_address) do
Task.start(fn -> Snmp.discover_equipment(equipment) end)
"Equipment updated successfully. SNMP discovery started in background."
else
"Equipment updated successfully"
end
{:noreply,
socket
|> put_flash(:info, flash_message)
|> push_navigate(to: ~p"/orgs/#{socket.assigns.organization.slug}/equipment/#{equipment.id}")}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :form, to_form(changeset))}
end
end
end