mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
fix(ux): Align filters horizontally on md breakpoints and higher (#5265)
Fixes #5231 Fixes #5232 <img width="636" alt="Screenshot 2024-06-05 at 7 26 19 PM" src="https://github.com/firezone/firezone/assets/167144/8e40ba37-9757-4f83-98ad-24c61efbad36"> <img width="1792" alt="Screenshot 2024-06-05 at 7 26 11 PM" src="https://github.com/firezone/firezone/assets/167144/eca5084b-ce35-4df6-bb30-474811944ea2"> <img width="720" alt="Screenshot 2024-06-05 at 7 26 03 PM" src="https://github.com/firezone/firezone/assets/167144/c3eccdba-b3c0-467a-91c0-5197e2a74ed6"> <img width="1791" alt="Screenshot 2024-06-05 at 7 32 16 PM" src="https://github.com/firezone/firezone/assets/167144/64d417e3-cf74-4f20-9cf5-22b7c0cd620c"> <img width="748" alt="Screenshot 2024-06-05 at 7 32 07 PM" src="https://github.com/firezone/firezone/assets/167144/11cd2f3a-f8ee-4098-bad9-ab21fd6c000c"> <img width="1792" alt="Screenshot 2024-06-05 at 7 31 50 PM" src="https://github.com/firezone/firezone/assets/167144/c601eec9-956b-4229-a1c4-484c4bca5001"> <img width="1792" alt="Screenshot 2024-06-05 at 7 31 48 PM" src="https://github.com/firezone/firezone/assets/167144/2bd2c61a-e39b-4215-8e76-b7b3835dd5aa"> <img width="1792" alt="Screenshot 2024-06-05 at 7 31 43 PM" src="https://github.com/firezone/firezone/assets/167144/c06d431d-37c1-4ca1-8ab2-67a879cf609b">
This commit is contained in:
@@ -332,7 +332,7 @@ defmodule Web.CoreComponents do
|
||||
|
||||
def label(assigns) do
|
||||
~H"""
|
||||
<label for={@for} class={["block text-sm text-neutral-900", @class]}>
|
||||
<label for={@for} class={["block text-sm text-neutral-900 mb-2", @class]}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
</label>
|
||||
"""
|
||||
@@ -406,10 +406,10 @@ defmodule Web.CoreComponents do
|
||||
def list(assigns) do
|
||||
~H"""
|
||||
<div class="mt-14">
|
||||
<dl class="-my-4 divide-y divide-zinc-100">
|
||||
<dl class="-my-4 divide-y divide-neutral-100">
|
||||
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8">
|
||||
<dt class="w-1/4 flex-none text-zinc-500"><%= item.title %></dt>
|
||||
<dd class="text-zinc-700"><%= render_slot(item) %></dd>
|
||||
<dt class="w-1/4 flex-none text-neutral-500"><%= item.title %></dt>
|
||||
<dd class="text-neutral-700"><%= render_slot(item) %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@@ -32,9 +32,8 @@ defmodule Web.FormComponents do
|
||||
|
||||
attr :type, :string,
|
||||
default: "text",
|
||||
values:
|
||||
~w(checkbox color date datetime-local email file hidden month number password
|
||||
range radio readonly search group_select select tel text textarea taglist time url week)
|
||||
values: ~w(checkbox color date datetime-local email file hidden month number password
|
||||
range radio readonly search group_select select tel text textarea time url week)
|
||||
|
||||
attr :field, Phoenix.HTML.FormField,
|
||||
doc: "a form field struct retrieved from the form, for example: @form[:email]"
|
||||
@@ -116,7 +115,7 @@ defmodule Web.FormComponents do
|
||||
|
||||
~H"""
|
||||
<div phx-feedback-for={@name}>
|
||||
<label class="flex items-center gap-4 text-sm leading-6 text-zinc-600">
|
||||
<label class="flex items-center gap-4 text-sm leading-6 text-neutral-600">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={@id}
|
||||
@@ -143,7 +142,7 @@ defmodule Web.FormComponents do
|
||||
def input(%{type: "group_select"} = assigns) do
|
||||
~H"""
|
||||
<div phx-feedback-for={@name}>
|
||||
<.label for={@id}><%= @label %></.label>
|
||||
<.label :if={@label} for={@id}><%= @label %></.label>
|
||||
<input
|
||||
:if={not is_nil(@value) and not is_nil(@rest[:disabled])}
|
||||
type="hidden"
|
||||
@@ -221,7 +220,7 @@ defmodule Web.FormComponents do
|
||||
id={@id}
|
||||
name={@name}
|
||||
class={[
|
||||
"mt-2 block w-full rounded sm:text-sm sm:leading-6",
|
||||
"block w-full rounded sm:text-sm sm:leading-6",
|
||||
"bg-neutral-50",
|
||||
"border border-neutral-300 text-neutral-900 rounded",
|
||||
"phx-no-feedback:border-neutral-300",
|
||||
@@ -237,54 +236,6 @@ defmodule Web.FormComponents do
|
||||
"""
|
||||
end
|
||||
|
||||
def input(%{type: "taglist"} = assigns) do
|
||||
values =
|
||||
if is_nil(assigns.value),
|
||||
do: [],
|
||||
else: Enum.map(assigns.value, &Phoenix.HTML.Form.normalize_value("text", &1))
|
||||
|
||||
assigns = assign(assigns, :values, values)
|
||||
|
||||
~H"""
|
||||
<div phx-feedback-for={@name}>
|
||||
<.label for={@id}><%= @label %></.label>
|
||||
|
||||
<div :for={{value, index} <- Enum.with_index(@values)} class="flex mt-2">
|
||||
<input
|
||||
type="text"
|
||||
name={"#{@name}[]"}
|
||||
id={@id}
|
||||
value={value}
|
||||
class={[
|
||||
"bg-neutral-50 p-2.5 block w-full rounded border text-neutral-900 text-sm",
|
||||
"phx-no-feedback:border-neutral-300",
|
||||
"disabled:bg-neutral-50 disabled:text-neutral-500 disabled:border-neutral-200 disabled:shadow-none",
|
||||
"border-neutral-300",
|
||||
@errors != [] && "border-rose-400"
|
||||
]}
|
||||
{@rest}
|
||||
/>
|
||||
<.button
|
||||
type="button"
|
||||
phx-click={"delete:#{@name}"}
|
||||
phx-value-index={index}
|
||||
class="align-middle ml-2 inline-block whitespace-nowrap"
|
||||
>
|
||||
<.icon name="hero-minus" /> Delete
|
||||
</.button>
|
||||
</div>
|
||||
|
||||
<.button type="button" phx-click={"add:#{@name}"} class="mt-2">
|
||||
<.icon name="hero-plus" /> Add
|
||||
</.button>
|
||||
|
||||
<.error :for={msg <- @errors} inline={@inline_errors} data-validation-error-for={@name}>
|
||||
<%= msg %>
|
||||
</.error>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def input(%{type: "hidden"} = assigns) do
|
||||
~H"""
|
||||
<input
|
||||
|
||||
@@ -312,7 +312,7 @@ defmodule Web.NavigationComponents do
|
||||
<div class="mt-16">
|
||||
<.link
|
||||
navigate={@navigate}
|
||||
class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
|
||||
class="text-sm font-semibold leading-6 text-neutral-900 hover:text-neutral-700"
|
||||
>
|
||||
<.icon name="hero-arrow-left-solid" class="h-3 w-3" />
|
||||
<%= render_slot(@inner_block) %>
|
||||
|
||||
@@ -111,8 +111,7 @@ defmodule Web.Groups.Show do
|
||||
}
|
||||
kind={:info}
|
||||
>
|
||||
<p>This group is managed by Firezone and cannot be edited.</p>
|
||||
<p>It will contain all actors with at least one authentication identity.</p>
|
||||
<p>This Group contains all Users and cannot be edited.</p>
|
||||
</.flash>
|
||||
<.flash :if={Actors.group_synced?(@group)} kind={:info}>
|
||||
This group is synced from an external source and cannot be edited.
|
||||
|
||||
@@ -40,7 +40,7 @@ defmodule Web.Resources.New do
|
||||
<label for="resource_type" class="block mb-2 text-sm text-neutral-900">
|
||||
Type
|
||||
</label>
|
||||
<div class="flex text-sm leading-6 text-zinc-600">
|
||||
<div class="flex text-sm leading-6 text-neutral-600">
|
||||
<div class="flex items-center me-4">
|
||||
<.input
|
||||
id="resource-type--dns"
|
||||
|
||||
@@ -89,30 +89,6 @@ defmodule Web.LiveTable do
|
||||
Map.take(filter.params, keys) != %{}
|
||||
end
|
||||
|
||||
defp resource_filter(assigns) do
|
||||
~H"""
|
||||
<.form
|
||||
:if={@filters != []}
|
||||
id={"#{@live_table_id}-filters"}
|
||||
for={@form}
|
||||
phx-change="filter"
|
||||
phx-debounce="100"
|
||||
onkeydown="return event.key != 'Enter';"
|
||||
>
|
||||
<.input type="hidden" name="table_id" value={@live_table_id} />
|
||||
|
||||
<div
|
||||
:for={filter <- @filters}
|
||||
class="flex flex-col md:flex-row items-center justify-between space-y-3 md:space-y-0 md:space-x-4 pb-4"
|
||||
>
|
||||
<div class="w-full xl:w-1/2">
|
||||
<.filter live_table_id={@live_table_id} form={@form} filter={filter} />
|
||||
</div>
|
||||
</div>
|
||||
</.form>
|
||||
"""
|
||||
end
|
||||
|
||||
def datetime_input(assigns) do
|
||||
~H"""
|
||||
<div phx-feedback-for={@field.name} class={["flex items-center"]}>
|
||||
@@ -168,6 +144,30 @@ defmodule Web.LiveTable do
|
||||
defp normalize_value(_, nil),
|
||||
do: nil
|
||||
|
||||
defp resource_filter(assigns) do
|
||||
~H"""
|
||||
<.form
|
||||
:if={@filters != []}
|
||||
id={"#{@live_table_id}-filters"}
|
||||
for={@form}
|
||||
phx-change="filter"
|
||||
phx-debounce="100"
|
||||
onkeydown="return event.key != 'Enter';"
|
||||
>
|
||||
<.input type="hidden" name="table_id" value={@live_table_id} />
|
||||
|
||||
<div class="mb-2 space-y-2 md:space-y-0 md:gap-2 md:flex md:justify-end">
|
||||
<.filter
|
||||
:for={filter <- @filters}
|
||||
live_table_id={@live_table_id}
|
||||
form={@form}
|
||||
filter={filter}
|
||||
/>
|
||||
</div>
|
||||
</.form>
|
||||
"""
|
||||
end
|
||||
|
||||
defp filter(%{filter: %{type: {:range, :datetime}}} = assigns) do
|
||||
~H"""
|
||||
<div class="flex items-center">
|
||||
@@ -190,137 +190,147 @@ defmodule Web.LiveTable do
|
||||
|
||||
defp filter(%{filter: %{type: {:string, :websearch}}} = assigns) do
|
||||
~H"""
|
||||
<div class={["relative w-full"]} phx-feedback-for={@form[@filter.name].name}>
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<.icon name="hero-magnifying-glass" class="w-5 h-5 text-neutral-500" />
|
||||
</div>
|
||||
<div class="flex items-center order-last">
|
||||
<div class="relative w-full" phx-feedback-for={@form[@filter.name].name}>
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<.icon name="hero-magnifying-glass" class="w-5 h-5 text-neutral-500" />
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
name={@form[@filter.name].name}
|
||||
id={@form[@filter.name].id}
|
||||
value={Phoenix.HTML.Form.normalize_value("text", @form[@filter.name].value)}
|
||||
placeholder={"Search by " <> @filter.title}
|
||||
class={[
|
||||
"bg-neutral-50 border border-neutral-300 text-neutral-900 text-sm rounded",
|
||||
"block w-full pl-10 p-2",
|
||||
"phx-no-feedback:border-neutral-300",
|
||||
"disabled:bg-neutral-50 disabled:text-neutral-500 disabled:border-neutral-200 disabled:shadow-none",
|
||||
"focus:outline-none focus:border-1 focus:ring-0",
|
||||
"border-neutral-300",
|
||||
@form[@filter.name].errors != [] && "border-rose-400"
|
||||
]}
|
||||
/>
|
||||
<.error
|
||||
:for={msg <- @form[@filter.name].errors}
|
||||
data-validation-error-for={@form[@filter.name].name}
|
||||
>
|
||||
<%= msg %>
|
||||
</.error>
|
||||
<input
|
||||
type="text"
|
||||
name={@form[@filter.name].name}
|
||||
id={@form[@filter.name].id}
|
||||
value={Phoenix.HTML.Form.normalize_value("text", @form[@filter.name].value)}
|
||||
placeholder={"Search by " <> @filter.title}
|
||||
class={[
|
||||
"bg-neutral-50 border border-neutral-300 text-neutral-900 text-sm rounded",
|
||||
"block w-full pl-10 p-2",
|
||||
"phx-no-feedback:border-neutral-300",
|
||||
"disabled:bg-neutral-50 disabled:text-neutral-500 disabled:border-neutral-200 disabled:shadow-none",
|
||||
"focus:outline-none focus:border-1 focus:ring-0",
|
||||
"border-neutral-300",
|
||||
@form[@filter.name].errors != [] && "border-rose-400"
|
||||
]}
|
||||
/>
|
||||
<.error
|
||||
:for={msg <- @form[@filter.name].errors}
|
||||
data-validation-error-for={@form[@filter.name].name}
|
||||
>
|
||||
<%= msg %>
|
||||
</.error>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp filter(%{filter: %{type: {:string, :email}}} = assigns) do
|
||||
~H"""
|
||||
<div class={["relative w-full"]} phx-feedback-for={@form[@filter.name].name}>
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<.icon name="hero-magnifying-glass" class="w-5 h-5 text-neutral-500" />
|
||||
</div>
|
||||
<div class="flex items-center order-last">
|
||||
<div class="relative w-full" phx-feedback-for={@form[@filter.name].name}>
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<.icon name="hero-magnifying-glass" class="w-5 h-5 text-neutral-500" />
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
name={@form[@filter.name].name}
|
||||
id={@form[@filter.name].id}
|
||||
value={Phoenix.HTML.Form.normalize_value("text", @form[@filter.name].value)}
|
||||
placeholder={"Search by " <> @filter.title}
|
||||
class={[
|
||||
"bg-neutral-50 border border-neutral-300 text-neutral-900 text-sm rounded",
|
||||
"block w-full pl-10 p-2",
|
||||
"phx-no-feedback:border-neutral-300",
|
||||
"disabled:bg-neutral-50 disabled:text-neutral-500 disabled:border-neutral-200 disabled:shadow-none",
|
||||
"focus:outline-none focus:border-1 focus:ring-0",
|
||||
"border-neutral-300",
|
||||
@form[@filter.name].errors != [] && "border-rose-400"
|
||||
]}
|
||||
/>
|
||||
<.error
|
||||
:for={msg <- @form[@filter.name].errors}
|
||||
data-validation-error-for={@form[@filter.name].name}
|
||||
>
|
||||
<%= msg %>
|
||||
</.error>
|
||||
<input
|
||||
type="text"
|
||||
name={@form[@filter.name].name}
|
||||
id={@form[@filter.name].id}
|
||||
value={Phoenix.HTML.Form.normalize_value("text", @form[@filter.name].value)}
|
||||
placeholder={"Search by " <> @filter.title}
|
||||
class={[
|
||||
"bg-neutral-50 border border-neutral-300 text-neutral-900 text-sm rounded",
|
||||
"block w-full pl-10 p-2",
|
||||
"phx-no-feedback:border-neutral-300",
|
||||
"disabled:bg-neutral-50 disabled:text-neutral-500 disabled:border-neutral-200 disabled:shadow-none",
|
||||
"focus:outline-none focus:border-1 focus:ring-0",
|
||||
"border-neutral-300",
|
||||
@form[@filter.name].errors != [] && "border-rose-400"
|
||||
]}
|
||||
/>
|
||||
<.error
|
||||
:for={msg <- @form[@filter.name].errors}
|
||||
data-validation-error-for={@form[@filter.name].name}
|
||||
>
|
||||
<%= msg %>
|
||||
</.error>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp filter(%{filter: %{type: {:string, :uuid}}} = assigns) do
|
||||
~H"""
|
||||
<.input
|
||||
type="group_select"
|
||||
field={@form[@filter.name]}
|
||||
options={
|
||||
[
|
||||
{nil, [{"For any " <> @filter.title, nil}]}
|
||||
] ++ @filter.values
|
||||
}
|
||||
/>
|
||||
<div class="flex items-center order-4">
|
||||
<div class="w-full">
|
||||
<.input
|
||||
type="group_select"
|
||||
field={@form[@filter.name]}
|
||||
options={
|
||||
[
|
||||
{nil, [{"For any " <> @filter.title, nil}]}
|
||||
] ++ @filter.values
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp filter(%{filter: %{type: :string, values: values}} = assigns)
|
||||
when 0 < length(values) and length(values) < 5 do
|
||||
~H"""
|
||||
<div class="inline-flex rounded-md shadow-sm" role="group">
|
||||
<.intersperse_blocks>
|
||||
<:item>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
"border-y border-l rounded-l",
|
||||
is_nil(@form[@filter.name].value) && "bg-neutral-100"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
type="radio"
|
||||
field={@form[@filter.name]}
|
||||
name={"_reset:" <> @form[@filter.name].name}
|
||||
value="true"
|
||||
checked={is_nil(@form[@filter.name].value)}
|
||||
class="hidden"
|
||||
/> All
|
||||
</label>
|
||||
</:item>
|
||||
<div class="flex items-center order-first">
|
||||
<div class="flex rounded" role="group">
|
||||
<.intersperse_blocks>
|
||||
<:item>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
"border-y border-l rounded-l",
|
||||
is_nil(@form[@filter.name].value) && "bg-neutral-100"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
type="radio"
|
||||
field={@form[@filter.name]}
|
||||
name={"_reset:" <> @form[@filter.name].name}
|
||||
value="true"
|
||||
checked={is_nil(@form[@filter.name].value)}
|
||||
class="hidden"
|
||||
/> All
|
||||
</label>
|
||||
</:item>
|
||||
|
||||
<:item :let={position} :for={{label, value} <- @filter.values}>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
@form[@filter.name].value == value && "bg-neutral-100",
|
||||
position == :first && "border-y border-l rounded-l",
|
||||
position == :last && "border-y border-r rounded-r",
|
||||
position != :first && position != :last && "border"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
type="radio"
|
||||
field={@form[@filter.name]}
|
||||
value={value}
|
||||
checked={@form[@filter.name].value == value}
|
||||
class="hidden"
|
||||
/>
|
||||
<%= label %>
|
||||
</label>
|
||||
</:item>
|
||||
</.intersperse_blocks>
|
||||
<:item :let={position} :for={{label, value} <- @filter.values}>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
@form[@filter.name].value == value && "bg-neutral-100",
|
||||
position == :first && "border-y border-l rounded-l",
|
||||
position == :last && "border-y border-r rounded-r",
|
||||
position != :first && position != :last && "border"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
type="radio"
|
||||
field={@form[@filter.name]}
|
||||
value={value}
|
||||
checked={@form[@filter.name].value == value}
|
||||
class="hidden"
|
||||
/>
|
||||
<%= label %>
|
||||
</label>
|
||||
</:item>
|
||||
</.intersperse_blocks>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
@@ -328,71 +338,77 @@ defmodule Web.LiveTable do
|
||||
defp filter(%{filter: %{type: {:list, :string}, values: values}} = assigns)
|
||||
when 0 < length(values) and length(values) < 5 do
|
||||
~H"""
|
||||
<div class="inline-flex rounded-md shadow-sm" role="group">
|
||||
<.intersperse_blocks>
|
||||
<:item>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
"border-y border-l rounded-l",
|
||||
is_nil(@form[@filter.name].value) && "bg-neutral-100"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
type="checkbox"
|
||||
field={@form[@filter.name]}
|
||||
name={"_reset:" <> @form[@filter.name].name}
|
||||
value={true}
|
||||
checked={is_nil(@form[@filter.name].value)}
|
||||
class="hidden"
|
||||
/> All
|
||||
</label>
|
||||
</:item>
|
||||
<div class="flex items-center order-first">
|
||||
<div class="flex rounded w-full" role="group">
|
||||
<.intersperse_blocks>
|
||||
<:item>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
"border-y border-l rounded-l",
|
||||
is_nil(@form[@filter.name].value) && "bg-neutral-100"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-__all__"}
|
||||
type="checkbox"
|
||||
field={@form[@filter.name]}
|
||||
name={"_reset:" <> @form[@filter.name].name}
|
||||
value={true}
|
||||
checked={is_nil(@form[@filter.name].value)}
|
||||
class="hidden"
|
||||
/> All
|
||||
</label>
|
||||
</:item>
|
||||
|
||||
<:item :let={position} :for={{label, value} <- @filter.values}>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
@form[@filter.name].value && value in @form[@filter.name].value && "bg-neutral-100",
|
||||
position == :first && "border-y border-l rounded-l",
|
||||
position == :last && "border-y border-r rounded-r",
|
||||
position != :first && position != :last && "border"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
type="checkbox"
|
||||
field={@form[@filter.name]}
|
||||
name={@form[@filter.name].name <> "[]"}
|
||||
value={value}
|
||||
checked={@form[@filter.name].value && value in @form[@filter.name].value}
|
||||
class="hidden"
|
||||
/>
|
||||
<%= label %>
|
||||
</label>
|
||||
</:item>
|
||||
</.intersperse_blocks>
|
||||
<:item :let={position} :for={{label, value} <- @filter.values}>
|
||||
<label
|
||||
for={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
class={[
|
||||
"px-4 py-2 text-sm border-neutral-200 text-neutral-900",
|
||||
"hover:bg-neutral-200 hover:text-neutral-700",
|
||||
"cursor-pointer",
|
||||
@form[@filter.name].value && value in @form[@filter.name].value && "bg-neutral-100",
|
||||
position == :first && "border-y border-l rounded-l",
|
||||
position == :last && "border-y border-r rounded-r",
|
||||
position != :first && position != :last && "border"
|
||||
]}
|
||||
>
|
||||
<.input
|
||||
id={"#{@live_table_id}-#{@filter.name}-#{value}"}
|
||||
type="checkbox"
|
||||
field={@form[@filter.name]}
|
||||
name={@form[@filter.name].name <> "[]"}
|
||||
value={value}
|
||||
checked={@form[@filter.name].value && value in @form[@filter.name].value}
|
||||
class="hidden"
|
||||
/>
|
||||
<%= label %>
|
||||
</label>
|
||||
</:item>
|
||||
</.intersperse_blocks>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp filter(%{filter: %{type: :string, values: values}} = assigns) when length(values) > 0 do
|
||||
~H"""
|
||||
<.input
|
||||
type="group_select"
|
||||
field={@form[@filter.name]}
|
||||
options={[
|
||||
{nil, [{"For any " <> @filter.title, nil}]},
|
||||
{@filter.title, @filter.values}
|
||||
]}
|
||||
/>
|
||||
<div class="flex items-center order-4">
|
||||
<div class="w-full">
|
||||
<.input
|
||||
type="group_select"
|
||||
field={@form[@filter.name]}
|
||||
options={[
|
||||
{nil, [{"For any " <> @filter.title, nil}]},
|
||||
{@filter.title, @filter.values}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user