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
|
||||
q =
|
||||
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)
|
||||
end
|
||||
|
|
|
@ -13,7 +13,19 @@ defmodule Chiya.Notes.Note do
|
|||
|
||||
@derive {
|
||||
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]}
|
||||
schema "notes" do
|
||||
|
|
|
@ -748,12 +748,17 @@ defmodule ChiyaWeb.CoreComponents do
|
|||
assigns = assign(assigns, form: Phoenix.Component.to_form(meta), meta: nil)
|
||||
|
||||
~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}>
|
||||
<.input field={i.field} label={i.label} type={i.type} phx-debounce={120} {i.rest} />
|
||||
</.filter_fields>
|
||||
|
||||
<.button class="button" name="reset">reset</.button>
|
||||
</.form>
|
||||
"""
|
||||
end
|
||||
|
|
|
@ -13,15 +13,19 @@
|
|||
|
||||
<section class="flex flex-row flex-wrap mt-6 -mb-6 gap-3">
|
||||
<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"
|
||||
phx-click="update-channel"
|
||||
phx-value-channelid={nil}
|
||||
>
|
||||
All <span class="text-gray-600 dark:text-gray-500">(<%= Enum.count(@notes) %>)</span>
|
||||
</a>
|
||||
<%= for channel <- @channels do %>
|
||||
<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"
|
||||
phx-click="update-channel"
|
||||
phx-value-channelid={channel.id}
|
||||
>
|
||||
<%= channel.name %>
|
||||
<span class="text-gray-600 dark:text-gray-500">(<%= Enum.count(channel.notes) %>)</span>
|
||||
|
|
|
@ -3,8 +3,16 @@ defmodule ChiyaWeb.NoteListLive do
|
|||
|
||||
@impl true
|
||||
def mount(_params, __session, socket) do
|
||||
channels = Chiya.Channels.list_channels() |> Chiya.Channels.preload_channel()
|
||||
{: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
|
||||
|
||||
@impl true
|
||||
|
@ -25,6 +33,16 @@ defmodule ChiyaWeb.NoteListLive do
|
|||
{:noreply, push_patch(socket, to: ~p"/admin/notes?#{params}")}
|
||||
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
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
|
@ -42,7 +60,18 @@ defmodule ChiyaWeb.NoteListLive do
|
|||
</.header>
|
||||
|
||||
<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 class="flex flex-col gap-3 mt-6">
|
||||
|
|
Loading…
Reference in a new issue