Add contact infinite pagination
This commit is contained in:
parent
35b9fab724
commit
e253076285
@ -17,8 +17,12 @@ defmodule SendIt.Marketing do
|
||||
[%Contact{}, ...]
|
||||
|
||||
"""
|
||||
def list_contacts do
|
||||
Repo.all(Contact)
|
||||
def list_contacts(opts \\ [offset: 0, limit: 20]) do
|
||||
Repo.all(
|
||||
from c in Contact,
|
||||
offset: ^opts[:offset],
|
||||
limit: ^opts[:limit]
|
||||
)
|
||||
end
|
||||
|
||||
def list_subscribed_contacts do
|
||||
|
||||
@ -436,6 +436,7 @@ defmodule SendItWeb.CoreComponents do
|
||||
end
|
||||
|
||||
slot :action, doc: "the slot for showing user actions in the last table column"
|
||||
attr :rest, :global, doc: "the arbitrary HTML attributes to add to a table"
|
||||
|
||||
def table(assigns) do
|
||||
assigns =
|
||||
@ -453,7 +454,7 @@ defmodule SendItWeb.CoreComponents do
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id={@id} phx-update={match?(%Phoenix.LiveView.LiveStream{}, @rows) && "stream"}>
|
||||
<tbody id={@id} phx-update={match?(%Phoenix.LiveView.LiveStream{}, @rows) && "stream"} {@rest}>
|
||||
<tr :for={row <- @rows} id={@row_id && @row_id.(row)}>
|
||||
<td
|
||||
:for={{col, i} <- Enum.with_index(@col)}
|
||||
|
||||
@ -6,7 +6,10 @@ defmodule SendItWeb.ContactLive.Index do
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, stream(socket, :contacts, Marketing.list_contacts())}
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(page: 1, per_page: 20)
|
||||
|> paginate_contacts(1)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
@ -38,4 +41,44 @@ defmodule SendItWeb.ContactLive.Index do
|
||||
|
||||
{:noreply, stream_delete(socket, :contacts, contact)}
|
||||
end
|
||||
|
||||
def handle_event("next-page", _, socket) do
|
||||
IO.puts("NEXT Pageee")
|
||||
{:noreply, paginate_contacts(socket, socket.assigns.page + 1)}
|
||||
end
|
||||
|
||||
def handle_event("prev-page", %{"_overran" => true}, socket) do
|
||||
{:noreply, paginate_contacts(socket, 1)}
|
||||
end
|
||||
|
||||
def handle_event("prev-page", _, socket) do
|
||||
if socket.assigns.page > 1 do
|
||||
{:noreply, paginate_contacts(socket, socket.assigns.page - 1)}
|
||||
else
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
defp paginate_contacts(socket, new_page) when new_page >= 1 do
|
||||
%{per_page: per_page, page: cur_page} = socket.assigns
|
||||
contacts = Marketing.list_contacts(offset: (new_page - 1) * per_page, limit: per_page)
|
||||
|
||||
{contacts, at, limit} =
|
||||
if new_page >= cur_page do
|
||||
{contacts, -1, per_page * 3 * -1}
|
||||
else
|
||||
{Enum.reverse(contacts), 0, per_page * 3}
|
||||
end
|
||||
|
||||
case contacts do
|
||||
[] ->
|
||||
assign(socket, end_of_timeline?: at == -1)
|
||||
|
||||
[_ | _] = contacts ->
|
||||
socket
|
||||
|> assign(end_of_timeline?: false)
|
||||
|> assign(:page, new_page)
|
||||
|> stream(:contacts, contacts, at: at, limit: limit)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -11,6 +11,9 @@
|
||||
id="contacts"
|
||||
rows={@streams.contacts}
|
||||
row_click={fn {_id, contact} -> JS.navigate(~p"/contacts/#{contact}") end}
|
||||
phx-viewport-top={@page > 1 && "prev-page"}
|
||||
phx-viewport-bottom={!@end_of_timeline? && "next-page"}
|
||||
phx-page-loading
|
||||
>
|
||||
<:col :let={{_id, contact}} label="Name"><%= contact.name %></:col>
|
||||
<:col :let={{_id, contact}} label="Email"><%= contact.email %></:col>
|
||||
@ -25,6 +28,8 @@
|
||||
</:action>
|
||||
</.table>
|
||||
|
||||
<h3 :if={@end_of_timeline?}>No more contacts!</h3>
|
||||
|
||||
<.modal :if={@live_action in [:new]} id="contact-modal" show on_cancel={JS.patch(~p"/contacts")}>
|
||||
<.live_component
|
||||
module={SendItWeb.ContactLive.FormComponent}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user