more dark mode
This commit is contained in:
parent
fbad8c64b2
commit
c54b5d81bb
27 changed files with 673 additions and 1742 deletions
|
|
@ -124,7 +124,7 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
"primary" => "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500 dark:bg-blue-500 dark:hover:bg-blue-600",
|
||||
"danger" => "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500 dark:bg-red-500 dark:hover:bg-red-600",
|
||||
nil =>
|
||||
"bg-white text-zinc-900 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 focus:ring-blue-500 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700 dark:hover:bg-zinc-700"
|
||||
"bg-white text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:ring-blue-500 dark:bg-gray-800 dark:text-white dark:ring-gray-700 dark:hover:bg-gray-700"
|
||||
}
|
||||
|
||||
assigns =
|
||||
|
|
@ -254,11 +254,11 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
checked={@checked}
|
||||
class={
|
||||
@class ||
|
||||
"h-4 w-4 rounded border-zinc-300 text-blue-600 focus:ring-blue-500 dark:border-zinc-600 dark:bg-zinc-800"
|
||||
"h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800"
|
||||
}
|
||||
{@rest}
|
||||
/>
|
||||
<span class="text-sm font-medium text-zinc-900 dark:text-zinc-100">{@label}</span>
|
||||
<span class="text-sm font-medium text-gray-900 dark:text-white">{@label}</span>
|
||||
</label>
|
||||
<.error :for={msg <- @errors}>{msg}</.error>
|
||||
</div>
|
||||
|
|
@ -313,7 +313,7 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
~H"""
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<span :if={@label} class="block text-sm font-medium text-zinc-900 dark:text-zinc-100 mb-2">
|
||||
<span :if={@label} class="block text-sm font-medium text-gray-900 dark:text-white mb-2">
|
||||
{@label}
|
||||
</span>
|
||||
<textarea
|
||||
|
|
@ -321,9 +321,9 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
name={@name}
|
||||
class={[
|
||||
@class ||
|
||||
"block w-full rounded-lg border-0 py-2 px-3 text-zinc-900 shadow-sm ring-1 ring-inset focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 dark:bg-zinc-800 dark:text-zinc-100",
|
||||
"block w-full rounded-lg border-0 py-2 px-3 text-gray-900 shadow-sm ring-1 ring-inset focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 dark:bg-gray-800 dark:text-white",
|
||||
@errors == [] &&
|
||||
"ring-zinc-300 focus:ring-blue-600 dark:ring-zinc-700 dark:focus:ring-blue-500",
|
||||
"ring-gray-300 focus:ring-blue-600 dark:ring-gray-700 dark:focus:ring-blue-500",
|
||||
@errors != [] &&
|
||||
(@error_class ||
|
||||
"ring-red-300 focus:ring-red-500 dark:ring-red-700 dark:focus:ring-red-500")
|
||||
|
|
@ -341,7 +341,7 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
~H"""
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<span :if={@label} class="block text-sm font-medium text-zinc-900 dark:text-zinc-100 mb-2">
|
||||
<span :if={@label} class="block text-sm font-medium text-gray-900 dark:text-white mb-2">
|
||||
{@label}
|
||||
</span>
|
||||
<input
|
||||
|
|
@ -351,9 +351,9 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
|
||||
class={[
|
||||
@class ||
|
||||
"block w-full rounded-lg border-0 py-2 px-3 text-zinc-900 shadow-sm ring-1 ring-inset focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 dark:bg-zinc-800 dark:text-zinc-100",
|
||||
"block w-full rounded-lg border-0 py-2 px-3 text-gray-900 shadow-sm ring-1 ring-inset focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 dark:bg-gray-800 dark:text-white",
|
||||
@errors == [] &&
|
||||
"ring-zinc-300 focus:ring-blue-600 dark:ring-zinc-700 dark:focus:ring-blue-500",
|
||||
"ring-gray-300 focus:ring-blue-600 dark:ring-gray-700 dark:focus:ring-blue-500",
|
||||
@errors != [] &&
|
||||
(@error_class ||
|
||||
"ring-red-300 focus:ring-red-500 dark:ring-red-700 dark:focus:ring-red-500")
|
||||
|
|
@ -387,10 +387,10 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
~H"""
|
||||
<header class={[@actions != [] && "flex items-center justify-between gap-6", "mb-8"]}>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-zinc-900 dark:text-zinc-100">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">
|
||||
{render_slot(@inner_block)}
|
||||
</h1>
|
||||
<p :if={@subtitle != []} class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p :if={@subtitle != []} class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
{render_slot(@subtitle)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -497,10 +497,10 @@ defmodule ToweropsWeb.CoreComponents do
|
|||
|
||||
def list(assigns) do
|
||||
~H"""
|
||||
<div class="overflow-hidden bg-white shadow rounded-lg divide-y divide-zinc-200 dark:bg-zinc-900 dark:divide-zinc-800">
|
||||
<div class="overflow-hidden bg-white shadow rounded-lg divide-y divide-gray-200 dark:bg-gray-800/50 dark:divide-white/10">
|
||||
<div :for={item <- @item} class="px-6 py-4">
|
||||
<dt class="text-sm font-medium text-zinc-900 dark:text-zinc-100">{item.title}</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-700 dark:text-zinc-300">{render_slot(item)}</dd>
|
||||
<dt class="text-sm font-medium text-gray-900 dark:text-white">{item.title}</dt>
|
||||
<dd class="mt-1 text-sm text-gray-700 dark:text-gray-300">{render_slot(item)}</dd>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -37,19 +37,19 @@ defmodule ToweropsWeb.Layouts do
|
|||
|
||||
def app(assigns) do
|
||||
~H"""
|
||||
<div class="flex min-h-screen flex-col bg-zinc-50 dark:bg-zinc-950">
|
||||
<header class="border-b border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<div class="flex min-h-screen flex-col bg-gray-50 dark:bg-gray-950">
|
||||
<header class="border-b border-gray-200 bg-white dark:border-white/10 dark:bg-gray-900">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<nav class="flex h-16 items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<.link navigate={~p"/"} class="text-xl font-bold text-zinc-900 dark:text-zinc-100">
|
||||
<.link navigate={~p"/"} class="text-xl font-bold text-gray-900 dark:text-white">
|
||||
Towerops
|
||||
</.link>
|
||||
</div>
|
||||
<div class="flex items-center gap-x-4">
|
||||
<.link
|
||||
navigate={~p"/users/log-in"}
|
||||
class="text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-zinc-100"
|
||||
class="text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white"
|
||||
>
|
||||
Log in
|
||||
</.link>
|
||||
|
|
@ -109,7 +109,7 @@ defmodule ToweropsWeb.Layouts do
|
|||
|
||||
def authenticated(assigns) do
|
||||
~H"""
|
||||
<div class="flex min-h-screen flex-col bg-zinc-50 dark:bg-zinc-950">
|
||||
<div class="flex min-h-screen flex-col bg-gray-50 dark:bg-gray-950">
|
||||
<!-- Impersonation Banner -->
|
||||
<%= if @current_scope && @current_scope.impersonating? do %>
|
||||
<div class="bg-yellow-400 border-b-2 border-yellow-600">
|
||||
|
|
@ -133,12 +133,12 @@ defmodule ToweropsWeb.Layouts do
|
|||
</div>
|
||||
<% end %>
|
||||
|
||||
<nav class="border-b border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<nav class="border-b border-gray-200 bg-white dark:border-white/10 dark:bg-gray-900">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex h-16 justify-between">
|
||||
<div class="flex">
|
||||
<div class="flex flex-shrink-0 items-center">
|
||||
<.link navigate={~p"/orgs"} class="text-xl font-bold text-zinc-900 dark:text-zinc-100">
|
||||
<.link navigate={~p"/orgs"} class="text-xl font-bold text-gray-900 dark:text-white">
|
||||
Towerops
|
||||
</.link>
|
||||
</div>
|
||||
|
|
@ -275,9 +275,9 @@ defmodule ToweropsWeb.Layouts do
|
|||
class={[
|
||||
"inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium",
|
||||
if(@active,
|
||||
do: "border-zinc-900 text-zinc-900 dark:border-zinc-100 dark:text-zinc-100",
|
||||
do: "border-gray-900 text-gray-900 dark:border-white dark:text-white",
|
||||
else:
|
||||
"border-transparent text-zinc-700 hover:border-zinc-300 hover:text-zinc-900 dark:text-zinc-300 dark:hover:border-zinc-700 dark:hover:text-zinc-100"
|
||||
"border-transparent text-gray-700 hover:border-gray-300 hover:text-gray-900 dark:text-gray-300 dark:hover:border-gray-600 dark:hover:text-white"
|
||||
)
|
||||
]}
|
||||
>
|
||||
|
|
@ -341,7 +341,7 @@ defmodule ToweropsWeb.Layouts do
|
|||
type="button"
|
||||
id="theme-menu-button"
|
||||
phx-click={JS.toggle(to: "#theme-menu")}
|
||||
class="flex items-center justify-center p-2 rounded-md text-zinc-500 hover:text-zinc-700 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
class="flex items-center justify-center p-2 rounded-md text-gray-500 hover:text-gray-700 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-gray-200 dark:hover:bg-gray-800"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<.icon name="hero-sun" class="size-5 block dark:hidden" />
|
||||
|
|
@ -350,13 +350,13 @@ defmodule ToweropsWeb.Layouts do
|
|||
|
||||
<div
|
||||
id="theme-menu"
|
||||
class="hidden absolute top-full right-0 mt-2 w-36 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black/5 z-50 dark:bg-zinc-800 dark:ring-white/10"
|
||||
class="hidden absolute top-full right-0 mt-2 w-36 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black/5 z-50 dark:bg-gray-800 dark:ring-white/10"
|
||||
phx-click-away={JS.hide(to: "#theme-menu")}
|
||||
>
|
||||
<div class="py-1">
|
||||
<button
|
||||
type="button"
|
||||
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-700"
|
||||
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
|
||||
phx-click={JS.dispatch("phx:set-theme") |> JS.hide(to: "#theme-menu")}
|
||||
data-phx-theme="system"
|
||||
>
|
||||
|
|
@ -364,7 +364,7 @@ defmodule ToweropsWeb.Layouts do
|
|||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-700"
|
||||
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
|
||||
phx-click={JS.dispatch("phx:set-theme") |> JS.hide(to: "#theme-menu")}
|
||||
data-phx-theme="light"
|
||||
>
|
||||
|
|
@ -372,7 +372,7 @@ defmodule ToweropsWeb.Layouts do
|
|||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-700"
|
||||
class="flex w-full items-center gap-2 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
|
||||
phx-click={JS.dispatch("phx:set-theme") |> JS.hide(to: "#theme-menu")}
|
||||
data-phx-theme="dark"
|
||||
>
|
||||
|
|
@ -404,27 +404,27 @@ defmodule ToweropsWeb.Layouts do
|
|||
|
||||
def admin(assigns) do
|
||||
~H"""
|
||||
<div class="flex min-h-screen flex-col bg-zinc-50 dark:bg-zinc-950">
|
||||
<nav class="bg-white border-b border-zinc-200 dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<div class="flex min-h-screen flex-col bg-gray-50 dark:bg-gray-950">
|
||||
<nav class="bg-white border-b border-gray-200 dark:border-white/10 dark:bg-gray-900">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between h-16">
|
||||
<div class="flex">
|
||||
<.link
|
||||
navigate={~p"/admin"}
|
||||
class="flex items-center text-xl font-bold text-zinc-900 dark:text-zinc-100"
|
||||
class="flex items-center text-xl font-bold text-gray-900 dark:text-white"
|
||||
>
|
||||
Towerops Admin
|
||||
</.link>
|
||||
<div class="hidden sm:ml-6 sm:flex sm:space-x-8">
|
||||
<.link
|
||||
navigate={~p"/admin/users"}
|
||||
class="inline-flex items-center px-1 pt-1 text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-zinc-100"
|
||||
class="inline-flex items-center px-1 pt-1 text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white"
|
||||
>
|
||||
Users
|
||||
</.link>
|
||||
<.link
|
||||
navigate={~p"/admin/organizations"}
|
||||
class="inline-flex items-center px-1 pt-1 text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-zinc-100"
|
||||
class="inline-flex items-center px-1 pt-1 text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white"
|
||||
>
|
||||
Organizations
|
||||
</.link>
|
||||
|
|
@ -434,7 +434,7 @@ defmodule ToweropsWeb.Layouts do
|
|||
<.theme_toggle />
|
||||
<.link
|
||||
navigate={~p"/orgs"}
|
||||
class="text-sm text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
|
||||
class="text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
Back to App
|
||||
</.link>
|
||||
|
|
@ -474,9 +474,9 @@ defmodule ToweropsWeb.Layouts do
|
|||
|> assign(:formatted_time, TimeHelpers.format_iso8601(build_time, timezone))
|
||||
|
||||
~H"""
|
||||
<footer class="border-t border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<footer class="border-t border-gray-200 bg-white dark:border-white/10 dark:bg-gray-900">
|
||||
<div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
|
||||
<div class="flex flex-col items-center gap-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="flex flex-col items-center gap-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
<p>Copyright © {Date.utc_today().year} Towerops</p>
|
||||
<p class="text-xs">
|
||||
Last deploy <span title={@formatted_time}>{@time_ago}</span> · {@formatted_time}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<li>
|
||||
<a
|
||||
href="#introduction"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-gray-600 transition hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
Introduction
|
||||
</a>
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
<li>
|
||||
<a
|
||||
href="#authentication"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-gray-600 transition hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
Authentication
|
||||
</a>
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
<li>
|
||||
<a
|
||||
href="#errors"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-gray-600 transition hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
Errors
|
||||
</a>
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
<li>
|
||||
<a
|
||||
href="#devices"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-zinc-600 transition hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"
|
||||
class="block py-1 pl-4 pr-3 text-sm text-gray-600 transition hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
Devices
|
||||
</a>
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
<h1 class="text-4xl font-bold tracking-tight text-zinc-900 dark:text-white sm:text-5xl">
|
||||
Towerops API Reference
|
||||
</h1>
|
||||
<p class="mt-4 text-lg text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-4 text-lg text-gray-600 dark:text-gray-400">
|
||||
Use the Towerops API to manage your network monitoring infrastructure programmatically. Create and monitor sites, devices, and alerts.
|
||||
</p>
|
||||
</section>
|
||||
|
|
@ -88,16 +88,16 @@
|
|||
<h2 class="text-3xl font-bold tracking-tight text-zinc-900 dark:text-white">
|
||||
Authentication
|
||||
</h2>
|
||||
<p class="mt-4 text-base text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-4 text-base text-gray-600 dark:text-gray-400">
|
||||
All API requests require authentication using an API token. Include your token in the Authorization header:
|
||||
</p>
|
||||
<div class="mt-6 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-6 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<pre class="p-4 text-sm text-zinc-100 overflow-x-auto"><code><%= raw("""
|
||||
curl https://towerops.net/api/v1/sites \\
|
||||
-H "Authorization: Bearer #{@sample_token}"
|
||||
""") %></code></pre>
|
||||
</div>
|
||||
<p class="mt-4 text-base text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-4 text-base text-gray-600 dark:text-gray-400">
|
||||
API tokens are created and managed in your organization settings. Each token is scoped to a single organization.
|
||||
</p>
|
||||
</section>
|
||||
|
|
@ -107,11 +107,11 @@ curl https://towerops.net/api/v1/sites \\
|
|||
<h2 class="text-3xl font-bold tracking-tight text-zinc-900 dark:text-white">
|
||||
Errors
|
||||
</h2>
|
||||
<p class="mt-4 text-base text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-4 text-base text-gray-600 dark:text-gray-400">
|
||||
The API uses conventional HTTP response codes to indicate success or failure:
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
<table class="min-w-full divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="py-3 text-left text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
|
|
@ -122,44 +122,44 @@ curl https://towerops.net/api/v1/sites \\
|
|||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-white/10">
|
||||
<tr>
|
||||
<td class="py-3 text-sm font-mono text-emerald-600 dark:text-emerald-400">200</td>
|
||||
<td class="py-3 text-sm text-zinc-600 dark:text-zinc-400">Success</td>
|
||||
<td class="py-3 text-sm text-gray-600 dark:text-gray-400">Success</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-3 text-sm font-mono text-emerald-600 dark:text-emerald-400">201</td>
|
||||
<td class="py-3 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<td class="py-3 text-sm text-gray-600 dark:text-gray-400">
|
||||
Created successfully
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-3 text-sm font-mono text-red-600 dark:text-red-400">400</td>
|
||||
<td class="py-3 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<td class="py-3 text-sm text-gray-600 dark:text-gray-400">
|
||||
Bad request - missing or invalid parameters
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-3 text-sm font-mono text-red-600 dark:text-red-400">401</td>
|
||||
<td class="py-3 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<td class="py-3 text-sm text-gray-600 dark:text-gray-400">
|
||||
Unauthorized - invalid or missing API token
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-3 text-sm font-mono text-red-600 dark:text-red-400">403</td>
|
||||
<td class="py-3 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<td class="py-3 text-sm text-gray-600 dark:text-gray-400">
|
||||
Forbidden - you don't have access to this resource
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-3 text-sm font-mono text-red-600 dark:text-red-400">404</td>
|
||||
<td class="py-3 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<td class="py-3 text-sm text-gray-600 dark:text-gray-400">
|
||||
Not found - resource doesn't exist
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-3 text-sm font-mono text-red-600 dark:text-red-400">422</td>
|
||||
<td class="py-3 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<td class="py-3 text-sm text-gray-600 dark:text-gray-400">
|
||||
Unprocessable entity - validation errors
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -168,14 +168,14 @@ curl https://towerops.net/api/v1/sites \\
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="my-16 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-16 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Sites Resource -->
|
||||
<section id="sites" class="scroll-mt-24 mb-16">
|
||||
<h2 class="text-3xl font-bold tracking-tight text-zinc-900 dark:text-white">
|
||||
Sites
|
||||
</h2>
|
||||
<p class="mt-4 text-base text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-4 text-base text-gray-600 dark:text-gray-400">
|
||||
Sites represent physical locations where your network devices are deployed. Each site can have multiple devices and may have default SNMP configuration.
|
||||
</p>
|
||||
|
||||
|
|
@ -183,59 +183,59 @@ curl https://towerops.net/api/v1/sites \\
|
|||
<div class="mt-12">
|
||||
<h3 class="text-xl font-semibold text-zinc-900 dark:text-white">The site model</h3>
|
||||
<div class="mt-6">
|
||||
<dl class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<dl class="divide-y divide-gray-200 dark:divide-white/10">
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
id
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Unique identifier for the site (UUID).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
name
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
The name of the site.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
location
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Physical location or address of the site.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_community
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Default SNMP community string for devices at this site (optional).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
inserted_at
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
timestamp
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Timestamp when the site was created.
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -243,7 +243,7 @@ curl https://towerops.net/api/v1/sites \\
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- List all sites -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -252,20 +252,20 @@ curl https://towerops.net/api/v1/sites \\
|
|||
<span class="inline-flex items-center rounded-md bg-emerald-50 px-2 py-1 text-xs font-medium text-emerald-700 ring-1 ring-inset ring-emerald-600/20 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-emerald-400/30">
|
||||
GET
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">/api/v1/sites</span>
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">/api/v1/sites</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<!-- Left column - description -->
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Lists all sites for the authenticated organization.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Right column - code example -->
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -275,7 +275,7 @@ curl -G https://towerops.net/api/v1/sites \\
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -297,7 +297,7 @@ curl -G https://towerops.net/api/v1/sites \\
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Create a site -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -306,39 +306,39 @@ curl -G https://towerops.net/api/v1/sites \\
|
|||
<span class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-600/20 dark:bg-blue-400/10 dark:text-blue-400 dark:ring-blue-400/30">
|
||||
POST
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">/api/v1/sites</span>
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">/api/v1/sites</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<!-- Left column -->
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Creates a new site for the authenticated organization.
|
||||
</p>
|
||||
|
||||
<h4 class="mt-6 text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
Required parameters
|
||||
</h4>
|
||||
<dl class="mt-3 divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<dl class="mt-3 divide-y divide-gray-200 dark:divide-white/10">
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
name
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
The name of the site.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
location
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Physical location of the site.
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -347,15 +347,15 @@ curl -G https://towerops.net/api/v1/sites \\
|
|||
<h4 class="mt-6 text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
Optional parameters
|
||||
</h4>
|
||||
<dl class="mt-3 divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<dl class="mt-3 divide-y divide-gray-200 dark:divide-white/10">
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_community
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Default SNMP community string for devices at this site.
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -364,7 +364,7 @@ curl -G https://towerops.net/api/v1/sites \\
|
|||
|
||||
<!-- Right column -->
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -382,7 +382,7 @@ curl https://towerops.net/api/v1/sites \
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -400,7 +400,7 @@ curl https://towerops.net/api/v1/sites \
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Get a site -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -409,20 +409,20 @@ curl https://towerops.net/api/v1/sites \
|
|||
<span class="inline-flex items-center rounded-md bg-emerald-50 px-2 py-1 text-xs font-medium text-emerald-700 ring-1 ring-inset ring-emerald-600/20 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-emerald-400/30">
|
||||
GET
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/sites/:id
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Retrieves a single site by ID.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -432,7 +432,7 @@ curl https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-446655440000 \
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -450,7 +450,7 @@ curl https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-446655440000 \
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Update a site -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -459,20 +459,20 @@ curl https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-446655440000 \
|
|||
<span class="inline-flex items-center rounded-md bg-amber-50 px-2 py-1 text-xs font-medium text-amber-700 ring-1 ring-inset ring-amber-600/20 dark:bg-amber-400/10 dark:text-amber-400 dark:ring-amber-400/30">
|
||||
PATCH
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/sites/:id
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Updates an existing site. Only provided fields will be updated.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -488,7 +488,7 @@ curl -X PATCH https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-44665544
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -506,7 +506,7 @@ curl -X PATCH https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-44665544
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Delete a site -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -515,20 +515,20 @@ curl -X PATCH https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-44665544
|
|||
<span class="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-600/20 dark:bg-red-400/10 dark:text-red-400 dark:ring-red-400/30">
|
||||
DELETE
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/sites/:id
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Deletes a site. Note: This will also delete all devices associated with the site.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -538,7 +538,7 @@ curl -X DELETE https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-4466554
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -553,14 +553,14 @@ curl -X DELETE https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-4466554
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="my-16 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-16 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Devices Resource -->
|
||||
<section id="devices" class="scroll-mt-24 mb-16">
|
||||
<h2 class="text-3xl font-bold tracking-tight text-zinc-900 dark:text-white">
|
||||
Devices
|
||||
</h2>
|
||||
<p class="mt-4 text-base text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-4 text-base text-gray-600 dark:text-gray-400">
|
||||
Devices are network equipment monitored by Towerops. Each device belongs to a site and can be monitored via ICMP ping and SNMP.
|
||||
</p>
|
||||
|
||||
|
|
@ -568,125 +568,125 @@ curl -X DELETE https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-4466554
|
|||
<div class="mt-12">
|
||||
<h3 class="text-xl font-semibold text-zinc-900 dark:text-white">The device model</h3>
|
||||
<div class="mt-6">
|
||||
<dl class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<dl class="divide-y divide-gray-200 dark:divide-white/10">
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
id
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Unique identifier for the device (UUID).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
name
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
The name of the device.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
ip_address
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
IP address of the device.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
site_id
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
ID of the site this device belongs to.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
description
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Optional description of the device.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
monitoring_enabled
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
boolean
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Whether monitoring is enabled for this device.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
check_interval_seconds
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
integer
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
How often to poll this device (in seconds).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_enabled
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
boolean
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Whether SNMP monitoring is enabled.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_version
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
SNMP version to use (e.g., "2c").
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_port
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
integer
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
SNMP port (default: 161).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
inserted_at
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
timestamp
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Timestamp when the device was created.
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -694,7 +694,7 @@ curl -X DELETE https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-4466554
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- List all devices -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -703,29 +703,29 @@ curl -X DELETE https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-4466554
|
|||
<span class="inline-flex items-center rounded-md bg-emerald-50 px-2 py-1 text-xs font-medium text-emerald-700 ring-1 ring-inset ring-emerald-600/20 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-emerald-400/30">
|
||||
GET
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/devices
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Lists all devices for the authenticated organization.
|
||||
</p>
|
||||
|
||||
<h4 class="mt-6 text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
Optional parameters
|
||||
</h4>
|
||||
<dl class="mt-3 divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<dl class="mt-3 divide-y divide-gray-200 dark:divide-white/10">
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
site_id
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Filter devices by site ID.
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -733,7 +733,7 @@ curl -X DELETE https://towerops.net/api/v1/sites/550e8400-e29b-41d4-a716-4466554
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -743,7 +743,7 @@ curl -G https://towerops.net/api/v1/devices \
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -767,7 +767,7 @@ curl -G https://towerops.net/api/v1/devices \
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Create a device -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -776,51 +776,51 @@ curl -G https://towerops.net/api/v1/devices \
|
|||
<span class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-600/20 dark:bg-blue-400/10 dark:text-blue-400 dark:ring-blue-400/30">
|
||||
POST
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/devices
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Creates a new device.
|
||||
</p>
|
||||
|
||||
<h4 class="mt-6 text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
Required parameters
|
||||
</h4>
|
||||
<dl class="mt-3 divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<dl class="mt-3 divide-y divide-gray-200 dark:divide-white/10">
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
site_id
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
ID of the site this device belongs to.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
name
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
The name of the device.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
ip_address
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
IP address of the device.
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -829,70 +829,70 @@ curl -G https://towerops.net/api/v1/devices \
|
|||
<h4 class="mt-6 text-sm font-semibold text-zinc-900 dark:text-white">
|
||||
Optional parameters
|
||||
</h4>
|
||||
<dl class="mt-3 divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<dl class="mt-3 divide-y divide-gray-200 dark:divide-white/10">
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
description
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Description of the device.
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
monitoring_enabled
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
boolean
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Enable monitoring (default: true).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_enabled
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
boolean
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Enable SNMP monitoring (default: true).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_version
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
SNMP version (default: "2c").
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_community
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
string
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
SNMP community string (inherits from site/org if not set).
|
||||
</dd>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<dt class="text-sm font-mono font-medium text-zinc-900 dark:text-white">
|
||||
snmp_port
|
||||
<span class="ml-2 font-sans text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 font-sans text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
integer
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<dd class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
SNMP port (default: 161).
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -900,7 +900,7 @@ curl -G https://towerops.net/api/v1/devices \
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -920,7 +920,7 @@ curl https://towerops.net/api/v1/devices \
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -940,7 +940,7 @@ curl https://towerops.net/api/v1/devices \
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Get a device -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -949,20 +949,20 @@ curl https://towerops.net/api/v1/devices \
|
|||
<span class="inline-flex items-center rounded-md bg-emerald-50 px-2 py-1 text-xs font-medium text-emerald-700 ring-1 ring-inset ring-emerald-600/20 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-emerald-400/30">
|
||||
GET
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/devices/:id
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Retrieves a single device by ID, including all configuration details.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -972,7 +972,7 @@ curl https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-446655440001 \
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -996,7 +996,7 @@ curl https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-446655440001 \
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Update a device -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -1005,20 +1005,20 @@ curl https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-446655440001 \
|
|||
<span class="inline-flex items-center rounded-md bg-amber-50 px-2 py-1 text-xs font-medium text-amber-700 ring-1 ring-inset ring-amber-600/20 dark:bg-amber-400/10 dark:text-amber-400 dark:ring-amber-400/30">
|
||||
PATCH
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/devices/:id
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Updates an existing device. Only provided fields will be updated.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -1035,7 +1035,7 @@ curl -X PATCH https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-446655
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -1059,7 +1059,7 @@ curl -X PATCH https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-446655
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-12 border-zinc-200 dark:border-zinc-800" />
|
||||
<hr class="my-12 border-gray-200 dark:border-white/10" />
|
||||
|
||||
<!-- Delete a device -->
|
||||
<div class="mt-12">
|
||||
|
|
@ -1068,20 +1068,20 @@ curl -X PATCH https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-446655
|
|||
<span class="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-600/20 dark:bg-red-400/10 dark:text-red-400 dark:ring-red-400/30">
|
||||
DELETE
|
||||
</span>
|
||||
<span class="text-sm font-mono text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm font-mono text-gray-600 dark:text-gray-400">
|
||||
/api/v1/devices/:id
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 grid grid-cols-1 gap-x-12 gap-y-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
Deletes a device. Note: This will also delete all monitoring data associated with the device.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Request</p>
|
||||
</div>
|
||||
|
|
@ -1091,7 +1091,7 @@ curl -X DELETE https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-44665
|
|||
""") %></code></pre>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-zinc-900 dark:bg-zinc-950">
|
||||
<div class="mt-4 overflow-hidden rounded-lg bg-gray-900 dark:bg-gray-950">
|
||||
<div class="border-b border-zinc-800 px-4 py-2">
|
||||
<p class="text-xs font-medium text-zinc-400">Response</p>
|
||||
</div>
|
||||
|
|
@ -1107,8 +1107,8 @@ curl -X DELETE https://towerops.net/api/v1/devices/650e8400-e29b-41d4-a716-44665
|
|||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="mt-24 border-t border-zinc-200 dark:border-zinc-800 pt-8 pb-16">
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<footer class="mt-24 border-t border-gray-200 dark:border-white/10 pt-8 pb-16">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">
|
||||
© 2026 Towerops. All rights reserved.
|
||||
</p>
|
||||
</footer>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -60,10 +60,10 @@
|
|||
|
||||
<div class="relative">
|
||||
<div class="absolute inset-0 flex items-center">
|
||||
<div class="w-full border-t border-zinc-300 dark:border-zinc-700"></div>
|
||||
<div class="w-full border-t border-gray-300 dark:border-white/10"></div>
|
||||
</div>
|
||||
<div class="relative flex justify-center text-sm">
|
||||
<span class="bg-zinc-50 px-2 text-zinc-600 dark:bg-zinc-950 dark:text-zinc-400">
|
||||
<span class="bg-gray-50 px-2 text-gray-600 dark:bg-gray-950 dark:text-gray-400">
|
||||
or use email
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -85,10 +85,10 @@
|
|||
|
||||
<div class="relative">
|
||||
<div class="absolute inset-0 flex items-center">
|
||||
<div class="w-full border-t border-zinc-300 dark:border-zinc-700"></div>
|
||||
<div class="w-full border-t border-gray-300 dark:border-white/10"></div>
|
||||
</div>
|
||||
<div class="relative flex justify-center text-sm">
|
||||
<span class="bg-zinc-50 px-2 text-zinc-600 dark:bg-zinc-950 dark:text-zinc-400">
|
||||
<span class="bg-gray-50 px-2 text-gray-600 dark:bg-gray-950 dark:text-gray-400">
|
||||
or use password
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,38 +41,38 @@
|
|||
<div class="divider" />
|
||||
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold leading-6 text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-lg font-semibold leading-6 text-gray-900 dark:text-white">
|
||||
Alert Notification Devices
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Manage mobile devices that receive push notifications for alerts
|
||||
</p>
|
||||
|
||||
<div class="mt-6 space-y-4">
|
||||
<%= if Enum.empty?(@mobile_sessions) do %>
|
||||
<div class="rounded-lg border border-dashed border-zinc-300 p-8 text-center dark:border-zinc-700">
|
||||
<.icon name="hero-device-phone-mobile" class="mx-auto h-12 w-12 text-zinc-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="rounded-lg border border-dashed border-gray-300 p-8 text-center dark:border-white/10">
|
||||
<.icon name="hero-device-phone-mobile" class="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
No mobile devices registered
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
Add a mobile device to receive push notifications for alerts
|
||||
</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="space-y-3">
|
||||
<%= for session <- @mobile_sessions do %>
|
||||
<div class="flex items-center justify-between rounded-lg border border-zinc-200 p-4 dark:border-zinc-800">
|
||||
<div class="flex items-center justify-between rounded-lg border border-gray-200 p-4 dark:border-white/10">
|
||||
<div class="flex items-center gap-3">
|
||||
<.icon name="hero-device-phone-mobile" class="h-5 w-5 text-zinc-400" />
|
||||
<.icon name="hero-device-phone-mobile" class="h-5 w-5 text-gray-400" />
|
||||
<div>
|
||||
<p class="font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<p class="font-medium text-gray-900 dark:text-white">
|
||||
{session.device_name || "Unknown Device"}
|
||||
</p>
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
{session.device_os} • {session.app_version}
|
||||
</p>
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Last used {Calendar.strftime(session.last_used_at, "%B %d, %Y")}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -100,7 +100,7 @@
|
|||
do:
|
||||
"bg-green-100 text-green-700 hover:bg-green-200 dark:bg-green-900/20 dark:text-green-400 dark:hover:bg-green-900/30",
|
||||
else:
|
||||
"bg-zinc-100 text-zinc-700 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-400 dark:hover:bg-zinc-700"
|
||||
"bg-gray-100 text-gray-700 hover:bg-gray-200 dark:bg-gray-800/50 dark:text-gray-400 dark:hover:bg-gray-800"
|
||||
)
|
||||
]}
|
||||
>
|
||||
|
|
@ -136,7 +136,7 @@
|
|||
|
||||
<.link
|
||||
navigate={~p"/mobile/qr-login"}
|
||||
class="inline-flex items-center gap-2 rounded-lg bg-zinc-900 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-zinc-700 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-300"
|
||||
class="inline-flex items-center gap-2 rounded-lg bg-gray-900 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-gray-700 dark:bg-gray-50 dark:text-gray-900 dark:hover:bg-gray-300"
|
||||
>
|
||||
<.icon name="hero-qr-code" class="h-4 w-4" /> Add Mobile Device
|
||||
</.link>
|
||||
|
|
@ -146,10 +146,10 @@
|
|||
<div class="divider" />
|
||||
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold leading-6 text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-lg font-semibold leading-6 text-gray-900 dark:text-white">
|
||||
Passkeys
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Use your device's biometrics (Face ID, Touch ID, Windows Hello) or security keys to sign in
|
||||
</p>
|
||||
|
||||
|
|
@ -163,31 +163,31 @@
|
|||
|
||||
<div class="mt-6 space-y-4">
|
||||
<%= if Enum.empty?(@credentials) do %>
|
||||
<div class="rounded-lg border border-dashed border-zinc-300 p-8 text-center dark:border-zinc-700">
|
||||
<.icon name="hero-key" class="mx-auto h-12 w-12 text-zinc-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="rounded-lg border border-dashed border-gray-300 p-8 text-center dark:border-white/10">
|
||||
<.icon name="hero-key" class="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
No passkeys registered
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
Add a passkey to enable quick, secure sign-in with biometrics
|
||||
</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="space-y-3">
|
||||
<%= for credential <- @credentials do %>
|
||||
<div class="flex items-center justify-between rounded-lg border border-zinc-200 p-4 dark:border-zinc-800">
|
||||
<div class="flex items-center justify-between rounded-lg border border-gray-200 p-4 dark:border-white/10">
|
||||
<div class="flex items-center gap-3">
|
||||
<.icon name="hero-key" class="h-5 w-5 text-zinc-400" />
|
||||
<.icon name="hero-key" class="h-5 w-5 text-gray-400" />
|
||||
<div>
|
||||
<p class="font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<p class="font-medium text-gray-900 dark:text-white">
|
||||
{credential.name}
|
||||
</p>
|
||||
<%= if credential.last_used_at do %>
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Last used {Calendar.strftime(credential.last_used_at, "%B %d, %Y")}
|
||||
</p>
|
||||
<% else %>
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">Never used</p>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">Never used</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -208,7 +208,7 @@
|
|||
<button
|
||||
type="button"
|
||||
id="add-passkey-btn"
|
||||
class="inline-flex items-center gap-2 rounded-lg bg-zinc-900 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-zinc-700 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-300"
|
||||
class="inline-flex items-center gap-2 rounded-lg bg-gray-900 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-gray-700 dark:bg-gray-50 dark:text-gray-900 dark:hover:bg-gray-300"
|
||||
>
|
||||
<.icon name="hero-plus" class="h-4 w-4" /> Add Passkey
|
||||
</button>
|
||||
|
|
@ -224,7 +224,7 @@
|
|||
<div class="flex min-h-screen items-end justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0">
|
||||
<!-- Background overlay -->
|
||||
<div
|
||||
class="fixed inset-0 z-0 bg-zinc-500 bg-opacity-75 transition-opacity dark:bg-zinc-950 dark:bg-opacity-75"
|
||||
class="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-950 dark:bg-opacity-75"
|
||||
aria-hidden="true"
|
||||
>
|
||||
</div>
|
||||
|
|
@ -237,20 +237,20 @@
|
|||
​
|
||||
</span>
|
||||
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-zinc-900 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-gray-800/95 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div>
|
||||
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900">
|
||||
<.icon name="hero-key" class="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-5">
|
||||
<h3
|
||||
class="text-lg font-semibold leading-6 text-zinc-900 dark:text-zinc-100"
|
||||
class="text-lg font-semibold leading-6 text-gray-900 dark:text-white"
|
||||
id="modal-title"
|
||||
>
|
||||
Add Passkey
|
||||
</h3>
|
||||
<div class="mt-2">
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Give this passkey a name to help you identify it later (e.g., "MacBook Touch ID", "iPhone").
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -259,7 +259,7 @@
|
|||
type="text"
|
||||
id="passkey-name-input"
|
||||
placeholder="e.g., MacBook Touch ID"
|
||||
class="block w-full rounded-lg border-zinc-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100 sm:text-sm"
|
||||
class="block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-white/10 dark:bg-gray-800/50 dark:text-white sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -281,7 +281,7 @@
|
|||
<button
|
||||
type="button"
|
||||
id="cancel-add-passkey"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-lg bg-white px-3 py-2 text-sm font-semibold text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700 dark:hover:bg-zinc-700 sm:col-start-1 sm:mt-0"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-lg bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 dark:bg-gray-800/50 dark:text-white dark:ring-white/10 dark:hover:bg-gray-800 sm:col-start-1 sm:mt-0"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -1,31 +1,37 @@
|
|||
<Layouts.admin flash={@flash} timezone={@timezone}>
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-zinc-900">Admin Dashboard</h1>
|
||||
<p class="text-zinc-600">System overview and recent activity</p>
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">Admin Dashboard</h1>
|
||||
<p class="text-gray-600 dark:text-gray-400">System overview and recent activity</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="bg-white rounded-lg border border-zinc-200 p-6">
|
||||
<h2 class="text-lg font-semibold text-zinc-900 mb-2">Users</h2>
|
||||
<p class="text-3xl font-bold text-zinc-900">{@user_count}</p>
|
||||
<.link navigate={~p"/admin/users"} class="text-blue-600 hover:underline text-sm">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">Users</h2>
|
||||
<p class="text-3xl font-bold text-gray-900 dark:text-white">{@user_count}</p>
|
||||
<.link
|
||||
navigate={~p"/admin/users"}
|
||||
class="text-blue-600 dark:text-blue-400 hover:underline text-sm"
|
||||
>
|
||||
View all users →
|
||||
</.link>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg border border-zinc-200 p-6">
|
||||
<h2 class="text-lg font-semibold text-zinc-900 mb-2">Organizations</h2>
|
||||
<p class="text-3xl font-bold text-zinc-900">{@org_count}</p>
|
||||
<.link navigate={~p"/admin/organizations"} class="text-blue-600 hover:underline text-sm">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">Organizations</h2>
|
||||
<p class="text-3xl font-bold text-gray-900 dark:text-white">{@org_count}</p>
|
||||
<.link
|
||||
navigate={~p"/admin/organizations"}
|
||||
class="text-blue-600 dark:text-blue-400 hover:underline text-sm"
|
||||
>
|
||||
View all organizations →
|
||||
</.link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg border border-zinc-200">
|
||||
<div class="px-4 py-3 border-b border-zinc-200">
|
||||
<h2 class="text-lg font-semibold text-zinc-900">Recent Audit Logs</h2>
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">Recent Audit Logs</h2>
|
||||
</div>
|
||||
<.table id="audit-logs" rows={@recent_logs}>
|
||||
<:col :let={log} label="Action">{log.action}</:col>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<Layouts.admin flash={@flash} timezone={@timezone}>
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-zinc-900">All Organizations</h1>
|
||||
<p class="text-zinc-600">Manage organizations</p>
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">All Organizations</h1>
|
||||
<p class="text-gray-600 dark:text-gray-400">Manage organizations</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg border border-zinc-200">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<.table id="organizations" rows={@organizations}>
|
||||
<:col :let={org} label="Name">{org.name}</:col>
|
||||
<:col :let={org} label="Slug">{org.slug}</:col>
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
phx-click="delete_org"
|
||||
phx-value-id={org.id}
|
||||
data-confirm="Are you sure? This will delete all sites, device, and data for this organization."
|
||||
class="text-sm text-red-600 hover:text-red-800"
|
||||
class="text-sm text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<Layouts.admin flash={@flash} timezone={@timezone}>
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-zinc-900">All Users</h1>
|
||||
<p class="text-zinc-600">Manage system users</p>
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">All Users</h1>
|
||||
<p class="text-gray-600 dark:text-gray-400">Manage system users</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg border border-zinc-200">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<.table id="users" rows={@users}>
|
||||
<:col :let={user} label="Email">{user.email}</:col>
|
||||
<:col :let={user} label="Superuser">{if user.is_superuser, do: "Yes", else: "No"}</:col>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<button
|
||||
type="submit"
|
||||
disabled={user.is_superuser}
|
||||
class="text-sm text-blue-600 hover:text-blue-800 disabled:text-zinc-400 disabled:cursor-not-allowed"
|
||||
class="text-sm text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 disabled:text-gray-400 disabled:cursor-not-allowed"
|
||||
>
|
||||
Impersonate
|
||||
</button>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
phx-value-id={user.id}
|
||||
data-confirm="Are you sure you want to delete this user?"
|
||||
disabled={user.is_superuser}
|
||||
class="text-sm text-red-600 hover:text-red-800 disabled:text-zinc-400 disabled:cursor-not-allowed"
|
||||
class="text-sm text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300 disabled:text-gray-400 disabled:cursor-not-allowed"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
</.link>
|
||||
</div>
|
||||
|
||||
<div class="bg-white dark:bg-zinc-900 shadow rounded-lg">
|
||||
<div class="px-6 py-5 border-b border-zinc-200 dark:border-zinc-800">
|
||||
<h3 class="text-lg font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 shadow rounded-lg">
|
||||
<div class="px-6 py-5 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-lg font-medium text-gray-900 dark:text-white">
|
||||
Edit Agent
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Update the agent name. The authentication token cannot be changed.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
placeholder="e.g., Datacenter Agent"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
A descriptive name to identify this agent in your organization.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
<div class="mt-6 flex items-center justify-end gap-x-4">
|
||||
<.link
|
||||
navigate={~p"/orgs/#{@current_organization.slug}/agents/#{@agent_token.id}"}
|
||||
class="text-sm font-semibold text-zinc-700 dark:text-zinc-300 hover:text-zinc-900 dark:hover:text-zinc-100"
|
||||
class="text-sm font-semibold text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"
|
||||
>
|
||||
Cancel
|
||||
</.link>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ defmodule ToweropsWeb.AgentLive.Helpers do
|
|||
:online -> "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300"
|
||||
:warning -> "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300"
|
||||
:offline -> "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300"
|
||||
:never -> "bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-300"
|
||||
:never -> "bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ defmodule ToweropsWeb.AgentLive.Helpers do
|
|||
:online -> "bg-green-600 dark:bg-green-400 animate-pulse"
|
||||
:warning -> "bg-yellow-600 dark:bg-yellow-400"
|
||||
:offline -> "bg-red-600 dark:bg-red-400"
|
||||
:never -> "bg-zinc-400 dark:bg-zinc-600"
|
||||
:never -> "bg-gray-400 dark:bg-gray-600"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
<!-- New Agent Form -->
|
||||
<div id="new-agent-form" class="hidden mt-6">
|
||||
<div class="bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-6">
|
||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100 mb-4">
|
||||
<div class="bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg p-6">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">
|
||||
Create New Agent
|
||||
</h3>
|
||||
<.form for={@agent_form} phx-submit="create_agent">
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
<button
|
||||
type="button"
|
||||
phx-click={JS.hide(to: "#new-agent-form")}
|
||||
class="px-3 py-2 text-sm font-semibold text-zinc-700 dark:text-zinc-300 hover:text-zinc-900 dark:hover:text-zinc-100"
|
||||
class="px-3 py-2 text-sm font-semibold text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
|
@ -49,9 +49,9 @@
|
|||
|
||||
<%= if @agent_tokens == [] do %>
|
||||
<div class="text-center py-16">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">No agents</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">No agents</h3>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Get started by creating your first remote agent.
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
{agent.name}
|
||||
</.link>
|
||||
<%= if agent.metadata["version"] do %>
|
||||
<div class="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5">
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
|
||||
v{agent.metadata["version"]}
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -87,10 +87,10 @@
|
|||
|
||||
<:col :let={agent} label="Device">
|
||||
<% counts = Map.get(@device_counts, agent.id, %{direct: 0, total: 0}) %>
|
||||
<div class="text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<div class="text-sm text-gray-900 dark:text-white">
|
||||
{counts.total} total
|
||||
</div>
|
||||
<div class="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5">
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
|
||||
{counts.direct} direct
|
||||
<%= if counts.total > counts.direct do %>
|
||||
· {counts.total - counts.direct} inherited
|
||||
|
|
@ -99,16 +99,16 @@
|
|||
</:col>
|
||||
|
||||
<:col :let={agent} label="Last Seen">
|
||||
<div class="text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<div class="text-sm text-gray-900 dark:text-white">
|
||||
<.timestamp datetime={agent.last_seen_at} timezone={@timezone} />
|
||||
</div>
|
||||
<%= if agent.last_seen_at do %>
|
||||
<div class="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5">
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
|
||||
{format_datetime(agent.last_seen_at, @timezone)}
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if agent.last_ip do %>
|
||||
<div class="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5 font-mono">
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5 font-mono">
|
||||
{agent.last_ip}
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -116,7 +116,7 @@
|
|||
|
||||
<:col :let={agent} label="Metadata">
|
||||
<%= if agent.metadata["hostname"] do %>
|
||||
<div class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<.icon name="hero-computer-desktop" class="h-4 w-4 inline" />
|
||||
{agent.metadata["hostname"]}
|
||||
</div>
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
</:col>
|
||||
|
||||
<:col :let={agent} label="Created">
|
||||
<div class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
||||
{ToweropsWeb.TimeHelpers.format_date(agent.inserted_at, @timezone)}
|
||||
</div>
|
||||
</:col>
|
||||
|
|
@ -151,7 +151,7 @@
|
|||
</button>
|
||||
</div>
|
||||
<% else %>
|
||||
<span class="text-xs text-zinc-500 dark:text-zinc-400">Disabled</span>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">Disabled</span>
|
||||
<% end %>
|
||||
</:action>
|
||||
</.table>
|
||||
|
|
@ -167,26 +167,26 @@
|
|||
>
|
||||
<div class="flex min-h-screen items-center justify-center p-4">
|
||||
<div
|
||||
class="fixed inset-0 bg-zinc-500/75 dark:bg-zinc-950/75 transition-opacity"
|
||||
class="fixed inset-0 bg-gray-500/75 dark:bg-gray-950/75 transition-opacity"
|
||||
phx-click="close_token_modal"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="relative bg-white dark:bg-zinc-900 rounded-lg shadow-xl max-w-2xl w-full">
|
||||
<div class="relative bg-white dark:bg-gray-900 rounded-lg shadow-xl max-w-2xl w-full">
|
||||
<div class="p-6">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
|
||||
Agent Setup Instructions
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Use the token and Docker Compose configuration below to deploy this agent.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
phx-click="close_token_modal"
|
||||
class="text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300"
|
||||
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
|
||||
>
|
||||
<.icon name="hero-x-mark" class="h-6 w-6" />
|
||||
</button>
|
||||
|
|
@ -194,16 +194,16 @@
|
|||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
Agent Name
|
||||
</label>
|
||||
<div class="text-base font-mono text-zinc-900 dark:text-zinc-100">
|
||||
<div class="text-base font-mono text-gray-900 dark:text-white">
|
||||
{@new_token.agent_token.name}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2">
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
Authentication Token
|
||||
</label>
|
||||
<div class="relative">
|
||||
|
|
@ -211,7 +211,7 @@
|
|||
type="text"
|
||||
readonly
|
||||
value={@new_token.token}
|
||||
class="w-full font-mono text-sm bg-zinc-50 dark:bg-zinc-800 border border-zinc-300 dark:border-zinc-700 rounded px-3 py-2 pr-24 text-zinc-900 dark:text-zinc-100"
|
||||
class="w-full font-mono text-sm bg-gray-50 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded px-3 py-2 pr-24 text-gray-900 dark:text-white"
|
||||
id="agent-token-input"
|
||||
/>
|
||||
<button
|
||||
|
|
@ -219,21 +219,21 @@
|
|||
phx-hook="CopyToClipboard"
|
||||
data-target="#agent-token-input"
|
||||
id={"copy-token-#{@new_token.agent_token.id}"}
|
||||
class="absolute right-2 top-1/2 -translate-y-1/2 px-3 py-1 text-xs font-medium text-zinc-700 dark:text-zinc-300 bg-zinc-100 dark:bg-zinc-800 border border-zinc-300 dark:border-zinc-700 rounded hover:bg-zinc-200 dark:hover:bg-zinc-700"
|
||||
class="absolute right-2 top-1/2 -translate-y-1/2 px-3 py-1 text-xs font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
>
|
||||
<.icon name="hero-clipboard" class="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-lg p-4">
|
||||
<h4 class="text-sm font-medium text-zinc-900 dark:text-zinc-100 mb-2">
|
||||
<div class="bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mb-2">
|
||||
Docker Compose Setup with Auto-Updates
|
||||
</h4>
|
||||
<p class="text-xs text-zinc-600 dark:text-zinc-400 mb-3">
|
||||
<p class="text-xs text-gray-600 dark:text-gray-400 mb-3">
|
||||
This configuration includes Watchtower for automatic agent updates. The agent will automatically update to the latest version every 15 minutes during development.
|
||||
</p>
|
||||
<pre class="text-xs font-mono text-zinc-600 dark:text-zinc-400 overflow-x-auto"><code>services:
|
||||
<pre class="text-xs font-mono text-gray-600 dark:text-gray-400 overflow-x-auto"><code>services:
|
||||
towerops-agent:
|
||||
image: {@agent_image}
|
||||
container_name: towerops-agent
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ defmodule ToweropsWeb.AgentLive.Show do
|
|||
:direct -> "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300"
|
||||
:site -> "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300"
|
||||
:organization -> "bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300"
|
||||
:unknown -> "bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-300"
|
||||
:unknown -> "bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
</.link>
|
||||
<.link
|
||||
navigate={~p"/orgs/#{@current_organization.slug}/agents"}
|
||||
class="text-sm font-semibold text-zinc-700 dark:text-zinc-300 hover:text-zinc-900 dark:hover:text-zinc-100"
|
||||
class="text-sm font-semibold text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white"
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="h-5 w-5" /> Back to Agents
|
||||
</.link>
|
||||
|
|
@ -27,10 +27,10 @@
|
|||
<!-- Agent Status Overview -->
|
||||
<div class="mt-6 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<!-- Status Card -->
|
||||
<div class="bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-6">
|
||||
<div class="bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Status</p>
|
||||
<p class="text-sm font-medium text-gray-600 dark:text-gray-400">Status</p>
|
||||
<% {status, label} = agent_status(@agent_token) %>
|
||||
<div class="mt-2">
|
||||
<span class={"inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium #{status_badge_class(status)}"}>
|
||||
|
|
@ -39,104 +39,104 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<.icon name="hero-signal" class="h-8 w-8 text-zinc-400 dark:text-zinc-600" />
|
||||
<.icon name="hero-signal" class="h-8 w-8 text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Device Count Card -->
|
||||
<div class="bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-6">
|
||||
<div class="bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Device</p>
|
||||
<p class="mt-2 text-3xl font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<p class="text-sm font-medium text-gray-600 dark:text-gray-400">Device</p>
|
||||
<p class="mt-2 text-3xl font-semibold text-gray-900 dark:text-white">
|
||||
{length(@polling_targets)}
|
||||
</p>
|
||||
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{@direct_assignments} direct
|
||||
</p>
|
||||
</div>
|
||||
<.icon name="hero-server" class="h-8 w-8 text-zinc-400 dark:text-zinc-600" />
|
||||
<.icon name="hero-server" class="h-8 w-8 text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Last Seen Card -->
|
||||
<div class="bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-6">
|
||||
<div class="bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Last Seen</p>
|
||||
<p class="mt-2 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<p class="text-sm font-medium text-gray-600 dark:text-gray-400">Last Seen</p>
|
||||
<p class="mt-2 text-lg font-semibold text-gray-900 dark:text-white">
|
||||
<.timestamp
|
||||
datetime={@agent_token.last_seen_at}
|
||||
timezone={@timezone}
|
||||
/>
|
||||
</p>
|
||||
<%= if @agent_token.last_seen_at do %>
|
||||
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{format_datetime(@agent_token.last_seen_at, @timezone)}
|
||||
</p>
|
||||
<% end %>
|
||||
<%= if @agent_token.last_ip do %>
|
||||
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400 font-mono">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400 font-mono">
|
||||
{@agent_token.last_ip}
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<.icon name="hero-clock" class="h-8 w-8 text-zinc-400 dark:text-zinc-600 flex-shrink-0" />
|
||||
<.icon name="hero-clock" class="h-8 w-8 text-gray-400 dark:text-gray-500 flex-shrink-0" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Version/Uptime Card -->
|
||||
<div class="bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-6">
|
||||
<div class="bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Agent Info</p>
|
||||
<p class="text-sm font-medium text-gray-600 dark:text-gray-400">Agent Info</p>
|
||||
<%= if @agent_token.metadata["version"] do %>
|
||||
<p class="mt-2 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<p class="mt-2 text-lg font-semibold text-gray-900 dark:text-white">
|
||||
v{@agent_token.metadata["version"]}
|
||||
</p>
|
||||
<% else %>
|
||||
<p class="mt-2 text-lg font-semibold text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-2 text-lg font-semibold text-gray-500 dark:text-gray-400">
|
||||
Unknown
|
||||
</p>
|
||||
<% end %>
|
||||
<%= if @agent_token.metadata["uptime_seconds"] do %>
|
||||
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
Uptime: {format_uptime(@agent_token.metadata["uptime_seconds"])}
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<.icon name="hero-information-circle" class="h-8 w-8 text-zinc-400 dark:text-zinc-600" />
|
||||
<.icon name="hero-information-circle" class="h-8 w-8 text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Agent Metadata -->
|
||||
<%= if @agent_token.metadata && map_size(@agent_token.metadata) > 0 do %>
|
||||
<div class="mt-6 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-6">
|
||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100 mb-4">
|
||||
<div class="mt-6 bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg p-6">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">
|
||||
Agent Metadata
|
||||
</h3>
|
||||
<dl class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<%= if @agent_token.metadata["hostname"] do %>
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Hostname</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-900 dark:text-zinc-100 font-mono">
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Hostname</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 dark:text-white font-mono">
|
||||
{@agent_token.metadata["hostname"]}
|
||||
</dd>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if @agent_token.metadata["version"] do %>
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Version</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Version</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 dark:text-white">
|
||||
{@agent_token.metadata["version"]}
|
||||
</dd>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if @agent_token.metadata["uptime_seconds"] do %>
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Uptime</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Uptime</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 dark:text-white">
|
||||
{format_uptime(@agent_token.metadata["uptime_seconds"])}
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -146,40 +146,40 @@
|
|||
<% end %>
|
||||
|
||||
<!-- Agent Timestamps -->
|
||||
<div class="mt-6 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg p-6">
|
||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100 mb-4">
|
||||
<div class="mt-6 bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg p-6">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">
|
||||
Timestamps
|
||||
</h3>
|
||||
<dl class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Created</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Created</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 dark:text-white">
|
||||
{format_datetime(@agent_token.inserted_at, @timezone)}
|
||||
</dd>
|
||||
<dd class="mt-0.5 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<dd class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">
|
||||
<.timestamp datetime={@agent_token.inserted_at} timezone={@timezone} /> (created)
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Last Updated</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Last Updated</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 dark:text-white">
|
||||
{format_datetime(@agent_token.updated_at, @timezone)}
|
||||
</dd>
|
||||
<dd class="mt-0.5 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<dd class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">
|
||||
<.timestamp datetime={@agent_token.updated_at} timezone={@timezone} />
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">
|
||||
Last Seen (Heartbeat)
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<dd class="mt-1 text-sm text-gray-900 dark:text-white">
|
||||
{format_datetime(@agent_token.last_seen_at, @timezone)}
|
||||
</dd>
|
||||
<%= if @agent_token.last_seen_at do %>
|
||||
<dd class="mt-0.5 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<dd class="mt-0.5 text-xs text-gray-500 dark:text-gray-400">
|
||||
<.timestamp datetime={@agent_token.last_seen_at} timezone={@timezone} />
|
||||
</dd>
|
||||
<% end %>
|
||||
|
|
@ -187,8 +187,8 @@
|
|||
|
||||
<%= if @agent_token.last_ip do %>
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Last IP Address</dt>
|
||||
<dd class="mt-1 text-sm text-zinc-900 dark:text-zinc-100 font-mono">
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Last IP Address</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 dark:text-white font-mono">
|
||||
{@agent_token.last_ip}
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -197,38 +197,38 @@
|
|||
</div>
|
||||
|
||||
<!-- Device List -->
|
||||
<div class="mt-6 bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-lg">
|
||||
<div class="p-6 border-b border-zinc-200 dark:border-zinc-800">
|
||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="mt-6 bg-white dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg">
|
||||
<div class="p-6 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
|
||||
Polling Targets
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Device that this agent is responsible for polling
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%= if @polling_targets == [] do %>
|
||||
<div class="p-12 text-center">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
|
||||
<h3 class="mt-4 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
||||
<h3 class="mt-4 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
No devices assigned
|
||||
</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
This agent is not currently polling any device.
|
||||
</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="divide-y divide-zinc-200 dark:divide-zinc-800">
|
||||
<div class="divide-y divide-gray-200 dark:divide-white/10">
|
||||
<%= for device <- @polling_targets do %>
|
||||
<.link
|
||||
navigate={~p"/devices/#{device.id}"}
|
||||
class="block hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors"
|
||||
class="block hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-3">
|
||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
||||
<p class="text-sm font-medium text-gray-900 dark:text-white truncate">
|
||||
{device.name}
|
||||
</p>
|
||||
<% {source, source_label} = assignment_source(device, @agent_token.id) %>
|
||||
|
|
@ -236,7 +236,7 @@
|
|||
{source_label}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-1 flex items-center gap-4 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="mt-1 flex items-center gap-4 text-sm text-gray-600 dark:text-gray-400">
|
||||
<span class="flex items-center gap-1">
|
||||
<.icon name="hero-globe-alt" class="h-4 w-4" />
|
||||
{device.ip_address}
|
||||
|
|
@ -249,7 +249,7 @@
|
|||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<.icon name="hero-chevron-right" class="h-5 w-5 text-zinc-400 dark:text-zinc-600" />
|
||||
<.icon name="hero-chevron-right" class="h-5 w-5 text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
</div>
|
||||
</.link>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
</.header>
|
||||
|
||||
<div class="mb-6">
|
||||
<div class="inline-flex rounded-lg border border-zinc-200 dark:border-zinc-800">
|
||||
<div class="inline-flex rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<.link
|
||||
patch={~p"/orgs/#{@current_organization.slug}/alerts"}
|
||||
class={[
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
@filter == "active" &&
|
||||
"bg-blue-600 text-white dark:bg-blue-500",
|
||||
@filter != "active" &&
|
||||
"bg-white text-zinc-700 hover:bg-zinc-50 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
"bg-white text-gray-700 hover:bg-gray-50 dark:bg-gray-800/50 dark:text-gray-300 dark:hover:bg-gray-800"
|
||||
]}
|
||||
>
|
||||
Active Alerts
|
||||
|
|
@ -27,11 +27,11 @@
|
|||
<.link
|
||||
patch={~p"/orgs/#{@current_organization.slug}/alerts?filter=all"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm font-medium rounded-r-lg border-l border-zinc-200 dark:border-zinc-800",
|
||||
"px-4 py-2 text-sm font-medium rounded-r-lg border-l border-gray-200 dark:border-white/10",
|
||||
@filter == "all" &&
|
||||
"bg-blue-600 text-white dark:bg-blue-500",
|
||||
@filter != "all" &&
|
||||
"bg-white text-zinc-700 hover:bg-zinc-50 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
"bg-white text-gray-700 hover:bg-gray-50 dark:bg-gray-800/50 dark:text-gray-300 dark:hover:bg-gray-800"
|
||||
]}
|
||||
>
|
||||
All Alerts
|
||||
|
|
@ -41,9 +41,9 @@
|
|||
|
||||
<%= if Enum.empty?(@alerts) do %>
|
||||
<div class="text-center py-16">
|
||||
<.icon name="hero-bell-slash" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">No alerts</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<.icon name="hero-bell-slash" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">No alerts</h3>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
<%= if @filter == "active" do %>
|
||||
There are no active alerts for this organization.
|
||||
<% else %>
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
alert.alert_type == :device_down && is_nil(alert.resolved_at) &&
|
||||
"border-l-4 border-red-500 bg-red-50 dark:bg-red-950 dark:border-red-700",
|
||||
(alert.alert_type != :device_down || alert.resolved_at) &&
|
||||
"border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900"
|
||||
"border-gray-200 bg-white dark:border-white/10 dark:bg-gray-800/50"
|
||||
]}>
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex-1">
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
</span>
|
||||
|
||||
<%= if alert.resolved_at do %>
|
||||
<span class="inline-flex items-center rounded-full bg-zinc-100 px-2.5 py-0.5 text-xs font-medium text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200">
|
||||
<span class="inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-800 dark:bg-gray-800 dark:text-gray-200">
|
||||
Resolved
|
||||
</span>
|
||||
<% end %>
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-3 font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="mt-3 font-semibold text-gray-900 dark:text-white">
|
||||
<.link
|
||||
navigate={~p"/devices/#{alert.device.id}"}
|
||||
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
|
||||
|
|
@ -102,9 +102,9 @@
|
|||
</.link>
|
||||
</h3>
|
||||
|
||||
<p class="mt-1 text-sm text-zinc-700 dark:text-zinc-300">{alert.message}</p>
|
||||
<p class="mt-1 text-sm text-gray-700 dark:text-gray-300">{alert.message}</p>
|
||||
|
||||
<div class="mt-3 space-y-1 text-xs text-zinc-600 dark:text-zinc-400">
|
||||
<div class="mt-3 space-y-1 text-xs text-gray-600 dark:text-gray-400">
|
||||
<div>
|
||||
<strong class="font-medium">Triggered:</strong>
|
||||
{ToweropsWeb.TimeHelpers.format_iso8601(alert.triggered_at, @timezone)}
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@
|
|||
</.header>
|
||||
|
||||
<%= if @sites_count == 0 do %>
|
||||
<div class="mt-8 rounded-lg border-2 border-dashed border-zinc-300 bg-zinc-50 p-12 text-center dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div class="mt-8 rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 p-12 text-center dark:border-white/20 dark:bg-gray-800/50">
|
||||
<.icon
|
||||
name="hero-light-bulb"
|
||||
class="mx-auto h-16 w-16 text-blue-500 dark:text-blue-400"
|
||||
/>
|
||||
<h3 class="mt-6 text-xl font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="mt-6 text-xl font-semibold text-gray-900 dark:text-white">
|
||||
Let's get started!
|
||||
</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Follow these steps to set up your network monitoring:
|
||||
</p>
|
||||
<div class="mt-8 max-w-2xl mx-auto">
|
||||
|
|
@ -29,32 +29,32 @@
|
|||
1
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-medium text-zinc-900 dark:text-zinc-100">Create a Site</h4>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<h4 class="font-medium text-gray-900 dark:text-white">Create a Site</h4>
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Sites represent your physical locations (offices, data centers, towers, etc.)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 items-start">
|
||||
<div class="flex-shrink-0 flex items-center justify-center w-8 h-8 rounded-full bg-zinc-200 text-zinc-600 font-semibold dark:bg-zinc-700 dark:text-zinc-400">
|
||||
<div class="flex-shrink-0 flex items-center justify-center w-8 h-8 rounded-full bg-gray-200 text-gray-600 font-semibold dark:bg-gray-700 dark:text-gray-400">
|
||||
2
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-medium text-zinc-900 dark:text-zinc-100">Add Device</h4>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<h4 class="font-medium text-gray-900 dark:text-white">Add Device</h4>
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Add network devices (routers, switches, servers) to your sites
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 items-start">
|
||||
<div class="flex-shrink-0 flex items-center justify-center w-8 h-8 rounded-full bg-zinc-200 text-zinc-600 font-semibold dark:bg-zinc-700 dark:text-zinc-400">
|
||||
<div class="flex-shrink-0 flex items-center justify-center w-8 h-8 rounded-full bg-gray-200 text-gray-600 font-semibold dark:bg-gray-700 dark:text-gray-400">
|
||||
3
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<h4 class="font-medium text-gray-900 dark:text-white">
|
||||
Monitor & Receive Alerts
|
||||
</h4>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Towerops will automatically monitor your devices and alert you of issues
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -71,30 +71,30 @@
|
|||
<div class="mt-8 grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||||
<.link
|
||||
navigate={~p"/sites"}
|
||||
class="rounded-lg border border-zinc-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900"
|
||||
class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
|
||||
>
|
||||
<h3 class="text-sm font-medium text-zinc-500 dark:text-zinc-400">Sites</h3>
|
||||
<p class="mt-2 text-3xl font-bold text-zinc-900 dark:text-zinc-100">{@sites_count}</p>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">Total sites</p>
|
||||
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400">Sites</h3>
|
||||
<p class="mt-2 text-3xl font-bold text-gray-900 dark:text-white">{@sites_count}</p>
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">Total sites</p>
|
||||
</.link>
|
||||
|
||||
<.link
|
||||
navigate={~p"/devices"}
|
||||
class="rounded-lg border border-zinc-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900"
|
||||
class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
|
||||
>
|
||||
<h3 class="text-sm font-medium text-zinc-500 dark:text-zinc-400">Device</h3>
|
||||
<p class="mt-2 text-3xl font-bold text-zinc-900 dark:text-zinc-100">{@device_count}</p>
|
||||
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400">Device</h3>
|
||||
<p class="mt-2 text-3xl font-bold text-gray-900 dark:text-white">{@device_count}</p>
|
||||
<div class="mt-3 space-y-1.5 text-sm">
|
||||
<div class="flex items-center gap-2 text-zinc-700 dark:text-zinc-300">
|
||||
<div class="flex items-center gap-2 text-gray-700 dark:text-gray-300">
|
||||
<span class="h-2 w-2 rounded-full bg-green-500"></span>
|
||||
{@device_up} Up
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-zinc-700 dark:text-zinc-300">
|
||||
<div class="flex items-center gap-2 text-gray-700 dark:text-gray-300">
|
||||
<span class="h-2 w-2 rounded-full bg-red-500"></span>
|
||||
{@device_down} Down
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-zinc-700 dark:text-zinc-300">
|
||||
<span class="h-2 w-2 rounded-full bg-zinc-400"></span>
|
||||
<div class="flex items-center gap-2 text-gray-700 dark:text-gray-300">
|
||||
<span class="h-2 w-2 rounded-full bg-gray-400"></span>
|
||||
{@device_unknown} Unknown
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -102,21 +102,21 @@
|
|||
|
||||
<.link
|
||||
navigate={~p"/orgs/#{@current_organization.slug}/alerts"}
|
||||
class="rounded-lg border border-zinc-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-zinc-800 dark:bg-zinc-900"
|
||||
class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm transition-shadow hover:shadow-md dark:border-white/10 dark:bg-gray-800/50"
|
||||
>
|
||||
<h3 class="text-sm font-medium text-zinc-500 dark:text-zinc-400">Active Alerts</h3>
|
||||
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400">Active Alerts</h3>
|
||||
<p class={[
|
||||
"mt-2 text-3xl font-bold",
|
||||
(length(@active_alerts) > 0 && "text-red-600 dark:text-red-500") ||
|
||||
"text-zinc-900 dark:text-zinc-100"
|
||||
"text-gray-900 dark:text-white"
|
||||
]}>
|
||||
{length(@active_alerts)}
|
||||
</p>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">Requires attention</p>
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">Requires attention</p>
|
||||
</.link>
|
||||
|
||||
<div class="rounded-lg border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<h3 class="text-sm font-medium text-zinc-500 dark:text-zinc-400">System Status</h3>
|
||||
<div class="rounded-lg border border-gray-200 bg-white p-6 shadow-sm dark:border-white/10 dark:bg-gray-800/50">
|
||||
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400">System Status</h3>
|
||||
<div class={[
|
||||
"mt-3 flex items-center gap-2 text-sm font-semibold",
|
||||
(@device_down == 0 && "text-green-600 dark:text-green-500") ||
|
||||
|
|
@ -136,7 +136,7 @@
|
|||
<%= if length(@active_alerts) > 0 do %>
|
||||
<div class="mt-8">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-semibold text-zinc-900 dark:text-zinc-100">Active Alerts</h2>
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Active Alerts</h2>
|
||||
<.link
|
||||
navigate={~p"/orgs/#{@current_organization.slug}/alerts"}
|
||||
class="text-sm font-medium text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400"
|
||||
|
|
@ -153,7 +153,7 @@
|
|||
class="h-5 w-5 flex-shrink-0 text-red-600 dark:text-red-500"
|
||||
/>
|
||||
<div class="flex-1 min-w-0">
|
||||
<h3 class="font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white">
|
||||
<.link
|
||||
navigate={~p"/devices/#{alert.device.id}"}
|
||||
class="hover:text-blue-600 hover:underline dark:hover:text-blue-400"
|
||||
|
|
@ -161,16 +161,16 @@
|
|||
{alert.device.name}
|
||||
</.link>
|
||||
</h3>
|
||||
<p class="mt-0.5 text-sm text-zinc-700 dark:text-zinc-300">{alert.message}</p>
|
||||
<p class="mt-0.5 text-sm text-gray-700 dark:text-gray-300">{alert.message}</p>
|
||||
</div>
|
||||
<span class="text-xs text-zinc-500 dark:text-zinc-400 whitespace-nowrap">
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
|
||||
{ToweropsWeb.TimeHelpers.format_datetime(alert.triggered_at, @timezone)}
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= if length(@active_alerts) > 5 do %>
|
||||
<div class="text-center text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<div class="text-center text-sm text-gray-500 dark:text-gray-400">
|
||||
+ {length(@active_alerts) - 5} more alerts
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -179,7 +179,7 @@
|
|||
<% end %>
|
||||
|
||||
<div class="mt-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-zinc-900 dark:text-zinc-100">Quick Actions</h2>
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">Quick Actions</h2>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<.link
|
||||
navigate={~p"/sites"}
|
||||
|
|
@ -197,7 +197,7 @@
|
|||
</.link>
|
||||
<.link
|
||||
navigate={~p"/orgs/#{@current_organization.slug}/alerts"}
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-zinc-300 bg-white px-4 py-2.5 text-sm font-semibold text-zinc-700 shadow-sm hover:bg-zinc-50 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700"
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-gray-300 bg-white px-4 py-2.5 text-sm font-semibold text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 dark:border-white/10 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700"
|
||||
>
|
||||
<.icon name="hero-bell" class="h-5 w-5" />
|
||||
<span>View Alerts</span>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
do: ~p"/devices/#{@device.id}",
|
||||
else: ~p"/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"
|
||||
class="inline-flex items-center gap-1 text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="h-4 w-4" />
|
||||
{if @live_action == :edit, do: "Back to Device", else: "Back to Device List"}
|
||||
|
|
@ -82,22 +82,22 @@
|
|||
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">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-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">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-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">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-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">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Assign this device to a remote agent for local SNMP polling. Leave empty to inherit from site or organization defaults.
|
||||
</p>
|
||||
<% end %>
|
||||
|
|
@ -108,7 +108,7 @@
|
|||
|
||||
<!-- Monitoring Mode Tabs -->
|
||||
<div class="mb-6">
|
||||
<div class="border-b border-zinc-200 dark:border-zinc-700">
|
||||
<div class="border-b border-gray-200 dark:border-white/10">
|
||||
<nav class="-mb-px flex space-x-8" aria-label="Monitoring mode">
|
||||
<button
|
||||
type="button"
|
||||
|
|
@ -119,7 +119,7 @@
|
|||
@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"
|
||||
"border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:text-gray-400 dark:hover:border-gray-600 dark:hover:text-gray-300"
|
||||
]}
|
||||
>
|
||||
SNMP & ICMP
|
||||
|
|
@ -133,14 +133,14 @@
|
|||
@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"
|
||||
"border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:text-gray-400 dark:hover:border-gray-600 dark:hover:text-gray-300"
|
||||
]}
|
||||
>
|
||||
ICMP Only
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
<%= if @monitoring_mode == "snmp_and_icmp" do %>
|
||||
<p>
|
||||
Monitor device availability with ICMP pings and collect detailed information via SNMP
|
||||
|
|
@ -180,17 +180,17 @@
|
|||
<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">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-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">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-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">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-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>
|
||||
|
|
@ -246,9 +246,9 @@
|
|||
</.form>
|
||||
|
||||
<%= if @live_action == :edit do %>
|
||||
<div class="mt-12 pt-8 border-t border-zinc-200 dark:border-zinc-800">
|
||||
<div class="mt-12 pt-8 border-t border-gray-200 dark:border-white/10">
|
||||
<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">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
Once you delete this device, there is no going back. All monitoring history and alerts will be permanently deleted.
|
||||
</p>
|
||||
<.button
|
||||
|
|
|
|||
|
|
@ -32,15 +32,15 @@
|
|||
<div class="text-center py-16">
|
||||
<.icon
|
||||
name="hero-building-office"
|
||||
class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600"
|
||||
class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500"
|
||||
/>
|
||||
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">
|
||||
Create a site first
|
||||
</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Before adding device, you need to create at least one site location.
|
||||
</p>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Sites help you organize your devices by physical location.
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
|
|
@ -52,9 +52,9 @@
|
|||
<% else %>
|
||||
<%= if @device == [] do %>
|
||||
<div class="text-center py-16">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">No devices</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">No devices</h3>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Get started by adding your first device.
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
|
|
@ -97,13 +97,13 @@
|
|||
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
|
||||
eq.status == :down && "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
|
||||
eq.status == :unknown &&
|
||||
"bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200"
|
||||
"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200"
|
||||
]}>
|
||||
{eq.status |> to_string() |> String.upcase()}
|
||||
</span>
|
||||
</:col>
|
||||
<:col :let={eq} label="Last Checked">
|
||||
<span class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<span class="text-sm text-gray-600 dark:text-gray-400">
|
||||
{ToweropsWeb.TimeHelpers.format_datetime(eq.last_checked_at, @timezone)}
|
||||
</span>
|
||||
</:col>
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
<div class="mb-6">
|
||||
<!-- Breadcrumbs -->
|
||||
<nav class="flex mb-4" aria-label="Breadcrumb">
|
||||
<ol class="inline-flex items-center space-x-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<ol class="inline-flex items-center space-x-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
<li class="inline-flex items-center">
|
||||
<.link
|
||||
navigate={~p"/sites/#{@device.site.id}"}
|
||||
class="hover:text-zinc-900 dark:hover:text-zinc-200"
|
||||
class="hover:text-gray-900 dark:hover:text-white"
|
||||
>
|
||||
{@device.site.name}
|
||||
</.link>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<li aria-current="page">
|
||||
<div class="flex items-center">
|
||||
<.icon name="hero-chevron-right" class="h-4 w-4 mx-1" />
|
||||
<span class="text-zinc-900 dark:text-zinc-100 font-medium">{@device.name}</span>
|
||||
<span class="text-gray-900 dark:text-white font-medium">{@device.name}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">{@device.name}</h1>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 font-mono">{@device.ip_address}</p>
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">{@device.name}</h1>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 font-mono">{@device.ip_address}</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<.button navigate={~p"/devices/#{@device.id}/edit"}>
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- Tabs -->
|
||||
<div class="border-b border-zinc-200 dark:border-zinc-700">
|
||||
<div class="border-b border-gray-200 dark:border-white/10">
|
||||
<nav class="-mb-px flex space-x-8">
|
||||
<.link
|
||||
patch={~p"/devices/#{@device.id}?tab=overview"}
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
if @active_tab == "overview" do
|
||||
"border-blue-500 text-blue-600 dark:text-blue-400"
|
||||
else
|
||||
"border-transparent text-zinc-500 hover:text-zinc-700 hover:border-zinc-300 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||
"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
end
|
||||
]}
|
||||
>
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
if @active_tab == "ports" do
|
||||
"border-blue-500 text-blue-600 dark:text-blue-400"
|
||||
else
|
||||
"border-transparent text-zinc-500 hover:text-zinc-700 hover:border-zinc-300 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||
"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
end
|
||||
]}
|
||||
>
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
if @active_tab == "neighbors" do
|
||||
"border-blue-500 text-blue-600 dark:text-blue-400"
|
||||
else
|
||||
"border-transparent text-zinc-500 hover:text-zinc-700 hover:border-zinc-300 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||
"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
end
|
||||
]}
|
||||
>
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
if @active_tab == "logs" do
|
||||
"border-blue-500 text-blue-600 dark:text-blue-400"
|
||||
else
|
||||
"border-transparent text-zinc-500 hover:text-zinc-700 hover:border-zinc-300 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||
"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
end
|
||||
]}
|
||||
>
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
if @active_tab == "debug" do
|
||||
"border-blue-500 text-blue-600 dark:text-blue-400"
|
||||
else
|
||||
"border-transparent text-zinc-500 hover:text-zinc-700 hover:border-zinc-300 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||
"border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300"
|
||||
end
|
||||
]}
|
||||
>
|
||||
|
|
@ -124,39 +124,39 @@
|
|||
<!-- Left Column: Device Information & Traffic -->
|
||||
<div class="space-y-6">
|
||||
<!-- Device Information -->
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Device Information
|
||||
</h3>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<dl class="space-y-1">
|
||||
<%= if @snmp_device do %>
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">System Name</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">System Name</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{@snmp_device.sys_name || @device.name}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Resolved IP</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100 font-mono">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Resolved IP</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white font-mono">
|
||||
{@device.ip_address}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Hardware</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Hardware</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{@snmp_device.model || "N/A"}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Operating System</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Operating System</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{if @snmp_device.manufacturer && @snmp_device.firmware_version do
|
||||
"#{@snmp_device.manufacturer} #{@snmp_device.firmware_version}"
|
||||
else
|
||||
|
|
@ -165,59 +165,59 @@
|
|||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Object ID</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100 font-mono">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Object ID</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white font-mono">
|
||||
{@snmp_device.sys_object_id || "N/A"}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Contact</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Contact</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{@snmp_device.sys_contact || "N/A"}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Location</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Location</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{@snmp_device.sys_location || "N/A"}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Uptime</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Uptime</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{format_uptime(@snmp_device.sys_uptime)}
|
||||
</dd>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Name</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Name</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{@device.name}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">IP Address</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100 font-mono">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">IP Address</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white font-mono">
|
||||
{@device.ip_address}
|
||||
</dd>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Device Added</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Device Added</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{format_device_age(@device.inserted_at)}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between py-1.5">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">Last Discovered</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">Last Discovered</dt>
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{if @device.last_discovery_at do
|
||||
format_device_age(@device.last_discovery_at)
|
||||
else
|
||||
|
|
@ -230,16 +230,16 @@
|
|||
</div>
|
||||
<!-- Overall Traffic Chart -->
|
||||
<%= if @traffic_chart_data do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/traffic"}
|
||||
class="block px-4 py-3 border-b border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-750 transition-colors"
|
||||
class="block px-4 py-3 border-b border-gray-200 dark:border-white/10 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Overall Traffic
|
||||
</h3>
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-zinc-400" />
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-gray-400" />
|
||||
</div>
|
||||
</.link>
|
||||
<div class="p-4">
|
||||
|
|
@ -259,16 +259,16 @@
|
|||
<% end %>
|
||||
<!-- ICMP Latency Chart -->
|
||||
<%= if @latency_chart_data do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/latency"}
|
||||
class="block px-4 py-3 border-b border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-750 transition-colors"
|
||||
class="block px-4 py-3 border-b border-gray-200 dark:border-white/10 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
ICMP Latency
|
||||
</h3>
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-zinc-400" />
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-gray-400" />
|
||||
</div>
|
||||
</.link>
|
||||
<div class="p-4">
|
||||
|
|
@ -290,16 +290,16 @@
|
|||
<div class="space-y-6">
|
||||
<!-- CPU Usage Chart -->
|
||||
<%= if @cpu_chart_data do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/processors"}
|
||||
class="block px-4 py-3 border-b border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-750 transition-colors"
|
||||
class="block px-4 py-3 border-b border-gray-200 dark:border-white/10 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Processors
|
||||
</h3>
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-zinc-400" />
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-gray-400" />
|
||||
</div>
|
||||
</.link>
|
||||
<div class="p-4">
|
||||
|
|
@ -316,16 +316,16 @@
|
|||
<% end %>
|
||||
<!-- Memory Usage Chart -->
|
||||
<%= if @memory_chart_data do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/memory"}
|
||||
class="block px-4 py-3 border-b border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-750 transition-colors"
|
||||
class="block px-4 py-3 border-b border-gray-200 dark:border-white/10 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Memory Usage
|
||||
</h3>
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-zinc-400" />
|
||||
<.icon name="hero-arrow-right" class="h-4 w-4 text-gray-400" />
|
||||
</div>
|
||||
</.link>
|
||||
<div class="p-4">
|
||||
|
|
@ -342,17 +342,17 @@
|
|||
<% end %>
|
||||
<!-- Storage Usage -->
|
||||
<%= if @storage_sensors && length(@storage_sensors) > 0 do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Storage Usage
|
||||
</h3>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<dl class="space-y-1">
|
||||
<%= for sensor <- @storage_sensors do %>
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/storage"}
|
||||
class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
|
||||
|
|
@ -360,7 +360,7 @@
|
|||
{sensor.sensor_descr}
|
||||
</.link>
|
||||
</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
<%= if sensor.latest_reading do %>
|
||||
{format_sensor_value(
|
||||
sensor.latest_reading.value,
|
||||
|
|
@ -379,17 +379,17 @@
|
|||
<% end %>
|
||||
<!-- Temperature Sensors -->
|
||||
<%= if @temperature_sensors && length(@temperature_sensors) > 0 do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Temperature
|
||||
</h3>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<dl class="space-y-1">
|
||||
<%= for sensor <- @temperature_sensors do %>
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/temperature"}
|
||||
class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
|
||||
|
|
@ -397,7 +397,7 @@
|
|||
{sensor.sensor_descr}
|
||||
</.link>
|
||||
</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
<%= if sensor.latest_reading do %>
|
||||
{format_sensor_value(
|
||||
sensor.latest_reading.value,
|
||||
|
|
@ -416,15 +416,15 @@
|
|||
<% end %>
|
||||
<!-- Voltage Sensors -->
|
||||
<%= if @voltage_sensors && length(@voltage_sensors) > 0 do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">Voltage</h3>
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Voltage</h3>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<dl class="space-y-1">
|
||||
<%= for sensor <- @voltage_sensors do %>
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/voltage"}
|
||||
class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
|
||||
|
|
@ -432,7 +432,7 @@
|
|||
{sensor.sensor_descr}
|
||||
</.link>
|
||||
</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
<%= if sensor.latest_reading do %>
|
||||
{format_sensor_value(
|
||||
sensor.latest_reading.value,
|
||||
|
|
@ -451,9 +451,9 @@
|
|||
<% end %>
|
||||
<!-- SFP Transceivers -->
|
||||
<%= if @grouped_transceivers && length(@grouped_transceivers) > 0 do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Transceivers
|
||||
</h3>
|
||||
</div>
|
||||
|
|
@ -461,8 +461,8 @@
|
|||
<dl class="space-y-1">
|
||||
<%= for {_transceiver_name, sensors} <- @grouped_transceivers do %>
|
||||
<%= for sensor <- sensors do %>
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/dbm"}
|
||||
class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
|
||||
|
|
@ -470,7 +470,7 @@
|
|||
{sensor.sensor_descr}
|
||||
</.link>
|
||||
</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100 font-mono">
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white font-mono">
|
||||
<%= if sensor.latest_reading do %>
|
||||
{format_sensor_value(
|
||||
sensor.latest_reading.value,
|
||||
|
|
@ -490,15 +490,15 @@
|
|||
<% end %>
|
||||
<!-- Count Sensors (DHCP Leases, Connections, etc.) -->
|
||||
<%= if @count_sensors && length(@count_sensors) > 0 do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">Counters</h3>
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Counters</h3>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<dl class="space-y-1">
|
||||
<%= for sensor <- @count_sensors do %>
|
||||
<div class="flex justify-between py-1.5 border-b border-zinc-100 dark:border-zinc-800">
|
||||
<dt class="text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<div class="flex justify-between py-1.5 border-b border-gray-100 dark:border-white/5">
|
||||
<dt class="text-sm text-gray-600 dark:text-gray-400">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device.id}/graph/count"}
|
||||
class="hover:text-blue-600 dark:hover:text-blue-400 hover:underline"
|
||||
|
|
@ -506,7 +506,7 @@
|
|||
{sensor.sensor_descr}
|
||||
</.link>
|
||||
</dt>
|
||||
<dd class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<dd class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
<%= if sensor.latest_reading do %>
|
||||
{trunc(sensor.latest_reading.value)}
|
||||
<% else %>
|
||||
|
|
@ -525,19 +525,19 @@
|
|||
<%= if @snmp_interfaces && length(@snmp_interfaces) > 0 do %>
|
||||
<div class="space-y-6">
|
||||
<%= for {category, interfaces} <- @interfaces_by_type do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
{category} Interfaces
|
||||
<span class="ml-2 text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||
<span class="ml-2 text-xs font-normal text-gray-500 dark:text-gray-400">
|
||||
({length(interfaces)})
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<thead class="bg-zinc-50 dark:bg-zinc-900">
|
||||
<tr class="text-xs text-zinc-600 dark:text-zinc-400">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
|
||||
<thead class="bg-gray-50 dark:bg-gray-800/75">
|
||||
<tr class="text-xs text-gray-600 dark:text-gray-400">
|
||||
<th class="px-4 py-3 text-left font-medium">#</th>
|
||||
<th class="px-4 py-3 text-left font-medium">Name</th>
|
||||
<th class="px-4 py-3 text-left font-medium">Status</th>
|
||||
|
|
@ -545,10 +545,10 @@
|
|||
<th class="px-4 py-3 text-left font-medium">MAC</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-white/10">
|
||||
<%= for interface <- interfaces do %>
|
||||
<tr class="text-sm hover:bg-zinc-50 dark:hover:bg-zinc-900">
|
||||
<td class="px-4 py-3 text-zinc-900 dark:text-zinc-100">
|
||||
<tr class="text-sm hover:bg-gray-50 dark:hover:bg-gray-800">
|
||||
<td class="px-4 py-3 text-gray-900 dark:text-white">
|
||||
{interface.if_index}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
|
|
@ -558,11 +558,11 @@
|
|||
}
|
||||
class="hover:text-blue-600 dark:hover:text-blue-400"
|
||||
>
|
||||
<div class="font-medium text-zinc-900 dark:text-zinc-100 hover:underline">
|
||||
<div class="font-medium text-gray-900 dark:text-white hover:underline">
|
||||
{interface.if_name || interface.if_descr}
|
||||
</div>
|
||||
<%= if interface.if_alias do %>
|
||||
<div class="text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">
|
||||
{interface.if_alias}
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -576,15 +576,15 @@
|
|||
interface.if_oper_status == "down" &&
|
||||
"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
|
||||
interface.if_oper_status not in ["up", "down"] &&
|
||||
"bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200"
|
||||
"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200"
|
||||
]}>
|
||||
{String.upcase(interface.if_oper_status || "unknown")}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-zinc-900 dark:text-zinc-100">
|
||||
<td class="px-4 py-3 text-gray-900 dark:text-white">
|
||||
{format_speed(interface.if_speed)}
|
||||
</td>
|
||||
<td class="px-4 py-3 font-mono text-xs text-zinc-600 dark:text-zinc-400">
|
||||
<td class="px-4 py-3 font-mono text-xs text-gray-600 dark:text-gray-400">
|
||||
{interface.if_phys_address || "-"}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -597,21 +597,21 @@
|
|||
</div>
|
||||
<% else %>
|
||||
<div class="text-center py-12">
|
||||
<p class="text-zinc-500 dark:text-zinc-400">No interfaces discovered</p>
|
||||
<p class="text-gray-500 dark:text-gray-400">No interfaces discovered</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<% "neighbors" -> %>
|
||||
<%= if @neighbors && length(@neighbors) > 0 do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Discovered Neighbors
|
||||
</h3>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<thead class="bg-zinc-50 dark:bg-zinc-900">
|
||||
<tr class="text-xs text-zinc-600 dark:text-zinc-400">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
|
||||
<thead class="bg-gray-50 dark:bg-gray-800/75">
|
||||
<tr class="text-xs text-gray-600 dark:text-gray-400">
|
||||
<th class="px-4 py-3 text-left font-medium">Protocol</th>
|
||||
<th class="px-4 py-3 text-left font-medium">Local Port</th>
|
||||
<th class="px-4 py-3 text-left font-medium">Remote Device</th>
|
||||
|
|
@ -621,9 +621,9 @@
|
|||
<th class="px-4 py-3 text-left font-medium">Last Seen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-white/10">
|
||||
<%= for neighbor <- @neighbors do %>
|
||||
<tr class="text-sm hover:bg-zinc-50 dark:hover:bg-zinc-900">
|
||||
<tr class="text-sm hover:bg-gray-50 dark:hover:bg-gray-800">
|
||||
<td class="px-4 py-3">
|
||||
<span class={[
|
||||
"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium uppercase",
|
||||
|
|
@ -635,7 +635,7 @@
|
|||
{neighbor.protocol}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-zinc-900 dark:text-zinc-100">
|
||||
<td class="px-4 py-3 text-gray-900 dark:text-white">
|
||||
{neighbor.interface.if_name || neighbor.interface.if_descr}
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
|
|
@ -647,7 +647,7 @@
|
|||
{neighbor.matched_device.name}
|
||||
</.link>
|
||||
<% else %>
|
||||
<div class="text-zinc-900 dark:text-zinc-100">
|
||||
<div class="text-gray-900 dark:text-white">
|
||||
<%= if neighbor.remote_system_name do %>
|
||||
{neighbor.remote_system_name |> String.split("/") |> List.first()}
|
||||
<% else %>
|
||||
|
|
@ -657,26 +657,26 @@
|
|||
<% end %>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<div class="text-zinc-900 dark:text-zinc-100">
|
||||
<div class="text-gray-900 dark:text-white">
|
||||
{neighbor.remote_port_id || "-"}
|
||||
</div>
|
||||
<%= if !neighbor.matched_device && neighbor.remote_chassis_id do %>
|
||||
<div class="text-xs font-mono text-zinc-500 dark:text-zinc-400">
|
||||
<div class="text-xs font-mono text-gray-500 dark:text-gray-400">
|
||||
{neighbor.remote_chassis_id}
|
||||
</div>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-zinc-600 dark:text-zinc-400">
|
||||
<td class="px-4 py-3 text-xs text-gray-600 dark:text-gray-400">
|
||||
{neighbor.remote_platform || "-"}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-zinc-600 dark:text-zinc-400">
|
||||
<td class="px-4 py-3 text-xs text-gray-600 dark:text-gray-400">
|
||||
<%= if neighbor.remote_capabilities && length(neighbor.remote_capabilities) > 0 do %>
|
||||
{Enum.join(neighbor.remote_capabilities, ", ")}
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<td class="px-4 py-3 text-xs text-gray-500 dark:text-gray-400">
|
||||
{time_ago(neighbor.last_discovered_at)}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -686,30 +686,30 @@
|
|||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700 p-12">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-12">
|
||||
<div class="text-center">
|
||||
<.icon name="hero-server-stack" class="mx-auto h-12 w-12 text-zinc-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<.icon name="hero-server-stack" class="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
No neighbors discovered
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
This device doesn't have any LLDP or CDP neighbors, or neighbor discovery hasn't run yet.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% "logs" -> %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">Event Logs</h3>
|
||||
<p class="text-xs text-zinc-600 dark:text-zinc-400 mt-1">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Event Logs</h3>
|
||||
<p class="text-xs text-gray-600 dark:text-gray-400 mt-1">
|
||||
Showing the most recent 100 events
|
||||
</p>
|
||||
</div>
|
||||
<%= if Enum.any?(@events) do %>
|
||||
<div class="divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<div class="divide-y divide-gray-200 dark:divide-white/10">
|
||||
<%= for event <- @events do %>
|
||||
<div class="px-4 py-3 hover:bg-zinc-50 dark:hover:bg-zinc-750">
|
||||
<div class="px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-800">
|
||||
<div class="flex items-start gap-3">
|
||||
<!-- Severity Icon -->
|
||||
<div class={[
|
||||
|
|
@ -732,16 +732,16 @@
|
|||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="flex-1">
|
||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<p class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{event.message}
|
||||
</p>
|
||||
<div class="mt-1 flex items-center gap-3 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<div class="mt-1 flex items-center gap-3 text-xs text-gray-500 dark:text-gray-400">
|
||||
<span>{format_event_type(event.event_type)}</span>
|
||||
<span>•</span>
|
||||
<span class="capitalize">{event.severity}</span>
|
||||
</div>
|
||||
</div>
|
||||
<time class="flex-shrink-0 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<time class="flex-shrink-0 text-xs text-gray-500 dark:text-gray-400">
|
||||
{time_ago(event.occurred_at)}
|
||||
</time>
|
||||
</div>
|
||||
|
|
@ -752,23 +752,23 @@
|
|||
</div>
|
||||
<% else %>
|
||||
<div class="p-8 text-center">
|
||||
<.icon name="hero-document-text" class="mx-auto h-12 w-12 text-zinc-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<.icon name="hero-document-text" class="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
No events yet
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
Events will appear here as interface states change, speeds change, or other monitored changes occur.
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% "debug" -> %>
|
||||
<div class="bg-white dark:bg-zinc-800 shadow sm:rounded-lg">
|
||||
<div class="bg-white dark:bg-gray-800/50 shadow sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:p-6">
|
||||
<h3 class="text-lg font-medium leading-6 text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-white">
|
||||
Raw Discovery Data
|
||||
</h3>
|
||||
<div class="mt-2 max-w-xl text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<div class="mt-2 max-w-xl text-sm text-gray-500 dark:text-gray-400">
|
||||
<p>
|
||||
Raw SNMP OID values collected during the last discovery run at
|
||||
<%= if @snmp_device.last_discovery_at do %>
|
||||
|
|
@ -780,34 +780,34 @@
|
|||
</div>
|
||||
<%= if @snmp_device.raw_discovery_data do %>
|
||||
<div class="mt-5">
|
||||
<h4 class="text-sm font-medium text-zinc-900 dark:text-zinc-100 mb-3">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mb-3">
|
||||
System OIDs
|
||||
</h4>
|
||||
<div class="overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<table class="min-w-full divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<thead class="bg-zinc-50 dark:bg-zinc-900">
|
||||
<div class="overflow-hidden rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
|
||||
<thead class="bg-gray-50 dark:bg-gray-800/75">
|
||||
<tr>
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
||||
Field
|
||||
</th>
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
||||
OID
|
||||
</th>
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white dark:bg-zinc-800 divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<tbody class="bg-white dark:bg-gray-800/50 divide-y divide-gray-200 dark:divide-white/10">
|
||||
<%= for {key, data} <- Map.get(@snmp_device.raw_discovery_data, "system_oids", %{}) do %>
|
||||
<tr>
|
||||
<td class="px-3 py-4 whitespace-nowrap text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
<td class="px-3 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">
|
||||
{key}
|
||||
</td>
|
||||
<td class="px-3 py-4 whitespace-nowrap text-sm text-zinc-500 dark:text-zinc-400 font-mono">
|
||||
<td class="px-3 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 font-mono">
|
||||
{data["oid"]}
|
||||
</td>
|
||||
<td class="px-3 py-4 text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<td class="px-3 py-4 text-sm text-gray-900 dark:text-white">
|
||||
<code class="text-xs">{inspect(data["value"])}</code>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -817,28 +817,28 @@
|
|||
</div>
|
||||
|
||||
<%= if Map.get(@snmp_device.raw_discovery_data, "health_sensor_table") do %>
|
||||
<h4 class="text-sm font-medium text-zinc-900 dark:text-zinc-100 mt-6 mb-3">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mt-6 mb-3">
|
||||
Health Sensor Table Walk
|
||||
</h4>
|
||||
<div class="overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<table class="min-w-full divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<thead class="bg-zinc-50 dark:bg-zinc-900">
|
||||
<div class="overflow-hidden rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
|
||||
<thead class="bg-gray-50 dark:bg-gray-800/75">
|
||||
<tr>
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
||||
OID
|
||||
</th>
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 uppercase tracking-wider">
|
||||
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white dark:bg-zinc-800 divide-y divide-zinc-200 dark:divide-zinc-700">
|
||||
<tbody class="bg-white dark:bg-gray-800/50 divide-y divide-gray-200 dark:divide-white/10">
|
||||
<%= for {oid, value} <- Map.get(@snmp_device.raw_discovery_data, "health_sensor_table", %{}) do %>
|
||||
<tr>
|
||||
<td class="px-3 py-4 whitespace-nowrap text-sm font-mono text-zinc-500 dark:text-zinc-400">
|
||||
<td class="px-3 py-4 whitespace-nowrap text-sm font-mono text-gray-500 dark:text-gray-400">
|
||||
{oid}
|
||||
</td>
|
||||
<td class="px-3 py-4 text-sm text-zinc-900 dark:text-zinc-100">
|
||||
<td class="px-3 py-4 text-sm text-gray-900 dark:text-white">
|
||||
<code class="text-xs">{inspect(value)}</code>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -848,24 +848,24 @@
|
|||
</div>
|
||||
<% end %>
|
||||
|
||||
<h4 class="text-sm font-medium text-zinc-900 dark:text-zinc-100 mt-6 mb-3">
|
||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mt-6 mb-3">
|
||||
Copyable Debug Data
|
||||
</h4>
|
||||
<div class="rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<textarea
|
||||
readonly
|
||||
rows="10"
|
||||
class="w-full p-3 font-mono text-xs bg-zinc-50 dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 border-0 rounded-lg focus:ring-2 focus:ring-blue-500"
|
||||
class="w-full p-3 font-mono text-xs bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white border-0 rounded-lg focus:ring-2 focus:ring-blue-500"
|
||||
onclick="this.select()"
|
||||
><%= Jason.encode!(@snmp_device.raw_discovery_data, pretty: true) %></textarea>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
Click the text box to select all data, then copy with Cmd+C or Ctrl+C
|
||||
</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="mt-5 p-4 bg-zinc-50 dark:bg-zinc-900 rounded-md">
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<div class="mt-5 p-4 bg-gray-50 dark:bg-gray-900 rounded-md">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
No raw discovery data available. Run discovery again to collect debug data.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -874,7 +874,7 @@
|
|||
</div>
|
||||
<% _ -> %>
|
||||
<div class="text-center py-12">
|
||||
<p class="text-zinc-500 dark:text-zinc-400">Tab not found</p>
|
||||
<p class="text-gray-500 dark:text-gray-400">Tab not found</p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,19 +11,19 @@
|
|||
<div class="flex items-center gap-4">
|
||||
<.link
|
||||
navigate={~p"/devices/#{@device_id}"}
|
||||
class="text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
|
||||
class="text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="h-5 w-5" />
|
||||
</.link>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">{@chart_title}</h1>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">{@device.name}</p>
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">{@chart_title}</h1>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">{@device.name}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Date Range Selector -->
|
||||
<div class="flex items-center gap-2 mb-6">
|
||||
<span class="text-sm font-medium text-zinc-700 dark:text-zinc-300">Time Range:</span>
|
||||
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Time Range:</span>
|
||||
<div class="flex gap-1">
|
||||
<%= for {label, value} <- [{"1 Hour", "1h"}, {"6 Hours", "6h"}, {"12 Hours", "12h"}, {"24 Hours", "24h"}, {"7 Days", "7d"}, {"30 Days", "30d"}] do %>
|
||||
<button
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
if @range == value do
|
||||
"bg-blue-500 text-white border-blue-500"
|
||||
else
|
||||
"bg-white dark:bg-zinc-800 text-zinc-700 dark:text-zinc-300 border-zinc-300 dark:border-zinc-600 hover:bg-zinc-50 dark:hover:bg-zinc-700"
|
||||
"bg-white dark:bg-gray-800/50 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-white/10 hover:bg-gray-50 dark:hover:bg-gray-800"
|
||||
end
|
||||
]}
|
||||
>
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
</div>
|
||||
<!-- Large Chart -->
|
||||
<%= if @chart_data do %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="p-6">
|
||||
<div
|
||||
id="detail-chart"
|
||||
|
|
@ -62,13 +62,13 @@
|
|||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700 p-12">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-12">
|
||||
<div class="text-center">
|
||||
<.icon name="hero-chart-bar" class="mx-auto h-12 w-12 text-zinc-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<.icon name="hero-chart-bar" class="mx-auto h-12 w-12 text-gray-400" />
|
||||
<h3 class="mt-2 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
No sensor data available
|
||||
</h3>
|
||||
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||
This device doesn't have any sensors of this type.
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -92,13 +92,13 @@ defmodule ToweropsWeb.MobileQRLive do
|
|||
</.header>
|
||||
|
||||
<div :if={!@completed} class="mt-8">
|
||||
<div class="rounded-lg bg-white p-8 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-700">
|
||||
<div class="rounded-lg bg-white p-8 shadow-sm ring-1 ring-gray-200 dark:bg-gray-800/50 dark:ring-white/10">
|
||||
<div class="flex flex-col items-center space-y-6">
|
||||
<div class="text-center">
|
||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
|
||||
Scan with Mobile App
|
||||
</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Open the Towerops mobile app and scan this QR code to log in
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -112,17 +112,17 @@ defmodule ToweropsWeb.MobileQRLive do
|
|||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<p class="text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
This QR code expires in 5 minutes
|
||||
</p>
|
||||
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
Waiting for mobile app to scan...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="h-2 w-2 animate-pulse rounded-full bg-blue-500"></div>
|
||||
<span class="text-sm text-zinc-600 dark:text-zinc-400">Checking...</span>
|
||||
<span class="text-sm text-gray-600 dark:text-gray-400">Checking...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -164,23 +164,23 @@ defmodule ToweropsWeb.MobileQRLive do
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 rounded-lg bg-white p-4 dark:bg-zinc-800">
|
||||
<div class="mt-4 rounded-lg bg-white p-4 dark:bg-gray-800/50">
|
||||
<dl class="space-y-2 text-sm">
|
||||
<div>
|
||||
<dt class="font-medium text-zinc-700 dark:text-zinc-300">Device Name</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="font-medium text-gray-700 dark:text-gray-300">Device Name</dt>
|
||||
<dd class="mt-1 text-gray-900 dark:text-white">
|
||||
{@mobile_session.device_name || "Unknown"}
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="font-medium text-zinc-700 dark:text-zinc-300">Device OS</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="font-medium text-gray-700 dark:text-gray-300">Device OS</dt>
|
||||
<dd class="mt-1 text-gray-900 dark:text-white">
|
||||
{@mobile_session.device_os || "Unknown"}
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="font-medium text-zinc-700 dark:text-zinc-300">App Version</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-zinc-100">
|
||||
<dt class="font-medium text-gray-700 dark:text-gray-300">App Version</dt>
|
||||
<dd class="mt-1 text-gray-900 dark:text-white">
|
||||
{@mobile_session.app_version || "Unknown"}
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -200,7 +200,7 @@ defmodule ToweropsWeb.MobileQRLive do
|
|||
<div class="mt-6">
|
||||
<.link
|
||||
navigate={~p"/orgs"}
|
||||
class="text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
|
||||
class="text-sm font-medium text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
← Back to Organizations
|
||||
</.link>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="mb-4">
|
||||
<.link
|
||||
navigate={~p"/orgs/#{@organization.slug}"}
|
||||
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"
|
||||
class="inline-flex items-center gap-1 text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="h-4 w-4" /> Back to Dashboard
|
||||
</.link>
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<div class="mt-6 border-t pt-6">
|
||||
<h3 class="text-lg font-medium mb-4">SNMP Configuration</h3>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
Set default SNMP settings for all devices in this organization. These can be overridden at the site or device level.
|
||||
</p>
|
||||
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
placeholder="e.g., public"
|
||||
/>
|
||||
|
||||
<p class="mt-3 text-sm text-zinc-500 dark:text-zinc-400 italic">
|
||||
<p class="mt-3 text-sm text-gray-500 dark:text-gray-400 italic">
|
||||
<.icon name="hero-information-circle" class="h-4 w-4 inline" />
|
||||
SNMP configuration hierarchy: Device > Site > Organization
|
||||
</p>
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
<%= if @available_agents != [] do %>
|
||||
<div class="mt-6 border-t pt-6">
|
||||
<h3 class="text-lg font-medium mb-4">Default Agent</h3>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
Select a default agent for SNMP polling. This will be used for all devices in this organization unless overridden at the site or device level.
|
||||
</p>
|
||||
|
||||
|
|
@ -84,11 +84,11 @@
|
|||
options={Enum.map(@available_agents, &{&1.name, &1.id})}
|
||||
/>
|
||||
|
||||
<div class="mt-3 p-3 bg-zinc-50 dark:bg-zinc-800 rounded-lg text-sm">
|
||||
<p class="font-medium text-zinc-700 dark:text-zinc-300 mb-2">
|
||||
<div class="mt-3 p-3 bg-gray-50 dark:bg-gray-800/50 rounded-lg text-sm">
|
||||
<p class="font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
Current Device Assignment:
|
||||
</p>
|
||||
<div class="space-y-1 text-zinc-600 dark:text-zinc-400">
|
||||
<div class="space-y-1 text-gray-600 dark:text-gray-400">
|
||||
<div class="flex items-center gap-2">
|
||||
<.icon name="hero-server" class="h-4 w-4" />
|
||||
<span>
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mt-3 text-sm text-zinc-500 dark:text-zinc-400 italic">
|
||||
<p class="mt-3 text-sm text-gray-500 dark:text-gray-400 italic">
|
||||
<.icon name="hero-information-circle" class="h-4 w-4 inline" />
|
||||
Agent assignment hierarchy: Device > Site > Organization
|
||||
</p>
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
<% else %>
|
||||
<div class="mt-6 border-t pt-6">
|
||||
<h3 class="text-lg font-medium mb-2">Default Agent</h3>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
No agents configured yet.
|
||||
<.link
|
||||
navigate={~p"/orgs/#{@organization.slug}/agents"}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@
|
|||
<.link
|
||||
:for={org <- @organizations}
|
||||
navigate={~p"/orgs/#{org.slug}"}
|
||||
class="relative overflow-hidden rounded-lg border border-zinc-200 bg-white p-6 shadow-sm hover:shadow-md transition-shadow dark:border-zinc-800 dark:bg-zinc-900 cursor-pointer"
|
||||
class="relative overflow-hidden rounded-lg border border-gray-200 bg-white p-6 shadow-sm hover:shadow-md transition-shadow dark:border-white/10 dark:bg-gray-800/50 cursor-pointer"
|
||||
>
|
||||
<h2 class="text-xl font-semibold text-zinc-900 dark:text-zinc-100">{org.name}</h2>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">{org.name}</h2>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
{Enum.find(org.memberships, &(&1.user_id == @current_scope.user.id)).role
|
||||
|> to_string()
|
||||
|> String.capitalize()}
|
||||
|
|
@ -29,9 +29,9 @@
|
|||
</div>
|
||||
|
||||
<div :if={@organizations == []} class="text-center py-16">
|
||||
<.icon name="hero-building-office" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">No organizations</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<.icon name="hero-building-office" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-600" />
|
||||
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">No organizations</h3>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Get started by creating a new organization.
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
do: ~p"/sites/#{@site.id}",
|
||||
else: ~p"/sites"
|
||||
}
|
||||
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"
|
||||
class="inline-flex items-center gap-1 text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
>
|
||||
<.icon name="hero-arrow-left" class="h-4 w-4" />
|
||||
{if @live_action == :edit, do: "Back to Site", else: "Back to Sites"}
|
||||
|
|
@ -33,14 +33,14 @@
|
|||
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<span class="block text-sm font-medium text-zinc-900 dark:text-zinc-100 mb-2">
|
||||
<span class="block text-sm font-medium text-gray-900 dark:text-white mb-2">
|
||||
Parent Site
|
||||
<span class="text-zinc-400 dark:text-zinc-500 font-normal">(optional)</span>
|
||||
<span class="text-gray-400 dark:text-gray-500 font-normal">(optional)</span>
|
||||
</span>
|
||||
<select
|
||||
id={@form[:parent_site_id].id}
|
||||
name={@form[:parent_site_id].name}
|
||||
class="block w-full rounded-lg border-0 py-2 px-3 text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700 dark:focus:ring-blue-500"
|
||||
class="block w-full rounded-lg border-0 py-2 px-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6 dark:bg-gray-800/50 dark:text-white dark:ring-white/10 dark:focus:ring-blue-500"
|
||||
>
|
||||
<option value="">No parent site</option>
|
||||
{Phoenix.HTML.Form.options_for_select(
|
||||
|
|
@ -53,29 +53,29 @@
|
|||
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<span class="block text-sm font-medium text-zinc-900 dark:text-zinc-100 mb-2">
|
||||
Location <span class="text-zinc-400 dark:text-zinc-500 font-normal">(optional)</span>
|
||||
<span class="block text-sm font-medium text-gray-900 dark:text-white mb-2">
|
||||
Location <span class="text-gray-400 dark:text-gray-500 font-normal">(optional)</span>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
id={@form[:location].id}
|
||||
name={@form[:location].name}
|
||||
value={@form[:location].value}
|
||||
class="block w-full rounded-lg border-0 py-2 px-3 text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700 dark:focus:ring-blue-500"
|
||||
class="block w-full rounded-lg border-0 py-2 px-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6 dark:bg-gray-800/50 dark:text-white dark:ring-white/10 dark:focus:ring-blue-500"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label>
|
||||
<span class="block text-sm font-medium text-zinc-900 dark:text-zinc-100 mb-2">
|
||||
<span class="block text-sm font-medium text-gray-900 dark:text-white mb-2">
|
||||
Description
|
||||
<span class="text-zinc-400 dark:text-zinc-500 font-normal">(optional)</span>
|
||||
<span class="text-gray-400 dark:text-gray-500 font-normal">(optional)</span>
|
||||
</span>
|
||||
<textarea
|
||||
id={@form[:description].id}
|
||||
name={@form[:description].name}
|
||||
class="block w-full rounded-lg border-0 py-2 px-3 text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700 dark:focus:ring-blue-500"
|
||||
class="block w-full rounded-lg border-0 py-2 px-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6 dark:bg-gray-800/50 dark:text-white dark:ring-white/10 dark:focus:ring-blue-500"
|
||||
>{Phoenix.HTML.Form.normalize_value("textarea", @form[:description].value)}</textarea>
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -84,9 +84,9 @@
|
|||
<div class="mt-6 border-t pt-6">
|
||||
<h3 class="text-base font-medium mb-4">
|
||||
Agent Configuration
|
||||
<span class="text-zinc-400 dark:text-zinc-500 font-normal">(optional)</span>
|
||||
<span class="text-gray-400 dark:text-gray-500 font-normal">(optional)</span>
|
||||
</h3>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
Set a default agent for SNMP polling at this site. This will override the organization default for all devices at this site. Leave blank to inherit from organization.
|
||||
</p>
|
||||
|
||||
|
|
@ -123,12 +123,12 @@
|
|||
</div>
|
||||
<% else %>
|
||||
<%= if Map.get(assigns, :org_agent) do %>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400 flex items-center gap-1">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
||||
<.icon name="hero-building-office-2" class="h-4 w-4" />
|
||||
Currently inheriting organization default: <strong>{@org_agent.name}</strong>
|
||||
</p>
|
||||
<% else %>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
Set a default agent for all devices at this site. Device can override this setting individually.
|
||||
</p>
|
||||
<% end %>
|
||||
|
|
@ -139,9 +139,9 @@
|
|||
<div class="mt-6 border-t pt-6">
|
||||
<h3 class="text-base font-medium mb-4">
|
||||
SNMP Configuration
|
||||
<span class="text-zinc-400 dark:text-zinc-500 font-normal">(optional)</span>
|
||||
<span class="text-gray-400 dark:text-gray-500 font-normal">(optional)</span>
|
||||
</h3>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
Override organization SNMP defaults for all devices at this site. Leave blank to inherit from organization.
|
||||
</p>
|
||||
|
||||
|
|
@ -187,9 +187,9 @@
|
|||
</.form>
|
||||
|
||||
<%= if @live_action == :edit do %>
|
||||
<div class="mt-12 pt-8 border-t border-zinc-200 dark:border-zinc-800">
|
||||
<div class="mt-12 pt-8 border-t border-gray-200 dark:border-white/10">
|
||||
<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">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
Once you delete a site, there is no going back. This will also delete all devices at this site.
|
||||
</p>
|
||||
<.button
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
<div class="text-center py-16">
|
||||
<.icon
|
||||
name="hero-building-office"
|
||||
class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600"
|
||||
class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500"
|
||||
/>
|
||||
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">No sites</h3>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<h3 class="mt-4 text-lg font-semibold text-gray-900 dark:text-white">No sites</h3>
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Get started by creating your first site.
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
|
|
@ -36,16 +36,16 @@
|
|||
<.link
|
||||
:for={site <- @sites}
|
||||
navigate={~p"/sites/#{site.id}"}
|
||||
class="relative overflow-hidden rounded-lg border border-zinc-200 bg-white p-6 shadow-sm hover:shadow-md transition-shadow dark:border-zinc-800 dark:bg-zinc-900 cursor-pointer"
|
||||
class="relative overflow-hidden rounded-lg border border-gray-200 bg-white p-6 shadow-sm hover:shadow-md transition-shadow dark:border-white/10 dark:bg-gray-800/50 cursor-pointer"
|
||||
>
|
||||
<h3 class="text-xl font-semibold text-zinc-900 dark:text-zinc-100">{site.name}</h3>
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">{site.name}</h3>
|
||||
<%= if site.location do %>
|
||||
<p class="mt-2 flex items-center gap-1.5 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-2 flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400">
|
||||
<.icon name="hero-map-pin" class="h-4 w-4" /> {site.location}
|
||||
</p>
|
||||
<% end %>
|
||||
<%= if site.parent_site do %>
|
||||
<p class="mt-2 text-xs text-zinc-500 dark:text-zinc-500">
|
||||
<p class="mt-2 text-xs text-gray-500 dark:text-gray-500">
|
||||
Parent: {site.parent_site.name}
|
||||
</p>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@
|
|||
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-2">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4 text-zinc-900 dark:text-zinc-100">Site Details</h3>
|
||||
<h3 class="text-lg font-semibold mb-4 text-gray-900 dark:text-white">Site Details</h3>
|
||||
<dl class="space-y-4">
|
||||
<%= if @site.parent_site do %>
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Parent Site</dt>
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Parent Site</dt>
|
||||
<dd class="mt-1">
|
||||
<.link
|
||||
navigate={~p"/sites/#{@site.parent_site.id}"}
|
||||
|
|
@ -43,21 +43,21 @@
|
|||
<% end %>
|
||||
<%= if @site.location do %>
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Location</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-zinc-100">{@site.location}</dd>
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Location</dt>
|
||||
<dd class="mt-1 text-gray-900 dark:text-white">{@site.location}</dd>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if @site.description do %>
|
||||
<div>
|
||||
<dt class="text-sm font-medium text-zinc-600 dark:text-zinc-400">Description</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-zinc-100">{@site.description}</dd>
|
||||
<dt class="text-sm font-medium text-gray-600 dark:text-gray-400">Description</dt>
|
||||
<dd class="mt-1 text-gray-900 dark:text-white">{@site.description}</dd>
|
||||
</div>
|
||||
<% end %>
|
||||
</dl>
|
||||
|
||||
<%= if @site.child_sites != [] do %>
|
||||
<div class="mt-6">
|
||||
<h4 class="text-sm font-semibold mb-3 text-zinc-900 dark:text-zinc-100">Child Sites</h4>
|
||||
<h4 class="text-sm font-semibold mb-3 text-gray-900 dark:text-white">Child Sites</h4>
|
||||
<ul class="space-y-2">
|
||||
<li :for={child <- @site.child_sites}>
|
||||
<.link
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
<div>
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">Device</h3>
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Device</h3>
|
||||
<.button
|
||||
navigate={~p"/devices/new?site_id=#{@site.id}"}
|
||||
variant="primary"
|
||||
|
|
@ -84,15 +84,15 @@
|
|||
</div>
|
||||
|
||||
<%= if @device == [] do %>
|
||||
<div class="rounded-lg border-2 border-dashed border-zinc-300 bg-zinc-50 p-8 text-center dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
|
||||
<h4 class="mt-4 text-base font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 p-8 text-center dark:border-white/20 dark:bg-gray-800/50">
|
||||
<.icon name="hero-server" class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" />
|
||||
<h4 class="mt-4 text-base font-semibold text-gray-900 dark:text-white">
|
||||
Add your first device
|
||||
</h4>
|
||||
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Start monitoring by adding network devices to this site.
|
||||
</p>
|
||||
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
|
||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
You can add routers, switches, servers, or any device with an IP address.
|
||||
</p>
|
||||
<div class="mt-6">
|
||||
|
|
@ -109,11 +109,11 @@
|
|||
<.link
|
||||
:for={eq <- @device}
|
||||
navigate={~p"/devices/#{eq.id}"}
|
||||
class="flex items-center justify-between rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900 hover:border-zinc-300 dark:hover:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors cursor-pointer"
|
||||
class="flex items-center justify-between rounded-lg border border-gray-200 bg-white p-4 dark:border-white/10 dark:bg-gray-800/50 hover:border-gray-300 dark:hover:border-white/20 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors cursor-pointer"
|
||||
>
|
||||
<div>
|
||||
<p class="font-medium text-zinc-900 dark:text-zinc-100">{eq.name}</p>
|
||||
<p class="text-sm text-zinc-600 dark:text-zinc-400">{eq.ip_address}</p>
|
||||
<p class="font-medium text-gray-900 dark:text-white">{eq.name}</p>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400">{eq.ip_address}</p>
|
||||
</div>
|
||||
<span class={[
|
||||
"inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
|
||||
eq.status == :down && "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
|
||||
eq.status == :unknown &&
|
||||
"bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200"
|
||||
"bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200"
|
||||
]}>
|
||||
{eq.status |> to_string() |> String.upcase()}
|
||||
</span>
|
||||
|
|
@ -133,9 +133,9 @@
|
|||
<!-- Latency Chart -->
|
||||
<%= if @latency_chart_data do %>
|
||||
<div class="mt-8">
|
||||
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="px-4 py-3 border-b border-zinc-200 dark:border-zinc-700">
|
||||
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
||||
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
Site Latency - Last 24 Hours
|
||||
</h3>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -916,7 +916,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
<div class="flex min-h-screen items-end justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0">
|
||||
<div
|
||||
phx-click="cancel_add_token"
|
||||
class="fixed inset-0 z-0 bg-zinc-500 bg-opacity-75 transition-opacity dark:bg-zinc-950 dark:bg-opacity-75"
|
||||
class="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-950 dark:bg-opacity-75"
|
||||
aria-hidden="true"
|
||||
>
|
||||
</div>
|
||||
|
|
@ -927,7 +927,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
​
|
||||
</span>
|
||||
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-zinc-900 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-gray-800/95 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<.form for={%{}} as={:token} phx-submit="create_api_token">
|
||||
<div>
|
||||
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900">
|
||||
|
|
@ -935,13 +935,13 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
</div>
|
||||
<div class="mt-3 text-center sm:mt-5">
|
||||
<h3
|
||||
class="text-lg font-semibold leading-6 text-zinc-900 dark:text-zinc-100"
|
||||
class="text-lg font-semibold leading-6 text-gray-900 dark:text-white"
|
||||
id="create-api-token-modal-title"
|
||||
>
|
||||
Create API Token
|
||||
</h3>
|
||||
<div class="mt-2">
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Give this token a name and select the organization it will have access to.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -990,7 +990,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
<button
|
||||
type="button"
|
||||
phx-click="cancel_add_token"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-lg bg-white px-3 py-2 text-sm font-semibold text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700 dark:hover:bg-zinc-700 sm:col-start-1 sm:mt-0"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-lg bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 dark:bg-gray-800/50 dark:text-white dark:ring-white/10 dark:hover:bg-gray-800 sm:col-start-1 sm:mt-0"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
|
@ -1013,7 +1013,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
<div class="flex min-h-screen items-end justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0">
|
||||
<div
|
||||
phx-click="close_token_modal"
|
||||
class="fixed inset-0 z-0 bg-zinc-500 bg-opacity-75 transition-opacity dark:bg-zinc-950 dark:bg-opacity-75"
|
||||
class="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-950 dark:bg-opacity-75"
|
||||
aria-hidden="true"
|
||||
>
|
||||
</div>
|
||||
|
|
@ -1024,7 +1024,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
​
|
||||
</span>
|
||||
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-zinc-900 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-gray-800/95 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div>
|
||||
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-green-900">
|
||||
<.icon name="hero-check" class="h-6 w-6 text-green-600 dark:text-green-400" />
|
||||
|
|
@ -1032,18 +1032,18 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
<div class="mt-3 text-center sm:mt-5">
|
||||
<h3
|
||||
id="token-success-modal-title"
|
||||
class="text-lg font-semibold leading-6 text-zinc-900 dark:text-zinc-100"
|
||||
class="text-lg font-semibold leading-6 text-gray-900 dark:text-white"
|
||||
>
|
||||
API Token Created
|
||||
</h3>
|
||||
<div class="mt-2">
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Copy this token now. You won't be able to see it again.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<div class="rounded-lg bg-zinc-50 p-3 dark:bg-zinc-800">
|
||||
<code class="text-sm text-zinc-900 dark:text-zinc-100 break-all">
|
||||
<div class="rounded-lg bg-gray-50 p-3 dark:bg-gray-800/50">
|
||||
<code class="text-sm text-gray-900 dark:text-white break-all">
|
||||
{@created_token}
|
||||
</code>
|
||||
</div>
|
||||
|
|
@ -1074,7 +1074,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
>
|
||||
<div class="flex min-h-screen items-end justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0">
|
||||
<div
|
||||
class="fixed inset-0 z-0 bg-zinc-500 bg-opacity-75 transition-opacity dark:bg-zinc-950 dark:bg-opacity-75"
|
||||
class="fixed inset-0 z-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-950 dark:bg-opacity-75"
|
||||
aria-hidden="true"
|
||||
>
|
||||
</div>
|
||||
|
|
@ -1085,20 +1085,20 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
​
|
||||
</span>
|
||||
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-zinc-900 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div class="relative z-10 inline-block transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left align-bottom shadow-xl transition-all dark:bg-gray-800/95 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div>
|
||||
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-blue-100 dark:bg-blue-900">
|
||||
<.icon name="hero-key" class="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-5">
|
||||
<h3
|
||||
class="text-lg font-semibold leading-6 text-zinc-900 dark:text-zinc-100"
|
||||
class="text-lg font-semibold leading-6 text-gray-900 dark:text-white"
|
||||
id="add-passkey-modal-title"
|
||||
>
|
||||
Add Passkey
|
||||
</h3>
|
||||
<div class="mt-2">
|
||||
<p class="text-sm text-zinc-500 dark:text-zinc-400">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
Give this passkey a name to help you identify it later (e.g., "MacBook Touch ID", "iPhone").
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -1107,7 +1107,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
type="text"
|
||||
id="passkey-name-input"
|
||||
placeholder="e.g., MacBook Touch ID"
|
||||
class="block w-full rounded-lg border-zinc-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100 sm:text-sm"
|
||||
class="block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-white/10 dark:bg-gray-800/50 dark:text-white sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -1129,7 +1129,7 @@ defmodule ToweropsWeb.UserSettingsLive do
|
|||
<button
|
||||
type="button"
|
||||
id="cancel-add-passkey"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-lg bg-white px-3 py-2 text-sm font-semibold text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700 dark:hover:bg-zinc-700 sm:col-start-1 sm:mt-0"
|
||||
class="mt-3 inline-flex w-full justify-center rounded-lg bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 dark:bg-gray-800/50 dark:text-white dark:ring-white/10 dark:hover:bg-gray-800 sm:col-start-1 sm:mt-0"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue