diff --git a/lib/kmxgit/index_params.ex b/lib/kmxgit/index_params.ex
index 1f8f7ad..da5c51c 100644
--- a/lib/kmxgit/index_params.ex
+++ b/lib/kmxgit/index_params.ex
@@ -1,5 +1,5 @@
defmodule Kmxgit.IndexParams do
- defstruct column: "id", reverse: false, search: nil
+ defstruct column: "id", page: 1, per: 4, reverse: false, search: nil
end
diff --git a/lib/kmxgit/pagination.ex b/lib/kmxgit/pagination.ex
new file mode 100644
index 0000000..84422fb
--- /dev/null
+++ b/lib/kmxgit/pagination.ex
@@ -0,0 +1,41 @@
+defmodule Kmxgit.Pagination do
+ import Ecto.Query
+
+ alias Kmxgit.IndexParams
+ alias Kmxgit.Repo
+
+ def query(query, %IndexParams{page: page, per: per}) do
+ query
+ |> limit(^per + 1)
+ |> offset(^(per * (page - 1)))
+ end
+
+ def page(query, params = %IndexParams{page: page, per: per}, preload: preload) do
+ result = query
+ |> query(params)
+ |> preload(^preload)
+ |> Repo.all()
+ first_page = if page > 2, do: 1
+ prev_page = if page > 1, do: page - 1
+ {next_page, result} = if length(result) > per do
+ {page + 1, Enum.slice(result, 0..-2)}
+ else
+ {nil, result}
+ end
+ count = Repo.one(from(t in subquery(query), select: count("*")))
+ count_pages = Float.ceil(count / per) |> trunc()
+ last_page = if (page < count_pages - 1), do: count_pages
+ first = (page - 1) * per + 1
+ %{count: count,
+ count_pages: count_pages,
+ first: first,
+ first_page: first_page,
+ last: first + length(result) - 1,
+ last_page: last_page,
+ next_page: next_page,
+ page: page,
+ per: per,
+ prev_page: prev_page,
+ result: result}
+ end
+end
diff --git a/lib/kmxgit/repository_manager.ex b/lib/kmxgit/repository_manager.ex
index fb9742c..eaef52e 100644
--- a/lib/kmxgit/repository_manager.ex
+++ b/lib/kmxgit/repository_manager.ex
@@ -4,6 +4,7 @@ defmodule Kmxgit.RepositoryManager do
alias Kmxgit.IndexParams
alias Kmxgit.OrganisationManager.Organisation
+ alias Kmxgit.Pagination
alias Kmxgit.Repo
alias Kmxgit.RepositoryManager.Repository
alias Kmxgit.SlugManager
@@ -19,12 +20,11 @@ defmodule Kmxgit.RepositoryManager do
|> join(:full, [r, o, os], u in User, on: u.id == r.user_id)
|> join(:full, [r, o, os, u], us in Slug, on: us.user_id == u.id)
|> where([r, o, os, u, us], not is_nil(r))
- |> preload([members: :slug,
- organisation: [:slug, users: :slug],
- user: :slug])
|> search(params)
|> index_order_by(params)
- |> Repo.all()
+ |> Pagination.page(params, preload: [members: :slug,
+ organisation: [:slug, users: :slug],
+ user: :slug])
end
def search(query, %IndexParams{search: search}) do
diff --git a/lib/kmxgit_web.ex b/lib/kmxgit_web.ex
index 5c56545..525dabb 100644
--- a/lib/kmxgit_web.ex
+++ b/lib/kmxgit_web.ex
@@ -63,6 +63,10 @@ defmodule KmxgitWeb do
|> FileSize.to_string()
end
+ def page_link(conn, title \\ nil, page) do
+ link title || page, to: Routes.admin_repository_path(conn, :index, page: page, per: conn.assigns.pagination.per, search: conn.assigns.search, sort: conn.assigns.sort), class: "btn btn-primary"
+ end
+
def recaptcha_site_key do
Application.get_env :kmxgit, :recaptcha_site_key
end
diff --git a/lib/kmxgit_web/controllers/admin.ex b/lib/kmxgit_web/controllers/admin.ex
index 781f592..971efb5 100644
--- a/lib/kmxgit_web/controllers/admin.ex
+++ b/lib/kmxgit_web/controllers/admin.ex
@@ -2,8 +2,26 @@ defmodule KmxgitWeb.Admin do
alias Kmxgit.IndexParams
+ def page_params(index_params = %IndexParams{}, nil, nil) do
+ index_params
+ end
+ def page_params(index_params = %IndexParams{}, page, nil) do
+ %IndexParams{index_params | page: String.to_integer(page)}
+ end
+ def page_params(index_params = %IndexParams{}, nil, per) do
+ %IndexParams{index_params | per: String.to_integer(per)}
+ end
+ def page_params(index_params = %IndexParams{}, page, per) do
+ %IndexParams{index_params | page: String.to_integer(page),
+ per: String.to_integer(per)}
+ end
+
+ def search_param(index_params = %IndexParams{}, param) do
+ %IndexParams{index_params | search: param}
+ end
+
def sort_param(index_params = %IndexParams{}, param) do
- if param do
+ if param && param != "" do
case String.split(param, "-") do
[col, _] -> %IndexParams{index_params | column: col, reverse: true}
[col] -> %IndexParams{index_params | column: col}
@@ -13,8 +31,4 @@ defmodule KmxgitWeb.Admin do
index_params
end
end
-
- def search_param(index_params = %IndexParams{}, param) do
- %IndexParams{index_params | search: param}
- end
end
diff --git a/lib/kmxgit_web/controllers/admin/repository_controller.ex b/lib/kmxgit_web/controllers/admin/repository_controller.ex
index a61b1f8..d70e044 100644
--- a/lib/kmxgit_web/controllers/admin/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/admin/repository_controller.ex
@@ -11,14 +11,16 @@ defmodule KmxgitWeb.Admin.RepositoryController do
def index(conn, params) do
index_params = %IndexParams{}
- |> KmxgitWeb.Admin.sort_param(params["sort"])
+ |> KmxgitWeb.Admin.page_params(params["page"], params["per"])
|> KmxgitWeb.Admin.search_param(params["search"])
- repos = RepositoryManager.list_repositories(index_params)
+ |> KmxgitWeb.Admin.sort_param(params["sort"])
+ pagination = RepositoryManager.list_repositories(index_params)
conn
- |> assign(:repos, repos)
|> assign(:index, index_params)
+ |> assign(:pagination, pagination)
|> assign(:search, params["search"])
|> assign(:search_action, Routes.admin_repository_path(conn, :index, sort: params["sort"], search: params["search"]))
+ |> assign(:sort, params["sort"])
|> render("index.html")
end
diff --git a/lib/kmxgit_web/templates/admin/repository/index.html.heex b/lib/kmxgit_web/templates/admin/repository/index.html.heex
index 9782fa8..e2f6950 100644
--- a/lib/kmxgit_web/templates/admin/repository/index.html.heex
+++ b/lib/kmxgit_web/templates/admin/repository/index.html.heex
@@ -1,6 +1,7 @@
<div class="container-fluid">
<h1>Repositories</h1>
<%= render(KmxgitWeb.LayoutView, "search.html", assigns) %>
+ <%= render(KmxgitWeb.LayoutView, "pagination.html", assigns) %>
<table class="table admin-index">
<thead>
<tr>
@@ -12,7 +13,7 @@
</tr>
</thead>
<tbody>
- <%= Enum.map @repos, fn(repo) -> %>
+ <%= Enum.map @pagination.result, fn repo -> %>
<tr>
<td><%= link repo.id, to: Routes.admin_repository_path(@conn, :show, repo) %></td>
<td>
@@ -32,4 +33,5 @@
<% end %>
</tbody>
</table>
+ <%= render(KmxgitWeb.LayoutView, "pagination.html", assigns) %>
</div>
diff --git a/lib/kmxgit_web/templates/layout/pagination.html.heex b/lib/kmxgit_web/templates/layout/pagination.html.heex
new file mode 100644
index 0000000..4e16e8c
--- /dev/null
+++ b/lib/kmxgit_web/templates/layout/pagination.html.heex
@@ -0,0 +1,21 @@
+<%= if @pagination.first_page do %>
+ <%= page_link @conn, raw("<i class=\"fa fa-angle-double-left\"></i>"), @pagination.first_page %>
+<% end %>
+<%= if @pagination.prev_page do %>
+ <%= page_link @conn, raw("<i class=\"fa fa-angle-left\"></i>"), @pagination.prev_page %>
+<% end %>
+<span class="btn btn-primary disabled">
+ <%= @pagination.page %>
+</span>
+<%= if @pagination.next_page do %>
+ <%= page_link @conn, raw("<i class=\"fa fa-angle-right\"></i>"), @pagination.next_page %>
+<% end %>
+<%= if @pagination.last_page do %>
+ <%= page_link @conn, raw("<i class=\"fa fa-angle-double-right\"></i>"), @pagination.last_page %>
+<% end %>
+
+<%= @pagination.first %>
+-
+<%= @pagination.last %>
+<%= gettext("out of") %>
+<%= @pagination.count %>