200 lines
5.5 KiB
Elixir
200 lines
5.5 KiB
Elixir
defmodule ToweropsWeb.Org.IntegrationsLive do
|
|
@moduledoc false
|
|
use ToweropsWeb, :live_view
|
|
|
|
alias Towerops.Integrations
|
|
alias Towerops.Integrations.Integration
|
|
alias Towerops.Preseem.Client, as: PreseemClient
|
|
|
|
@providers [
|
|
%{
|
|
id: "preseem",
|
|
name: "Preseem",
|
|
description: "QoE monitoring and subscriber experience analytics for wireless ISPs.",
|
|
icon: "hero-signal"
|
|
}
|
|
]
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
organization = socket.assigns.current_scope.organization
|
|
integrations = load_integrations(organization.id)
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:organization, organization)
|
|
|> assign(:providers, @providers)
|
|
|> assign(:integrations, integrations)
|
|
|> assign(:configuring, nil)
|
|
|> assign(:form, nil)
|
|
|> assign(:test_result, nil)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("configure", %{"provider" => provider}, socket) do
|
|
integration = Map.get(socket.assigns.integrations, provider)
|
|
|
|
form =
|
|
case integration do
|
|
nil ->
|
|
%Integration{}
|
|
|> Integrations.change_integration(%{provider: provider})
|
|
|> to_form()
|
|
|
|
existing ->
|
|
existing
|
|
|> Integrations.change_integration(%{})
|
|
|> to_form()
|
|
end
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(:configuring, provider)
|
|
|> assign(:form, form)
|
|
|> assign(:test_result, nil)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("close_config", _params, socket) do
|
|
{:noreply,
|
|
socket
|
|
|> assign(:configuring, nil)
|
|
|> assign(:form, nil)
|
|
|> assign(:test_result, nil)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("validate", %{"integration" => params}, socket) do
|
|
integration = get_current_integration(socket)
|
|
|
|
changeset =
|
|
integration
|
|
|> Integrations.change_integration(normalize_params(params))
|
|
|> Map.put(:action, :validate)
|
|
|
|
{:noreply, assign(socket, :form, to_form(changeset))}
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("save", %{"integration" => params}, socket) do
|
|
organization = socket.assigns.organization
|
|
provider = socket.assigns.configuring
|
|
existing = Map.get(socket.assigns.integrations, provider)
|
|
attrs = normalize_params(params)
|
|
|
|
result =
|
|
case existing do
|
|
nil ->
|
|
Integrations.create_integration(organization.id, Map.put(attrs, :provider, provider))
|
|
|
|
integration ->
|
|
Integrations.update_integration(integration, attrs)
|
|
end
|
|
|
|
case result do
|
|
{:ok, _integration} ->
|
|
integrations = load_integrations(organization.id)
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(:integrations, integrations)
|
|
|> assign(:configuring, nil)
|
|
|> assign(:form, nil)
|
|
|> assign(:test_result, nil)
|
|
|> put_flash(:info, "Integration saved successfully")}
|
|
|
|
{:error, changeset} ->
|
|
{:noreply, assign(socket, :form, to_form(changeset))}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("test_connection", _params, socket) do
|
|
api_key = extract_api_key(socket)
|
|
|
|
if api_key == "" or is_nil(api_key) do
|
|
{:noreply, assign(socket, :test_result, {:error, "Please enter an API key first"})}
|
|
else
|
|
case PreseemClient.test_connection(api_key) do
|
|
{:ok, _body} ->
|
|
{:noreply, assign(socket, :test_result, {:ok, "Connection successful"})}
|
|
|
|
{:error, :unauthorized} ->
|
|
{:noreply, assign(socket, :test_result, {:error, "Invalid API key"})}
|
|
|
|
{:error, :forbidden} ->
|
|
{:noreply, assign(socket, :test_result, {:error, "Access forbidden"})}
|
|
|
|
{:error, reason} ->
|
|
{:noreply, assign(socket, :test_result, {:error, "Connection failed: #{inspect(reason)}"})}
|
|
end
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("toggle_enabled", %{"provider" => provider}, socket) do
|
|
case Map.get(socket.assigns.integrations, provider) do
|
|
nil ->
|
|
{:noreply, socket}
|
|
|
|
integration ->
|
|
case Integrations.update_integration(integration, %{enabled: !integration.enabled}) do
|
|
{:ok, _updated} ->
|
|
integrations = load_integrations(socket.assigns.organization.id)
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(:integrations, integrations)
|
|
|> put_flash(:info, "Integration updated")}
|
|
|
|
{:error, _changeset} ->
|
|
{:noreply, put_flash(socket, :error, "Failed to update integration")}
|
|
end
|
|
end
|
|
end
|
|
|
|
defp load_integrations(organization_id) do
|
|
organization_id
|
|
|> Integrations.list_integrations()
|
|
|> Map.new(fn integration -> {integration.provider, integration} end)
|
|
end
|
|
|
|
defp get_current_integration(socket) do
|
|
provider = socket.assigns.configuring
|
|
|
|
case Map.get(socket.assigns.integrations, provider) do
|
|
nil -> %Integration{}
|
|
integration -> integration
|
|
end
|
|
end
|
|
|
|
defp normalize_params(params) do
|
|
api_key = Map.get(params, "api_key", "")
|
|
base_url = Map.get(params, "base_url", "")
|
|
|
|
credentials =
|
|
then(%{"api_key" => api_key}, fn creds ->
|
|
if base_url == "", do: creds, else: Map.put(creds, "base_url", base_url)
|
|
end)
|
|
|
|
%{credentials: credentials}
|
|
end
|
|
|
|
defp get_credential(nil, _key), do: ""
|
|
|
|
defp get_credential(%Integration{credentials: credentials}, key) when is_map(credentials) do
|
|
Map.get(credentials, key, "")
|
|
end
|
|
|
|
defp get_credential(_integration, _key), do: ""
|
|
|
|
defp extract_api_key(socket) do
|
|
changeset = socket.assigns.form.source
|
|
data = Ecto.Changeset.apply_changes(changeset)
|
|
|
|
case data.credentials do
|
|
%{"api_key" => key} -> key
|
|
_ -> nil
|
|
end
|
|
end
|
|
end
|