filter form #319
5 changed files with 60 additions and 9 deletions
|
@ -42,7 +42,8 @@ defmodule Chiya.Notes do
|
||||||
def list_admin_notes(params) do
|
def list_admin_notes(params) do
|
||||||
q =
|
q =
|
||||||
Note
|
Note
|
||||||
|> order_by([n], desc: n.updated_at, desc: n.published_at)
|
|> join(:inner, [n], c in assoc(n, :channels), as: :channels)
|
||||||
|
|> order_by([n, c], desc: n.updated_at, desc: n.published_at)
|
||||||
|
|
||||||
Chiya.Flop.validate_and_run(q, params, for: Chiya.Notes.Note)
|
Chiya.Flop.validate_and_run(q, params, for: Chiya.Notes.Note)
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,19 @@ defmodule Chiya.Notes.Note do
|
||||||
|
|
||||||
@derive {
|
@derive {
|
||||||
Flop.Schema,
|
Flop.Schema,
|
||||||
filterable: [:name, :kind], sortable: [:name], default_limit: 10, max_limit: 100
|
filterable: [:name, :channels],
|
||||||
|
sortable: [:name],
|
||||||
|
default_limit: 10,
|
||||||
|
max_limit: 100,
|
||||||
|
adapter_opts: [
|
||||||
|
join_fields: [
|
||||||
|
channels: [
|
||||||
|
binding: :channels,
|
||||||
|
field: :name,
|
||||||
|
ecto_type: :string
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@derive {Jason.Encoder, only: [:id, :name, :content, :slug, :channels, :tags]}
|
@derive {Jason.Encoder, only: [:id, :name, :content, :slug, :channels, :tags]}
|
||||||
schema "notes" do
|
schema "notes" do
|
||||||
|
|
|
@ -748,12 +748,17 @@ defmodule ChiyaWeb.CoreComponents do
|
||||||
assigns = assign(assigns, form: Phoenix.Component.to_form(meta), meta: nil)
|
assigns = assign(assigns, form: Phoenix.Component.to_form(meta), meta: nil)
|
||||||
|
|
||||||
~H"""
|
~H"""
|
||||||
<.form for={@form} id={@id} phx-target={@target} phx-change={@on_change} phx-submit={@on_change}>
|
<.form
|
||||||
|
for={@form}
|
||||||
|
id={@id}
|
||||||
|
class="stack"
|
||||||
|
phx-target={@target}
|
||||||
|
phx-change={@on_change}
|
||||||
|
phx-submit={@on_change}
|
||||||
|
>
|
||||||
<.filter_fields :let={i} form={@form} fields={@fields}>
|
<.filter_fields :let={i} form={@form} fields={@fields}>
|
||||||
<.input field={i.field} label={i.label} type={i.type} phx-debounce={120} {i.rest} />
|
<.input field={i.field} label={i.label} type={i.type} phx-debounce={120} {i.rest} />
|
||||||
</.filter_fields>
|
</.filter_fields>
|
||||||
|
|
||||||
<.button class="button" name="reset">reset</.button>
|
|
||||||
</.form>
|
</.form>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,15 +13,19 @@
|
||||||
|
|
||||||
<section class="flex flex-row flex-wrap mt-6 -mb-6 gap-3">
|
<section class="flex flex-row flex-wrap mt-6 -mb-6 gap-3">
|
||||||
<a
|
<a
|
||||||
href={~p"/admin/notes"}
|
href="#"
|
||||||
class="text-sm dark:text-gray-300 rounded-full bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm transition"
|
class="text-sm dark:text-gray-300 rounded-full bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm transition"
|
||||||
|
phx-click="update-channel"
|
||||||
|
phx-value-channelid={nil}
|
||||||
>
|
>
|
||||||
All <span class="text-gray-600 dark:text-gray-500">(<%= Enum.count(@notes) %>)</span>
|
All <span class="text-gray-600 dark:text-gray-500">(<%= Enum.count(@notes) %>)</span>
|
||||||
</a>
|
</a>
|
||||||
<%= for channel <- @channels do %>
|
<%= for channel <- @channels do %>
|
||||||
<a
|
<a
|
||||||
href={~p"/admin/notes?channel=#{channel.slug}"}
|
href="#"
|
||||||
class="text-sm dark:text-gray-300 rounded-full bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm transition"
|
class="text-sm dark:text-gray-300 rounded-full bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 px-4 py-2 border border-gray-300 dark:border-gray-600 shadow-sm transition"
|
||||||
|
phx-click="update-channel"
|
||||||
|
phx-value-channelid={channel.id}
|
||||||
>
|
>
|
||||||
<%= channel.name %>
|
<%= channel.name %>
|
||||||
<span class="text-gray-600 dark:text-gray-500">(<%= Enum.count(channel.notes) %>)</span>
|
<span class="text-gray-600 dark:text-gray-500">(<%= Enum.count(channel.notes) %>)</span>
|
||||||
|
|
|
@ -3,8 +3,16 @@ defmodule ChiyaWeb.NoteListLive do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, __session, socket) do
|
def mount(_params, __session, socket) do
|
||||||
|
channels = Chiya.Channels.list_channels() |> Chiya.Channels.preload_channel()
|
||||||
{:ok, {notes, meta}} = Chiya.Notes.list_admin_notes(%{})
|
{:ok, {notes, meta}} = Chiya.Notes.list_admin_notes(%{})
|
||||||
{:ok, socket |> assign(%{notes: notes, meta: meta})}
|
|
||||||
|
{:ok,
|
||||||
|
socket
|
||||||
|
|> assign(%{
|
||||||
|
channels: channels,
|
||||||
|
notes: notes,
|
||||||
|
meta: meta
|
||||||
|
})}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -25,6 +33,16 @@ defmodule ChiyaWeb.NoteListLive do
|
||||||
{:noreply, push_patch(socket, to: ~p"/admin/notes?#{params}")}
|
{:noreply, push_patch(socket, to: ~p"/admin/notes?#{params}")}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp channel_list(assigns) do
|
||||||
|
channels =
|
||||||
|
assigns.channels
|
||||||
|
|> Enum.map(fn c ->
|
||||||
|
{"#{c.name} (#{Enum.count(c.notes)})", c.name}
|
||||||
|
end)
|
||||||
|
|
||||||
|
[{"All", nil}] ++ channels
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
@ -42,7 +60,18 @@ defmodule ChiyaWeb.NoteListLive do
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<.filter_form fields={[name: [op: :ilike_and]]} meta={@meta} id="user-filter-form" />
|
<.filter_form
|
||||||
|
fields={[
|
||||||
|
name: [op: :ilike_and],
|
||||||
|
channels: [
|
||||||
|
op: :ilike_and,
|
||||||
|
type: "select",
|
||||||
|
options: channel_list(assigns)
|
||||||
|
]
|
||||||
|
]}
|
||||||
|
meta={@meta}
|
||||||
|
id="user-filter-form"
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="flex flex-col gap-3 mt-6">
|
<section class="flex flex-col gap-3 mt-6">
|
||||||
|
|
Loading…
Reference in a new issue