feat: add Vereinfacht connection test button to settings
This commit is contained in:
parent
fca0194a7d
commit
f29bbb02a2
6 changed files with 389 additions and 9 deletions
|
|
@ -51,6 +51,7 @@ defmodule MvWeb.GlobalSettingsLive do
|
|||
|> assign(:vereinfacht_app_url_env_set, Mv.Config.vereinfacht_app_url_env_set?())
|
||||
|> assign(:vereinfacht_api_key_set, present?(settings.vereinfacht_api_key))
|
||||
|> assign(:last_vereinfacht_sync_result, nil)
|
||||
|> assign(:vereinfacht_test_result, nil)
|
||||
|> assign_form()
|
||||
|
||||
{:ok, socket}
|
||||
|
|
@ -167,15 +168,29 @@ defmodule MvWeb.GlobalSettingsLive do
|
|||
>
|
||||
{gettext("Save Vereinfacht Settings")}
|
||||
</.button>
|
||||
<.button
|
||||
:if={Mv.Config.vereinfacht_configured?()}
|
||||
type="button"
|
||||
phx-click="sync_vereinfacht_contacts"
|
||||
phx-disable-with={gettext("Syncing...")}
|
||||
class="mt-4 btn-outline"
|
||||
>
|
||||
{gettext("Sync all members without Vereinfacht contact")}
|
||||
</.button>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
<.button
|
||||
:if={Mv.Config.vereinfacht_configured?()}
|
||||
type="button"
|
||||
phx-click="test_vereinfacht_connection"
|
||||
phx-disable-with={gettext("Testing...")}
|
||||
class="btn-outline"
|
||||
>
|
||||
{gettext("Test Integration")}
|
||||
</.button>
|
||||
<.button
|
||||
:if={Mv.Config.vereinfacht_configured?()}
|
||||
type="button"
|
||||
phx-click="sync_vereinfacht_contacts"
|
||||
phx-disable-with={gettext("Syncing...")}
|
||||
class="btn-outline"
|
||||
>
|
||||
{gettext("Sync all members without Vereinfacht contact")}
|
||||
</.button>
|
||||
</div>
|
||||
<%= if @vereinfacht_test_result do %>
|
||||
<.vereinfacht_test_result result={@vereinfacht_test_result} />
|
||||
<% end %>
|
||||
<%= if @last_vereinfacht_sync_result do %>
|
||||
<.vereinfacht_sync_result result={@last_vereinfacht_sync_result} />
|
||||
<% end %>
|
||||
|
|
@ -207,6 +222,12 @@ defmodule MvWeb.GlobalSettingsLive do
|
|||
assign(socket, form: AshPhoenix.Form.validate(socket.assigns.form, setting_params))}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("test_vereinfacht_connection", _params, socket) do
|
||||
result = Mv.Vereinfacht.test_connection()
|
||||
{:noreply, assign(socket, :vereinfacht_test_result, result)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("sync_vereinfacht_contacts", _params, socket) do
|
||||
case Mv.Vereinfacht.sync_members_without_contact() do
|
||||
|
|
@ -246,15 +267,20 @@ defmodule MvWeb.GlobalSettingsLive do
|
|||
actor = MvWeb.LiveHelpers.current_actor(socket)
|
||||
# Never send blank API key so we do not overwrite the stored secret (security)
|
||||
setting_params_clean = drop_blank_vereinfacht_api_key(setting_params)
|
||||
saves_vereinfacht = vereinfacht_params?(setting_params_clean)
|
||||
|
||||
case MvWeb.LiveHelpers.submit_form(socket.assigns.form, setting_params_clean, actor) do
|
||||
{:ok, _updated_settings} ->
|
||||
{:ok, fresh_settings} = Membership.get_settings()
|
||||
|
||||
test_result =
|
||||
if saves_vereinfacht, do: Mv.Vereinfacht.test_connection(), else: nil
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:settings, fresh_settings)
|
||||
|> assign(:vereinfacht_api_key_set, present?(fresh_settings.vereinfacht_api_key))
|
||||
|> assign(:vereinfacht_test_result, test_result)
|
||||
|> put_flash(:info, gettext("Settings updated successfully"))
|
||||
|> assign_form()
|
||||
|
||||
|
|
@ -265,6 +291,12 @@ defmodule MvWeb.GlobalSettingsLive do
|
|||
end
|
||||
end
|
||||
|
||||
@vereinfacht_param_keys ~w[vereinfacht_api_url vereinfacht_api_key vereinfacht_club_id vereinfacht_app_url]
|
||||
|
||||
defp vereinfacht_params?(params) when is_map(params) do
|
||||
Enum.any?(@vereinfacht_param_keys, &Map.has_key?(params, &1))
|
||||
end
|
||||
|
||||
defp drop_blank_vereinfacht_api_key(params) when is_map(params) do
|
||||
case params do
|
||||
%{"vereinfacht_api_key" => v} when v in [nil, ""] ->
|
||||
|
|
@ -412,6 +444,109 @@ defmodule MvWeb.GlobalSettingsLive do
|
|||
Gettext.dgettext(MvWeb.Gettext, "default", message)
|
||||
end
|
||||
|
||||
attr :result, :any, required: true
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:ok, :connected}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-center gap-2 p-3 rounded-lg border border-success bg-success/10 text-success-aa text-sm">
|
||||
<.icon name="hero-check-circle" class="size-5 shrink-0" />
|
||||
<span>{gettext("Connection successful. API URL, API Key and Club ID are valid.")}</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, :not_configured}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-center gap-2 p-3 rounded-lg border border-warning bg-warning/10 text-warning-aa text-sm">
|
||||
<.icon name="hero-exclamation-triangle" class="size-5 shrink-0" />
|
||||
<span>{gettext("Not configured. Please set API URL, API Key and Club ID.")}</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, {:http, _status, :html_response}}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-start gap-2 p-3 rounded-lg border border-error bg-error/10 text-error-aa text-sm">
|
||||
<.icon name="hero-x-circle" class="size-5 shrink-0 mt-0.5" />
|
||||
<span>
|
||||
{gettext(
|
||||
"Connection failed. The URL does not point to a Vereinfacht API (received HTML instead of JSON)."
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, {:http, 401, _}}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-start gap-2 p-3 rounded-lg border border-error bg-error/10 text-error-aa text-sm">
|
||||
<.icon name="hero-x-circle" class="size-5 shrink-0 mt-0.5" />
|
||||
<span>{gettext("Connection failed (HTTP 401): API key is invalid or missing.")}</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, {:http, 403, _}}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-start gap-2 p-3 rounded-lg border border-error bg-error/10 text-error-aa text-sm">
|
||||
<.icon name="hero-x-circle" class="size-5 shrink-0 mt-0.5" />
|
||||
<span>
|
||||
{gettext(
|
||||
"Connection failed (HTTP 403): Access denied. Please check the Club ID and API key permissions."
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, {:http, 404, _}}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-start gap-2 p-3 rounded-lg border border-error bg-error/10 text-error-aa text-sm">
|
||||
<.icon name="hero-x-circle" class="size-5 shrink-0 mt-0.5" />
|
||||
<span>
|
||||
{gettext(
|
||||
"Connection failed (HTTP 404): API endpoint not found. Please check the API URL (e.g. correct version path)."
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, {:http, status, message}}} = assigns) do
|
||||
assigns = assign(assigns, :status, status)
|
||||
assigns = assign(assigns, :message, message)
|
||||
|
||||
~H"""
|
||||
<div class="mt-3 flex items-start gap-2 p-3 rounded-lg border border-error bg-error/10 text-error-aa text-sm">
|
||||
<.icon name="hero-x-circle" class="size-5 shrink-0 mt-0.5" />
|
||||
<span>
|
||||
{gettext("Connection failed (HTTP %{status}):", status: @status)}
|
||||
<span class="ml-1">{@message}</span>
|
||||
</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, {:request_failed, _reason}}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-center gap-2 p-3 rounded-lg border border-error bg-error/10 text-error-aa text-sm">
|
||||
<.icon name="hero-x-circle" class="size-5 shrink-0" />
|
||||
<span>
|
||||
{gettext("Connection failed. Could not reach the API (network error or wrong URL).")}
|
||||
</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp vereinfacht_test_result(%{result: {:error, _}} = assigns) do
|
||||
~H"""
|
||||
<div class="mt-3 flex items-center gap-2 p-3 rounded-lg border border-error bg-error/10 text-error-aa text-sm">
|
||||
<.icon name="hero-x-circle" class="size-5 shrink-0" />
|
||||
<span>{gettext("Connection failed. Unknown error.")}</span>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
attr :result, :map, required: true
|
||||
|
||||
defp vereinfacht_sync_result(assigns) do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue