diff --git a/lib/mix/tasks/populate_english.ex b/lib/mix/tasks/populate_english.ex index 78d87330..6d748576 100644 --- a/lib/mix/tasks/populate_english.ex +++ b/lib/mix/tasks/populate_english.ex @@ -65,38 +65,46 @@ defmodule Mix.Tasks.PopulateEnglish do defp process_lines([], acc), do: acc defp process_lines([line | rest], acc) do - # Found msgid line if String.starts_with?(line, "msgid ") do - {msgid_lines, remaining} = collect_string_lines([line | rest], []) - - # Check if this is a plural form (msgid_plural follows) - if is_plural_form?(remaining) do - # Skip plural forms - they need special handling - {plural_lines, remaining2} = skip_plural_translation(remaining, []) - new_acc = Enum.reverse(plural_lines, Enum.reverse(msgid_lines, acc)) - process_lines(remaining2, new_acc) - else - {msgstr_lines, remaining2} = collect_msgstr_lines(remaining, []) - - msgid_value = extract_string_value(msgid_lines) - - # If msgstr is empty and msgid is not empty, populate it - updated_msgstr = - if should_populate?(msgid_value, msgstr_lines) do - populate_msgstr(msgid_lines, msgid_value) - else - msgstr_lines - end - - new_acc = Enum.reverse(updated_msgstr, Enum.reverse(msgid_lines, acc)) - process_lines(remaining2, new_acc) - end + process_msgid_line([line | rest], acc) else # Regular line (comments, metadata, blank lines) process_lines(rest, [line | acc]) end end + defp process_msgid_line(lines, acc) do + {msgid_lines, remaining} = collect_string_lines(lines, []) + + # Check if this is a plural form (msgid_plural follows) + if plural_form?(remaining) do + process_plural_form(msgid_lines, remaining, acc) + else + process_singular_form(msgid_lines, remaining, acc) + end + end + + defp process_plural_form(msgid_lines, remaining, acc) do + {plural_lines, remaining2} = skip_plural_translation(remaining, []) + new_acc = Enum.reverse(plural_lines, Enum.reverse(msgid_lines, acc)) + process_lines(remaining2, new_acc) + end + + defp process_singular_form(msgid_lines, remaining, acc) do + {msgstr_lines, remaining2} = collect_msgstr_lines(remaining, []) + msgid_value = extract_string_value(msgid_lines) + + updated_msgstr = + if should_populate?(msgid_value, msgstr_lines) do + populate_msgstr(msgid_lines, msgid_value) + else + msgstr_lines + end + + new_acc = Enum.reverse(updated_msgstr, Enum.reverse(msgid_lines, acc)) + process_lines(remaining2, new_acc) + end + # Collect lines that are part of a msgid string (including continuation lines) defp collect_string_lines([], acc), do: {Enum.reverse(acc), []} @@ -205,9 +213,9 @@ defmodule Mix.Tasks.PopulateEnglish do end) end - defp is_plural_form?([]), do: false + defp plural_form?([]), do: false - defp is_plural_form?([line | _rest]) do + defp plural_form?([line | _rest]) do String.starts_with?(line, "msgid_plural ") end diff --git a/lib/towerops/devices/device.ex b/lib/towerops/devices/device.ex index cb77d8d3..814c2980 100644 --- a/lib/towerops/devices/device.ex +++ b/lib/towerops/devices/device.ex @@ -222,19 +222,30 @@ defmodule Towerops.Devices.Device do defp update_mikrotik_credential_source(changeset) do # If user explicitly set a username, mark source as "device" - # If it's blank/nil, mark source as "site" (will inherit from site or org) - case get_change(changeset, :mikrotik_username) do - nil -> - # No change to username, keep existing source - changeset + # If it's blank/nil/cleared, mark source as "site" (will inherit from site or org) + username_change = get_change(changeset, :mikrotik_username) + current_username = get_field(changeset, :mikrotik_username) - "" -> - # Explicitly cleared, set to inherit from site + cond do + # Explicitly set to empty string - clear and inherit + username_change == "" -> + changeset + |> put_change(:mikrotik_username, nil) + |> put_change(:mikrotik_credential_source, "site") + + # Explicitly set to a value - mark as device-specific + username_change != nil && username_change != "" -> + put_change(changeset, :mikrotik_credential_source, "device") + + # No change to username, but check if we should reset source + # (This handles cases where other MikroTik fields are cleared) + username_change == nil && (current_username == nil || current_username == "") && + get_field(changeset, :mikrotik_credential_source) == "device" -> put_change(changeset, :mikrotik_credential_source, "site") - _value -> - # Explicitly set a value, mark as device-specific - put_change(changeset, :mikrotik_credential_source, "device") + # No change, keep existing + true -> + changeset end end end diff --git a/lib/towerops/organizations.ex b/lib/towerops/organizations.ex index 391769f9..0fcf4c6a 100644 --- a/lib/towerops/organizations.ex +++ b/lib/towerops/organizations.ex @@ -115,6 +115,11 @@ defmodule Towerops.Organizations do """ def update_organization(%Organization{} = organization, attrs) do old_community = organization.snmp_community + old_mikrotik_username = organization.mikrotik_username + old_mikrotik_password = organization.mikrotik_password + old_mikrotik_port = organization.mikrotik_port + old_mikrotik_use_ssl = organization.mikrotik_use_ssl + old_mikrotik_enabled = organization.mikrotik_enabled case organization |> Organization.changeset(attrs) @@ -128,6 +133,29 @@ defmodule Towerops.Organizations do ) end + # If any MikroTik settings changed, propagate to inheriting devices + mikrotik_changed = + updated_organization.mikrotik_username != old_mikrotik_username || + updated_organization.mikrotik_password != old_mikrotik_password || + updated_organization.mikrotik_port != old_mikrotik_port || + updated_organization.mikrotik_use_ssl != old_mikrotik_use_ssl || + updated_organization.mikrotik_enabled != old_mikrotik_enabled + + if mikrotik_changed do + mikrotik_attrs = %{ + mikrotik_username: updated_organization.mikrotik_username, + mikrotik_password: updated_organization.mikrotik_password, + mikrotik_port: updated_organization.mikrotik_port, + mikrotik_use_ssl: updated_organization.mikrotik_use_ssl, + mikrotik_enabled: updated_organization.mikrotik_enabled + } + + Towerops.Devices.propagate_organization_mikrotik_change( + updated_organization.id, + mikrotik_attrs + ) + end + result error -> diff --git a/lib/towerops/sites.ex b/lib/towerops/sites.ex index 980451d0..e2bb7725 100644 --- a/lib/towerops/sites.ex +++ b/lib/towerops/sites.ex @@ -107,6 +107,11 @@ defmodule Towerops.Sites do """ def update_site(%Site{} = site, attrs) do old_community = site.snmp_community + old_mikrotik_username = site.mikrotik_username + old_mikrotik_password = site.mikrotik_password + old_mikrotik_port = site.mikrotik_port + old_mikrotik_use_ssl = site.mikrotik_use_ssl + old_mikrotik_enabled = site.mikrotik_enabled case site |> Site.changeset(attrs) @@ -117,6 +122,26 @@ defmodule Towerops.Sites do Towerops.Devices.propagate_site_community_change(updated_site.id, updated_site.snmp_community) end + # If any MikroTik settings changed, propagate to inheriting devices + mikrotik_changed = + updated_site.mikrotik_username != old_mikrotik_username || + updated_site.mikrotik_password != old_mikrotik_password || + updated_site.mikrotik_port != old_mikrotik_port || + updated_site.mikrotik_use_ssl != old_mikrotik_use_ssl || + updated_site.mikrotik_enabled != old_mikrotik_enabled + + if mikrotik_changed do + mikrotik_attrs = %{ + mikrotik_username: updated_site.mikrotik_username, + mikrotik_password: updated_site.mikrotik_password, + mikrotik_port: updated_site.mikrotik_port, + mikrotik_use_ssl: updated_site.mikrotik_use_ssl, + mikrotik_enabled: updated_site.mikrotik_enabled + } + + Towerops.Devices.propagate_site_mikrotik_change(updated_site.id, mikrotik_attrs) + end + result error -> diff --git a/lib/towerops_web/controllers/user_registration_html/new.html.heex b/lib/towerops_web/controllers/user_registration_html/new.html.heex index 5c74ece7..cfe3cd02 100644 --- a/lib/towerops_web/controllers/user_registration_html/new.html.heex +++ b/lib/towerops_web/controllers/user_registration_html/new.html.heex @@ -22,7 +22,10 @@ <%= if @invitation do %>
- {t_auth("You've been invited to join %{organization} as a %{role}.", organization: @invitation.organization.name, role: @invitation.role)} + {t_auth("You've been invited to join %{organization} as a %{role}.", + organization: @invitation.organization.name, + role: @invitation.role + )}
- {t_auth("To see sent emails, visit %{link}.", link: raw(~s(#{t_auth("the mailbox page")})))} + {t_auth("To see sent emails, visit %{link}.", + link: + raw( + ~s(#{t_auth("the mailbox page")}) + ) + )}
@@ -84,7 +89,7 @@ - + <.form :let={f} for={@form} as={:user} id="login_form_magic" action={~p"/users/log-in"}> <.input