parent
ce437b023f
commit
6d5b29a230
@ -0,0 +1,125 @@
|
|||||||
|
defmodule DecentralisedBookIndexWeb.Components.MyComponents.Pagination do
|
||||||
|
use Phoenix.Component
|
||||||
|
use DecentralisedBookIndexWeb, :verified_routes
|
||||||
|
|
||||||
|
attr :endpoint, :string, required: true
|
||||||
|
attr :page, :map, required: true
|
||||||
|
attr :page_params, :list, required: true
|
||||||
|
attr :params, :list, required: true
|
||||||
|
|
||||||
|
def pagination(assigns) do
|
||||||
|
assigns = assign(assigns, :current_page_number, get_current_page(assigns.page))
|
||||||
|
|
||||||
|
~H"""
|
||||||
|
<nav aria-label="Page navigation example" class="flex justify-center">
|
||||||
|
<ul class="inline-flex -space-x-px text-base h-10 mx-auto">
|
||||||
|
<li class="pl-auto">
|
||||||
|
<.button_link
|
||||||
|
data-role="previous-page"
|
||||||
|
kind="primary"
|
||||||
|
inverse
|
||||||
|
patch={"#{@endpoint}?#{page_params_which(@page, @params, "prev")}"}
|
||||||
|
class="flex items-center justify-center px-4 h-10 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||||
|
disabled={!AshPhoenix.LiveView.prev_page?(@page)}
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</.button_link>
|
||||||
|
</li>
|
||||||
|
<%= for number <- get_page_numbers(@page) do %>
|
||||||
|
<%= if number == @current_page_number do %>
|
||||||
|
<li>
|
||||||
|
<a href={"#{@endpoint}?#{page_params_number(@page_params, @params, number)}"}
|
||||||
|
aria-current="page"
|
||||||
|
class="flex items-center justify-center px-4 h-10 text-blue-600 border border-gray-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white">{number}</a>
|
||||||
|
</li>
|
||||||
|
<% else %>
|
||||||
|
<li>
|
||||||
|
<a href={"#{@endpoint}?#{page_params_number(@page_params, @params, number)}"}
|
||||||
|
class="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">{number}</a>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<li>
|
||||||
|
<.button_link
|
||||||
|
data-role="next-page"
|
||||||
|
kind="primary"
|
||||||
|
inverse
|
||||||
|
patch={"#{@endpoint}?#{page_params_which(@page, @params, "next")}"}
|
||||||
|
class="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
|
||||||
|
disabled={!AshPhoenix.LiveView.next_page?(@page)}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</.button_link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
attr :kind, :string,
|
||||||
|
values: ~w(base primary error),
|
||||||
|
default: "base"
|
||||||
|
|
||||||
|
attr :inverse, :boolean, default: false
|
||||||
|
attr :class, :string, default: ""
|
||||||
|
attr :rest, :global, include: ~w(navigate disabled patch)
|
||||||
|
|
||||||
|
slot :inner_block
|
||||||
|
|
||||||
|
defp button_link(assigns) do
|
||||||
|
~H"""
|
||||||
|
<.link
|
||||||
|
class={[
|
||||||
|
@rest[:disabled] && "opacity-60 grayscale pointer-events-none",
|
||||||
|
@class
|
||||||
|
]}
|
||||||
|
{@rest}
|
||||||
|
>
|
||||||
|
{render_slot(@inner_block)}
|
||||||
|
</.link>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_page_numbers(pages) do
|
||||||
|
%{count: count, limit: limit} = pages
|
||||||
|
|
||||||
|
max_number =
|
||||||
|
count/limit
|
||||||
|
|> :math.ceil()
|
||||||
|
|> Kernel.trunc()
|
||||||
|
|
||||||
|
1..max_number
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_current_page(pages) do
|
||||||
|
%{offset: offset, limit: limit} = pages
|
||||||
|
|
||||||
|
Kernel.trunc(offset/limit) +1
|
||||||
|
end
|
||||||
|
|
||||||
|
def page_params_which(page, params, which) do
|
||||||
|
page_params =
|
||||||
|
case AshPhoenix.LiveView.page_link_params(page, which) do
|
||||||
|
:invalid -> []
|
||||||
|
list -> list
|
||||||
|
end
|
||||||
|
|
||||||
|
page_params
|
||||||
|
|> Enum.into(params, fn {k, v} -> {Atom.to_string(k), v} end)
|
||||||
|
|> to_uri_params()
|
||||||
|
end
|
||||||
|
|
||||||
|
def page_params_number(page_params, params, number) do
|
||||||
|
limit = Keyword.get(page_params, :limit)
|
||||||
|
offset = limit*(number-1)
|
||||||
|
|
||||||
|
params
|
||||||
|
|> Map.put("limit", limit)
|
||||||
|
|> Map.put("offset", offset)
|
||||||
|
|> to_uri_params()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp to_uri_params(params) do
|
||||||
|
URI.encode_query(params)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in new issue