towerops/lib/towerops_web/live/mikrotik_backup_live/compare.html.heex

178 lines
8.6 KiB
Text

<Layouts.app flash={@flash}>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Header -->
<div class="mb-6">
<nav class="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 mb-4">
<.link navigate={~p"/devices"} class="hover:text-gray-700 dark:hover:text-gray-300">
{t("Devices")}
</.link>
<span>/</span>
<.link
navigate={~p"/devices/#{@device.id}"}
class="hover:text-gray-700 dark:hover:text-gray-300"
>
{@device.name}
</.link>
<span>/</span>
<.link
navigate={~p"/devices/#{@device.id}?tab=backups"}
class="hover:text-gray-700 dark:hover:text-gray-300"
>
{t("Backups")}
</.link>
<span>/</span>
<span class="text-gray-900 dark:text-white">Compare</span>
</nav>
<div class="flex items-center justify-between">
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">
{t("Compare Configuration Backups")}
</h1>
<.link
navigate={~p"/devices/#{@device.id}?tab=backups"}
class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-700"
>
<.icon name="hero-arrow-left" class="h-4 w-4" /> Back to Backups
</.link>
</div>
</div>
<!-- Backup Info Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<!-- Backup A -->
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-4">
<div class="flex items-center justify-between mb-2">
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Backup A (Older)</h3>
<button
phx-click="download_config"
phx-value-backup="a"
class="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"
>
<.icon name="hero-arrow-down-tray" class="h-4 w-4" /> Download
</button>
</div>
<dl class="space-y-1 text-sm">
<div class="flex justify-between">
<dt class="text-gray-500 dark:text-gray-400">Date:</dt>
<dd class="text-gray-900 dark:text-white font-mono">
{ToweropsWeb.TimeHelpers.format_iso8601(
@backup_a.backed_up_at,
@current_scope.timezone,
@current_scope.time_format
)}
</dd>
</div>
<div class="flex justify-between">
<dt class="text-gray-500 dark:text-gray-400">Size:</dt>
<dd class="text-gray-900 dark:text-white font-mono">
{format_bytes(@backup_a.config_size_bytes)}
</dd>
</div>
<div class="flex justify-between">
<dt class="text-gray-500 dark:text-gray-400">Source:</dt>
<dd>
<span class={[
"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",
@backup_a.trigger_source == "daily_cron" &&
"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",
@backup_a.trigger_source == "manual" &&
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"
]}>
{String.replace(@backup_a.trigger_source, "_", " ") |> String.capitalize()}
</span>
</dd>
</div>
</dl>
</div>
<!-- Backup B -->
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-4">
<div class="flex items-center justify-between mb-2">
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">Backup B (Newer)</h3>
<button
phx-click="download_config"
phx-value-backup="b"
class="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"
>
<.icon name="hero-arrow-down-tray" class="h-4 w-4" /> Download
</button>
</div>
<dl class="space-y-1 text-sm">
<div class="flex justify-between">
<dt class="text-gray-500 dark:text-gray-400">Date:</dt>
<dd class="text-gray-900 dark:text-white font-mono">
{ToweropsWeb.TimeHelpers.format_iso8601(
@backup_b.backed_up_at,
@current_scope.timezone,
@current_scope.time_format
)}
</dd>
</div>
<div class="flex justify-between">
<dt class="text-gray-500 dark:text-gray-400">Size:</dt>
<dd class="text-gray-900 dark:text-white font-mono">
{format_bytes(@backup_b.config_size_bytes)}
</dd>
</div>
<div class="flex justify-between">
<dt class="text-gray-500 dark:text-gray-400">Source:</dt>
<dd>
<span class={[
"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",
@backup_b.trigger_source == "daily_cron" &&
"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",
@backup_b.trigger_source == "manual" &&
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"
]}>
{String.replace(@backup_b.trigger_source, "_", " ") |> String.capitalize()}
</span>
</dd>
</div>
</dl>
</div>
</div>
<!-- Diff Stats -->
<%= if @diff_output == "" do %>
<div class="bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-4 mb-6">
<div class="flex items-center gap-2">
<.icon name="hero-check-circle" class="h-5 w-5 text-green-600 dark:text-green-400" />
<p class="text-sm text-green-800 dark:text-green-200">
{t("These backups are identical. No differences found.")}
</p>
</div>
</div>
<% else %>
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-4 mb-6">
<div class="flex items-center gap-6 text-sm">
<div class="flex items-center gap-2">
<span class="inline-block w-3 h-3 bg-green-500 rounded-sm"></span>
<span class="text-gray-600 dark:text-gray-400">
{@stats.additions} addition{if @stats.additions != 1, do: "s"}
</span>
</div>
<div class="flex items-center gap-2">
<span class="inline-block w-3 h-3 bg-red-500 rounded-sm"></span>
<span class="text-gray-600 dark:text-gray-400">
{@stats.deletions} deletion{if @stats.deletions != 1, do: "s"}
</span>
</div>
<div class="flex items-center gap-2">
<span class="inline-block w-3 h-3 bg-yellow-500 rounded-sm"></span>
<span class="text-gray-600 dark:text-gray-400">
{@stats.changes} change{if @stats.changes != 1, do: "s"}
</span>
</div>
</div>
</div>
<!-- Unified Diff Display -->
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 overflow-hidden">
<div class="px-4 py-3 border-b border-gray-200 dark:border-white/10 bg-gray-50 dark:bg-gray-800/75">
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">
{t("Configuration Differences")}
</h3>
</div>
<div class="overflow-x-auto">
<pre class="p-4 text-xs font-mono leading-relaxed"><code><%= for line <- String.split(@diff_output, "\n") do %><%= cond do %><% String.starts_with?(line, "+") && !String.starts_with?(line, "+++") -> %><span class="block bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200">{line}</span><% String.starts_with?(line, "-") && !String.starts_with?(line, "---") -> %><span class="block bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200">{line}</span><% String.starts_with?(line, "@@") -> %><span class="block bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300 font-semibold">{line}</span><% String.starts_with?(line, "---") || String.starts_with?(line, "+++") -> %><span class="block text-gray-500 dark:text-gray-500 italic">{line}</span><% true -> %><span class="block text-gray-700 dark:text-gray-300">{line}</span><% end %><% end %></code></pre>
</div>
</div>
<% end %>
</div>
</Layouts.app>