Changed the help text below the device name field to appear as placeholder text inside the input field when in SNMP mode
262 lines
10 KiB
Text
262 lines
10 KiB
Text
<Layouts.authenticated
|
|
flash={@flash}
|
|
current_scope={@current_scope}
|
|
current_organization={@organization}
|
|
>
|
|
<div class="mb-4">
|
|
<.link
|
|
navigate={
|
|
if @live_action == :edit,
|
|
do: ~p"/orgs/#{@organization.slug}/devices/#{@device.id}",
|
|
else: ~p"/orgs/#{@organization.slug}/devices"
|
|
}
|
|
class="inline-flex items-center gap-1 text-sm text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
|
|
>
|
|
<.icon name="hero-arrow-left" class="h-4 w-4" />
|
|
{if @live_action == :edit, do: "Back to Device", else: "Back to Device List"}
|
|
</.link>
|
|
</div>
|
|
|
|
<.header>
|
|
{@page_title}
|
|
<:subtitle>
|
|
{if @live_action == :new,
|
|
do: "Add new device to monitor",
|
|
else: "Update device details"}
|
|
</:subtitle>
|
|
</.header>
|
|
|
|
<div class="max-w-2xl">
|
|
<.form for={@form} id="device-form" phx-change="validate" phx-submit="save">
|
|
<.input
|
|
field={@form[:name]}
|
|
type="text"
|
|
label="Device Name"
|
|
placeholder={
|
|
if @monitoring_mode == "snmp_and_icmp",
|
|
do: "Leave blank to automatically populate from SNMP device name (sysName)",
|
|
else: nil
|
|
}
|
|
required={@monitoring_mode == "icmp_only"}
|
|
/>
|
|
|
|
<.input field={@form[:ip_address]} type="text" label="IP Address" required />
|
|
|
|
<.input
|
|
field={@form[:site_id]}
|
|
type="select"
|
|
label="Site"
|
|
required
|
|
prompt="Select a site"
|
|
options={Enum.map(@available_sites, &{&1.name, &1.id})}
|
|
/>
|
|
|
|
<.input field={@form[:description]} type="textarea" label="Description" />
|
|
|
|
<.input
|
|
field={@form[:check_interval_seconds]}
|
|
type="number"
|
|
label="Check Interval (seconds)"
|
|
min="30"
|
|
max="3600"
|
|
/>
|
|
|
|
<.input field={@form[:monitoring_enabled]} type="checkbox" label="Enable Monitoring" />
|
|
|
|
<%= if @available_agents != [] do %>
|
|
<.input
|
|
field={@form[:agent_token_id]}
|
|
type="select"
|
|
label="Remote Agent"
|
|
prompt="Inherit from site/organization"
|
|
options={Enum.map(@available_agents, &{&1.name, &1.id})}
|
|
/>
|
|
<%= if @live_action == :edit and Map.has_key?(assigns, :agent_source) do %>
|
|
<%= case @agent_source do %>
|
|
<% :device -> %>
|
|
<p class="mt-1 text-sm text-amber-600 dark:text-amber-400 flex items-center gap-1">
|
|
<.icon name="hero-exclamation-triangle" class="h-4 w-4" />
|
|
<strong>Overriding</strong> site/organization defaults -
|
|
this device is explicitly assigned
|
|
</p>
|
|
<% :site -> %>
|
|
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
|
|
<.icon name="hero-building-office" class="h-4 w-4" /> Inherited from site:
|
|
<strong>{@effective_agent_name}</strong>
|
|
</p>
|
|
<% :organization -> %>
|
|
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
|
|
<.icon name="hero-building-office-2" class="h-4 w-4" />
|
|
Inherited from organization: <strong>{@effective_agent_name}</strong>
|
|
</p>
|
|
<% :none -> %>
|
|
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
|
|
<.icon name="hero-cloud" class="h-4 w-4" /> No agent assigned - cloud polling
|
|
</p>
|
|
<% end %>
|
|
<% else %>
|
|
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
|
Assign this device to a remote agent for local SNMP polling. Leave empty to inherit from site or organization defaults.
|
|
</p>
|
|
<% end %>
|
|
<% end %>
|
|
|
|
<div class="mt-8 border-t pt-6">
|
|
<h3 class="text-lg font-medium mb-4">Monitoring Configuration</h3>
|
|
|
|
<!-- Monitoring Mode Tabs -->
|
|
<div class="mb-6">
|
|
<div class="border-b border-zinc-200 dark:border-zinc-700">
|
|
<nav class="-mb-px flex space-x-8" aria-label="Monitoring mode">
|
|
<button
|
|
type="button"
|
|
phx-click="switch_monitoring_mode"
|
|
phx-value-mode="snmp_and_icmp"
|
|
class={[
|
|
"whitespace-nowrap border-b-2 px-1 py-4 text-sm font-medium",
|
|
@monitoring_mode == "snmp_and_icmp" &&
|
|
"border-blue-500 text-blue-600 dark:border-blue-400 dark:text-blue-400",
|
|
@monitoring_mode != "snmp_and_icmp" &&
|
|
"border-transparent text-zinc-500 hover:border-zinc-300 hover:text-zinc-700 dark:text-zinc-400 dark:hover:border-zinc-600 dark:hover:text-zinc-300"
|
|
]}
|
|
>
|
|
SNMP & ICMP
|
|
</button>
|
|
<button
|
|
type="button"
|
|
phx-click="switch_monitoring_mode"
|
|
phx-value-mode="icmp_only"
|
|
class={[
|
|
"whitespace-nowrap border-b-2 px-1 py-4 text-sm font-medium",
|
|
@monitoring_mode == "icmp_only" &&
|
|
"border-blue-500 text-blue-600 dark:border-blue-400 dark:text-blue-400",
|
|
@monitoring_mode != "icmp_only" &&
|
|
"border-transparent text-zinc-500 hover:border-zinc-300 hover:text-zinc-700 dark:text-zinc-400 dark:hover:border-zinc-600 dark:hover:text-zinc-300"
|
|
]}
|
|
>
|
|
ICMP Only
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
<div class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
|
<%= if @monitoring_mode == "snmp_and_icmp" do %>
|
|
<p>
|
|
Monitor device availability with ICMP pings and collect detailed information via SNMP
|
|
(interfaces, sensors, system info).
|
|
</p>
|
|
<% else %>
|
|
<p>Monitor device availability with ICMP pings only (no SNMP discovery).</p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
:if={@monitoring_mode == "snmp_and_icmp"}
|
|
class="mt-4 space-y-4 pl-6 border-l-2 border-blue-200"
|
|
>
|
|
<.input
|
|
field={@form[:snmp_version]}
|
|
type="select"
|
|
label="SNMP Version"
|
|
prompt="Inherit from site/organization"
|
|
options={[{"SNMPv1", "1"}, {"SNMPv2c", "2c"}]}
|
|
/>
|
|
|
|
<.input
|
|
field={@form[:snmp_community]}
|
|
type="text"
|
|
label="Community String"
|
|
placeholder="Leave blank to inherit from site/organization"
|
|
autocomplete="off"
|
|
/>
|
|
|
|
<%= if @live_action == :edit and Map.has_key?(assigns, :snmp_config_source) do %>
|
|
<%= case @snmp_config_source do %>
|
|
<% :device -> %>
|
|
<p class="text-sm text-amber-600 dark:text-amber-400 flex items-center gap-1">
|
|
<.icon name="hero-exclamation-triangle" class="h-4 w-4" />
|
|
<strong>Overriding</strong> site/organization SNMP defaults
|
|
</p>
|
|
<% :site -> %>
|
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
|
|
<.icon name="hero-building-office" class="h-4 w-4" />
|
|
Inherited from site (v{@effective_snmp_version}, community: {@effective_snmp_community})
|
|
</p>
|
|
<% :organization -> %>
|
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
|
|
<.icon name="hero-building-office-2" class="h-4 w-4" />
|
|
Inherited from organization (v{@effective_snmp_version}, community: {@effective_snmp_community})
|
|
</p>
|
|
<% :default -> %>
|
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
|
|
<.icon name="hero-information-circle" class="h-4 w-4" />
|
|
Using default (v2c, no community set - configure at organization or site level)
|
|
</p>
|
|
<% end %>
|
|
<% end %>
|
|
|
|
<.input
|
|
field={@form[:snmp_port]}
|
|
type="number"
|
|
label="SNMP Port"
|
|
min="1"
|
|
max="65535"
|
|
value={@form[:snmp_port].value || 161}
|
|
/>
|
|
|
|
<div
|
|
:if={@snmp_test_result}
|
|
class="rounded-md p-3"
|
|
class={[
|
|
@snmp_test_result.success && "bg-green-50 text-green-800",
|
|
!@snmp_test_result.success && "bg-red-50 text-red-800"
|
|
]}
|
|
>
|
|
<div class="flex items-center gap-2">
|
|
<.icon :if={@snmp_test_result.success} name="hero-check-circle" class="w-5 h-5" />
|
|
<.icon :if={!@snmp_test_result.success} name="hero-x-circle" class="w-5 h-5" />
|
|
<span class="text-sm font-medium">{@snmp_test_result.message}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-3">
|
|
<.button type="button" phx-click="test_snmp" phx-disable-with="Testing...">
|
|
Test SNMP Connection
|
|
</.button>
|
|
|
|
<%= if @live_action == :edit do %>
|
|
<.button
|
|
type="button"
|
|
phx-click="trigger_discovery"
|
|
phx-disable-with="Discovering..."
|
|
>
|
|
<.icon name="hero-magnifying-glass" class="h-4 w-4" /> Rediscover Device
|
|
</.button>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-3 mt-6">
|
|
<.button phx-disable-with="Saving..." variant="primary">Save Device</.button>
|
|
<.button navigate={~p"/orgs/#{@organization.slug}/devices"}>Cancel</.button>
|
|
</div>
|
|
</.form>
|
|
|
|
<%= if @live_action == :edit do %>
|
|
<div class="mt-12 pt-8 border-t border-zinc-200 dark:border-zinc-800">
|
|
<h3 class="text-lg font-semibold text-red-600 dark:text-red-500 mb-4">Danger Zone</h3>
|
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
|
|
Once you delete this device, there is no going back. All monitoring history and alerts will be permanently deleted.
|
|
</p>
|
|
<.button
|
|
phx-click="delete"
|
|
data-confirm="Are you sure you want to delete this device? All monitoring history and alerts will be permanently deleted."
|
|
variant="danger"
|
|
>
|
|
<.icon name="hero-trash" class="h-4 w-4" /> Delete Device
|
|
</.button>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</Layouts.authenticated>
|