fix: add unique form IDs for LiveView 1.2 compatibility, add type attr to button component

This commit is contained in:
Graham McIntire 2026-07-08 11:10:41 -05:00
parent 749932082f
commit ca992f1fd1
16 changed files with 72 additions and 20 deletions

View file

@ -132,7 +132,7 @@ defmodule ToweropsWeb.CoreComponents do
<.button phx-click="go" variant="primary">Send!</.button>
<.button navigate={~p"/"}>Home</.button>
"""
attr :rest, :global, include: ~w(href navigate patch method download name value disabled)
attr :rest, :global, include: ~w(href navigate patch method download name value disabled type)
attr :class, :any
attr :variant, :string, values: ~w(primary secondary danger ghost)
attr :size, :string, default: "md", values: ~w(sm md lg)

View file

@ -19,7 +19,7 @@
<%!-- Search Bar --%>
<div class="mt-6">
<form phx-change="search" phx-submit="search" class="relative">
<form id="activity-search-form" phx-change="search" phx-submit="search" class="relative">
<div class="relative">
<.icon
name="hero-magnifying-glass"

View file

@ -198,6 +198,7 @@
</h3>
<.form
id="global-pricing-form"
for={@global_form}
phx-change="validate_global_pricing"
phx-submit="save_global_pricing"

View file

@ -59,6 +59,7 @@
<%= if @show_whitelist_form do %>
<div class="bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 p-6">
<.form
id="whitelist-form"
for={@whitelist_form}
phx-submit="add_whitelist"
class="space-y-4"

View file

@ -165,7 +165,7 @@
<div class="sticky top-0 z-10 bg-white dark:bg-gray-900 pb-3 -mx-4 px-4 sm:-mx-6 sm:px-6 lg:-ml-4 lg:-mr-8 lg:pl-4 lg:pr-8 border-b border-gray-100 dark:border-white/5">
<div class="flex items-center gap-3 pt-2">
<%!-- Search --%>
<form phx-change="search" class="flex-1 max-w-sm">
<form id="device-search-form" phx-change="search" class="flex-1 max-w-sm">
<div class="relative">
<.icon
name="hero-magnifying-glass"

View file

@ -15,7 +15,13 @@
</div>
<div class="max-w-2xl">
<.form for={@form} phx-change="validate" phx-submit="save" class="space-y-6">
<.form
id="escalation-policy-form"
for={@form}
phx-change="validate"
phx-submit="save"
class="space-y-6"
>
<div>
<.input field={@form[:name]} type="text" label={t("Name")} required />
</div>

View file

@ -149,7 +149,11 @@
<% end %>
<%!-- Add target form --%>
<form phx-submit="add_target" class="flex items-center gap-2">
<form
id={"add-target-form-#{rule.id}"}
phx-submit="add_target"
class="flex items-center gap-2"
>
<input type="hidden" name="rule_id" value={rule.id} />
<select
name="target_type"
@ -192,7 +196,7 @@
<%!-- Add Level button + form --%>
<%= if @show_add_rule do %>
<div class="rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-900/10 p-4">
<form phx-submit="save_rule">
<form id="save-rule-form" phx-submit="save_rule">
<div class="flex items-end gap-4 mb-4">
<div class="flex-1">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">

View file

@ -66,7 +66,7 @@
{t("Set organization-wide SNMP defaults. Can be overridden per-site or per-device.")}
</p>
<.form for={@form} phx-change="validate_snmp" phx-submit="save_snmp">
<.form id="snmp-form" for={@form} phx-change="validate_snmp" phx-submit="save_snmp">
<div class="space-y-4">
<.input
field={@form[:snmp_version]}
@ -141,7 +141,7 @@
{t("Sites represent physical locations — tower sites, POPs, data centers, etc.")}
</p>
<.form for={@site_form} phx-change="validate_site" phx-submit="save_site">
<.form id="site-form" for={@site_form} phx-change="validate_site" phx-submit="save_site">
<div class="space-y-4">
<.input
field={@site_form[:name]}
@ -229,6 +229,7 @@
</div>
<.form
id="integration-form"
for={@integration_form}
phx-change="validate_integration"
phx-submit="save_integration"

View file

@ -221,7 +221,10 @@
<%= cond do %>
<% @open_create_for == entry.device.id -> %>
<div class="flex items-center justify-end gap-2">
<form phx-change="select_manufacturer">
<form
id={"select-manufacturer-form-#{entry.device.id}"}
phx-change="select_manufacturer"
>
<select
name="manufacturer_id"
class="rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 dark:border-white/10 dark:bg-gray-800 dark:text-gray-300"
@ -239,6 +242,7 @@
</form>
<%= if @selected_manufacturer do %>
<form
id={"create-gaiia-item-form-#{entry.device.id}"}
phx-submit="create_gaiia_item"
class="flex items-center gap-2"
>
@ -266,7 +270,11 @@
</div>
<% @open_link_for == entry.device.id -> %>
<div class="flex items-center justify-end gap-2">
<form phx-change="search_gaiia_items" class="flex items-center gap-2">
<form
id={"search-gaiia-items-form-#{entry.device.id}"}
phx-change="search_gaiia_items"
class="flex items-center gap-2"
>
<input type="hidden" name="device_id" value={entry.device.id} />
<input
type="text"

View file

@ -948,7 +948,11 @@
<td class="whitespace-nowrap px-4 py-3 text-right text-sm">
<%= if member.role != :owner do %>
<div class="flex items-center justify-end gap-3">
<form phx-change="change_role" phx-value-user-id={member.user_id}>
<form
id={"change-role-form-#{member.user_id}"}
phx-change="change_role"
phx-value-user-id={member.user_id}
>
<select
name="role"
class="rounded-md border-gray-300 py-1 pl-2 pr-8 text-xs dark:border-white/10 dark:bg-white/5 dark:text-white"

View file

@ -39,7 +39,7 @@
</button>
</div>
<.form for={@form} phx-submit="save" class="space-y-4">
<.form id="report-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">

View file

@ -15,7 +15,13 @@
</div>
<div class="max-w-2xl">
<.form for={@form} phx-change="validate" phx-submit="save" class="space-y-6">
<.form
id="schedule-form"
for={@form}
phx-change="validate"
phx-submit="save"
class="space-y-6"
>
<div>
<.input field={@form[:name]} type="text" label={t("Name")} required />
</div>

View file

@ -104,7 +104,7 @@
<% end %>
<% else %>
<%!-- Search input --%>
<form phx-change="search" phx-submit="search" class="mb-4">
<form id="schedule-search-form" phx-change="search" phx-submit="search" class="mb-4">
<div class="relative max-w-md">
<span class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2.5">
<.icon name="hero-magnifying-glass" class="h-4 w-4 text-gray-400" />
@ -147,7 +147,7 @@
{window_label(@start_date, @range_days)}
</span>
</div>
<form phx-change="set_range" class="inline-flex">
<form id="range-form" phx-change="set_range" class="inline-flex">
<select
name="range"
class="rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-white text-sm py-1.5"

View file

@ -236,7 +236,12 @@
<%= if @show_add_layer do %>
<div class="mb-4 rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-900/10 p-4">
<.form for={@layer_form} phx-change="validate_layer" phx-submit="save_layer">
<.form
id="layer-form"
for={@layer_form}
phx-change="validate_layer"
phx-submit="save_layer"
>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-4">
<.input
field={@layer_form[:name]}
@ -457,6 +462,7 @@
{t("Restrict on-call shifts")}
</p>
<form
id={"layer-restriction-form-#{layer.id}"}
phx-change="set_layer_restriction"
phx-submit="set_layer_restriction"
class="space-y-2"
@ -541,7 +547,12 @@
<%= if @show_add_override do %>
<div class="mb-4 rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-900/10 p-4">
<.form for={@override_form} phx-change="validate_override" phx-submit="save_override">
<.form
id="override-form"
for={@override_form}
phx-change="validate_override"
phx-submit="save_override"
>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-4">
<.input
field={@override_form[:user_id]}

View file

@ -25,7 +25,12 @@
<div class="p-4 sm:p-6">
<div class="flex items-center gap-3">
<.icon name="hero-magnifying-glass" class="h-6 w-6 text-gray-400 flex-shrink-0" />
<form phx-change="search" phx-submit="search" class="flex-1 flex gap-2">
<form
id="trace-search-form"
phx-change="search"
phx-submit="search"
class="flex-1 flex gap-2"
>
<input
type="text"
name="query"

View file

@ -1625,7 +1625,7 @@
</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-gray-800/95 sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
<.form for={%{}} as={:device} phx-submit="create_device">
<.form id="create-device-form" for={%{}} as={:device} phx-submit="create_device">
<div>
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-indigo-100 dark:bg-indigo-900">
<.icon
@ -1756,7 +1756,12 @@
<p class="mb-2 text-sm font-medium text-gray-900 dark:text-white">
{t("Enter the 6-digit code from your app to verify")}
</p>
<.form for={%{}} as={:verification} phx-submit="verify_new_device">
<.form
id="verify-device-form"
for={%{}}
as={:verification}
phx-submit="verify_new_device"
>
<div class="flex justify-center gap-3">
<input
type="text"