fix: NetBox sync direction/checkboxes now reactive - track config in socket assigns instead of reading from saved credentials

This commit is contained in:
Graham McIntire 2026-02-14 14:30:45 -06:00
parent 5327c5fb58
commit 47f9ee703f
2 changed files with 67 additions and 25 deletions

View file

@ -75,6 +75,7 @@ defmodule ToweropsWeb.Org.SettingsLive do
|> assign(:configuring, nil)
|> assign(:integration_form, nil)
|> assign(:test_result, nil)
|> assign(:netbox_config, default_netbox_config())
|> assign(:timezone, socket.assigns.current_scope.timezone)}
end
@ -284,6 +285,13 @@ defmodule ToweropsWeb.Org.SettingsLive do
|> to_form()
end
socket =
if provider == "netbox" do
assign(socket, :netbox_config, load_netbox_config(integration))
else
socket
end
{:noreply,
socket
|> assign(:configuring, provider)
@ -310,6 +318,22 @@ defmodule ToweropsWeb.Org.SettingsLive do
|> Integrations.change_integration(normalize_params(params, integration))
|> Map.put(:action, :validate)
socket =
if socket.assigns.configuring == "netbox" do
assign(socket, :netbox_config, %{
"sync_direction" => Map.get(params, "sync_direction", "pull"),
"sync_devices" => Map.get(params, "sync_devices", "true") == "true",
"sync_sites" => Map.get(params, "sync_sites", "true") == "true",
"sync_ip_addresses" => Map.get(params, "sync_ip_addresses", "false") == "true",
"sync_interfaces" => Map.get(params, "sync_interfaces", "false") == "true",
"device_role_filter" => Map.get(params, "device_role_filter", ""),
"site_filter" => Map.get(params, "site_filter", ""),
"tag_filter" => Map.get(params, "tag_filter", "")
})
else
socket
end
{:noreply, assign(socket, :integration_form, to_form(changeset))}
end
@ -579,4 +603,34 @@ defmodule ToweropsWeb.Org.SettingsLive do
Logger.warning("Integration connection test failed: #{inspect(reason)}")
{:error, "Connection failed - please check your API credentials and try again"}
end
defp default_netbox_config do
%{
"sync_direction" => "pull",
"sync_devices" => true,
"sync_sites" => true,
"sync_ip_addresses" => false,
"sync_interfaces" => false,
"device_role_filter" => "",
"site_filter" => "",
"tag_filter" => ""
}
end
defp load_netbox_config(nil), do: default_netbox_config()
defp load_netbox_config(%Integration{credentials: creds}) when is_map(creds) do
%{
"sync_direction" => Map.get(creds, "sync_direction", "pull"),
"sync_devices" => Map.get(creds, "sync_devices", true),
"sync_sites" => Map.get(creds, "sync_sites", true),
"sync_ip_addresses" => Map.get(creds, "sync_ip_addresses", false),
"sync_interfaces" => Map.get(creds, "sync_interfaces", false),
"device_role_filter" => Map.get(creds, "device_role_filter", ""),
"site_filter" => Map.get(creds, "site_filter", ""),
"tag_filter" => Map.get(creds, "tag_filter", "")
}
end
defp load_netbox_config(_), do: default_netbox_config()
end

View file

@ -1141,7 +1141,7 @@
<label class={[
"relative flex cursor-pointer rounded-lg border p-4 shadow-xs transition-all focus:outline-none",
if(
get_credential(@integrations["netbox"], "sync_direction") in [
@netbox_config["sync_direction"] in [
"pull",
"",
nil
@ -1157,7 +1157,7 @@
name="integration[sync_direction]"
value="pull"
checked={
get_credential(@integrations["netbox"], "sync_direction") in [
@netbox_config["sync_direction"] in [
"pull",
"",
nil
@ -1178,7 +1178,7 @@
<label class={[
"relative flex cursor-pointer rounded-lg border p-4 shadow-xs transition-all focus:outline-none",
if(
get_credential(@integrations["netbox"], "sync_direction") == "push",
@netbox_config["sync_direction"] == "push",
do:
"border-indigo-600 ring-2 ring-indigo-600 bg-indigo-50 dark:bg-indigo-900/20",
else:
@ -1190,9 +1190,7 @@
name="integration[sync_direction]"
value="push"
class="sr-only"
checked={
get_credential(@integrations["netbox"], "sync_direction") == "push"
}
checked={@netbox_config["sync_direction"] == "push"}
/>
<div class="flex flex-col">
<span class="flex items-center gap-1.5 text-sm font-semibold text-gray-900 dark:text-white">
@ -1207,7 +1205,7 @@
<label class={[
"relative flex cursor-pointer rounded-lg border p-4 shadow-xs transition-all focus:outline-none",
if(
get_credential(@integrations["netbox"], "sync_direction") == "both",
@netbox_config["sync_direction"] == "both",
do:
"border-indigo-600 ring-2 ring-indigo-600 bg-indigo-50 dark:bg-indigo-900/20",
else:
@ -1219,9 +1217,7 @@
name="integration[sync_direction]"
value="both"
class="sr-only"
checked={
get_credential(@integrations["netbox"], "sync_direction") == "both"
}
checked={@netbox_config["sync_direction"] == "both"}
/>
<div class="flex flex-col">
<span class="flex items-center gap-1.5 text-sm font-semibold text-gray-900 dark:text-white">
@ -1260,9 +1256,7 @@
type="checkbox"
name="integration[sync_devices]"
value="true"
checked={
get_credential(@integrations["netbox"], "sync_devices") != "false"
}
checked={@netbox_config["sync_devices"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
/>
<div>
@ -1284,9 +1278,7 @@
type="checkbox"
name="integration[sync_sites]"
value="true"
checked={
get_credential(@integrations["netbox"], "sync_sites") != "false"
}
checked={@netbox_config["sync_sites"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
/>
<div>
@ -1308,9 +1300,7 @@
type="checkbox"
name="integration[sync_ip_addresses]"
value="true"
checked={
get_credential(@integrations["netbox"], "sync_ip_addresses") == "true"
}
checked={@netbox_config["sync_ip_addresses"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
/>
<div>
@ -1332,9 +1322,7 @@
type="checkbox"
name="integration[sync_interfaces]"
value="true"
checked={
get_credential(@integrations["netbox"], "sync_interfaces") == "true"
}
checked={@netbox_config["sync_interfaces"]}
class="mt-0.5 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
/>
<div>
@ -1371,7 +1359,7 @@
<input
type="text"
name="integration[device_role_filter]"
value={get_credential(@integrations["netbox"], "device_role_filter")}
value={@netbox_config["device_role_filter"]}
placeholder="e.g. access-point, router"
class="block w-full rounded-md border-gray-300 py-1.5 text-sm shadow-xs dark:border-white/10 dark:bg-white/5 dark:text-white"
/>
@ -1383,7 +1371,7 @@
<input
type="text"
name="integration[site_filter]"
value={get_credential(@integrations["netbox"], "site_filter")}
value={@netbox_config["site_filter"]}
placeholder="e.g. tower-north, main-pop"
class="block w-full rounded-md border-gray-300 py-1.5 text-sm shadow-xs dark:border-white/10 dark:bg-white/5 dark:text-white"
/>
@ -1395,7 +1383,7 @@
<input
type="text"
name="integration[tag_filter]"
value={get_credential(@integrations["netbox"], "tag_filter")}
value={@netbox_config["tag_filter"]}
placeholder="e.g. monitored, production"
class="block w-full rounded-md border-gray-300 py-1.5 text-sm shadow-xs dark:border-white/10 dark:bg-white/5 dark:text-white"
/>