242 lines
10 KiB
Text
242 lines
10 KiB
Text
<Layouts.authenticated
|
|
flash={@flash}
|
|
current_scope={@current_scope}
|
|
active_page="reports"
|
|
unresolved_alert_count={assigns[:unresolved_alert_count] || 0}
|
|
>
|
|
<.breadcrumb items={[
|
|
%{label: "Dashboard", navigate: ~p"/dashboard"},
|
|
%{label: "Reports"}
|
|
]} />
|
|
|
|
<div class="mb-6 flex items-center justify-between">
|
|
<div>
|
|
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">{t("Scheduled Reports")}</h1>
|
|
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
|
{t("Automated report generation and email delivery")}
|
|
</p>
|
|
</div>
|
|
<button
|
|
:if={!@show_form}
|
|
phx-click="show_form"
|
|
class="inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
|
|
>
|
|
<.icon name="hero-plus" class="w-4 h-4" />
|
|
{t("New Report")}
|
|
</button>
|
|
</div>
|
|
|
|
<%!-- Create Report Form --%>
|
|
<%= if @show_form do %>
|
|
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-6 mb-6">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">{t("Create Report")}</h2>
|
|
<button
|
|
phx-click="hide_form"
|
|
class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
|
|
>
|
|
<.icon name="hero-x-mark" class="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
|
|
<.form for={@form} phx-submit="save" class="space-y-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
{t("Report Name")}
|
|
</label>
|
|
<input
|
|
type="text"
|
|
name="report[name]"
|
|
placeholder="Weekly Uptime Report"
|
|
required
|
|
class="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 px-3 py-2 text-sm text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
{t("Report Type")}
|
|
</label>
|
|
<select
|
|
name="report[report_type]"
|
|
required
|
|
class="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 px-3 py-2 text-sm text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
>
|
|
<option value="uptime_summary">{t("Uptime Summary")}</option>
|
|
<option value="alert_history">{t("Alert History")}</option>
|
|
<option value="capacity_trends">{t("Capacity Trends")}</option>
|
|
<option value="rf_link_health">{t("RF Link Health")}</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
{t("Schedule")}
|
|
</label>
|
|
<select
|
|
name="report[schedule_type]"
|
|
class="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 px-3 py-2 text-sm text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
>
|
|
<option value="daily">{t("Daily")}</option>
|
|
<option value="weekly" selected>{t("Weekly")}</option>
|
|
<option value="monthly">{t("Monthly")}</option>
|
|
<option value="one_time">{t("One Time")}</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
{t("Time Range (days)")}
|
|
</label>
|
|
<select
|
|
name="report[scope_days]"
|
|
class="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 px-3 py-2 text-sm text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
>
|
|
<option value="1">{t("Last 24 hours")}</option>
|
|
<option value="7" selected>{t("Last 7 days")}</option>
|
|
<option value="30">{t("Last 30 days")}</option>
|
|
<option value="90">{t("Last 90 days")}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
|
{t("Recipients")}
|
|
<span class="font-normal text-gray-400">
|
|
{t("(comma-separated email addresses)")}
|
|
</span>
|
|
</label>
|
|
<textarea
|
|
name="report[recipients_text]"
|
|
rows="2"
|
|
required
|
|
placeholder="admin@example.com, noc@example.com"
|
|
class="w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 px-3 py-2 text-sm text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
></textarea>
|
|
</div>
|
|
|
|
<div class="flex justify-end gap-2">
|
|
<button
|
|
type="button"
|
|
phx-click="hide_form"
|
|
class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors"
|
|
>
|
|
{t("Cancel")}
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
class="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
|
|
>
|
|
{t("Create Report")}
|
|
</button>
|
|
</div>
|
|
</.form>
|
|
</div>
|
|
<% end %>
|
|
|
|
<%!-- Reports List --%>
|
|
<%= if @reports != [] do %>
|
|
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10">
|
|
<div class="overflow-x-auto">
|
|
<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-2 text-left font-medium">{t("Name")}</th>
|
|
<th class="px-4 py-2 text-left font-medium">{t("Type")}</th>
|
|
<th class="px-4 py-2 text-left font-medium">{t("Schedule")}</th>
|
|
<th class="px-4 py-2 text-left font-medium">{t("Recipients")}</th>
|
|
<th class="px-4 py-2 text-left font-medium">{t("Last Run")}</th>
|
|
<th class="px-4 py-2 text-left font-medium">{t("Status")}</th>
|
|
<th class="px-4 py-2 text-right font-medium">{t("Actions")}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200 dark:divide-white/10">
|
|
<%= for report <- @reports do %>
|
|
<tr class={"text-sm #{if !report.enabled, do: "opacity-50"}"}>
|
|
<td class="px-4 py-3">
|
|
<span class="font-medium text-gray-900 dark:text-white">{report.name}</span>
|
|
</td>
|
|
<td class="px-4 py-3 text-gray-600 dark:text-gray-400">
|
|
{humanize_type(report.report_type)}
|
|
</td>
|
|
<td class="px-4 py-3 text-gray-600 dark:text-gray-400">
|
|
{humanize_schedule(report.schedule)}
|
|
</td>
|
|
<td class="px-4 py-3 text-xs text-gray-500 dark:text-gray-400 max-w-48 truncate">
|
|
{format_recipients(report.recipients)}
|
|
</td>
|
|
<td class="px-4 py-3 text-xs text-gray-500 dark:text-gray-400">
|
|
<%= if report.last_run_at do %>
|
|
{Calendar.strftime(report.last_run_at, "%b %d, %H:%M")}
|
|
<% else %>
|
|
-
|
|
<% end %>
|
|
</td>
|
|
<td class="px-4 py-3">
|
|
<% {label, classes} = status_badge(report.last_run_status) %>
|
|
<span class={"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium #{classes}"}>
|
|
{label}
|
|
</span>
|
|
</td>
|
|
<td class="px-4 py-3 text-right">
|
|
<div class="flex items-center justify-end gap-2">
|
|
<button
|
|
phx-click="run_now"
|
|
phx-value-id={report.id}
|
|
title="Run now"
|
|
class="text-gray-400 hover:text-blue-600 dark:hover:text-blue-400"
|
|
>
|
|
<.icon name="hero-play" class="w-4 h-4" />
|
|
</button>
|
|
<button
|
|
phx-click="toggle"
|
|
phx-value-id={report.id}
|
|
title={if report.enabled, do: "Disable", else: "Enable"}
|
|
class="text-gray-400 hover:text-yellow-600 dark:hover:text-yellow-400"
|
|
>
|
|
<.icon
|
|
name={if report.enabled, do: "hero-pause", else: "hero-play"}
|
|
class="w-4 h-4"
|
|
/>
|
|
</button>
|
|
<button
|
|
phx-click="delete"
|
|
phx-value-id={report.id}
|
|
data-confirm="Delete this report?"
|
|
title="Delete"
|
|
class="text-gray-400 hover:text-red-600 dark:hover:text-red-400"
|
|
>
|
|
<.icon name="hero-trash" class="w-4 h-4" />
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<% else %>
|
|
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-12 text-center">
|
|
<.icon
|
|
name="hero-document-chart-bar"
|
|
class="w-12 h-12 mx-auto text-gray-300 dark:text-gray-600"
|
|
/>
|
|
<h3 class="mt-4 text-sm font-semibold text-gray-900 dark:text-white">
|
|
{t("No scheduled reports")}
|
|
</h3>
|
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
|
{t("Create a report to start receiving automated updates via email.")}
|
|
</p>
|
|
<button
|
|
phx-click="show_form"
|
|
class="mt-4 inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors"
|
|
>
|
|
<.icon name="hero-plus" class="w-4 h-4" />
|
|
{t("Create First Report")}
|
|
</button>
|
|
</div>
|
|
<% end %>
|
|
</Layouts.authenticated>
|