diff --git a/lib/kmxgit/user_manager.ex b/lib/kmxgit/user_manager.ex
index 1787026..33fb39e 100644
--- a/lib/kmxgit/user_manager.ex
+++ b/lib/kmxgit/user_manager.ex
@@ -9,10 +9,123 @@ defmodule Kmxgit.UserManager do
alias Kmxgit.SlugManager.Slug
alias Kmxgit.UserManager.{Avatar, User, UserToken, UserNotifier}
+ @list_preload [:owned_repositories,
+ :slug]
+
def list_users do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload
+ end
+ def list_users(%{column: "id", reverse: true}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: [desc: :id]
+ end
+ def list_users(%{column: "id"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: :id
+ end
+ def list_users(%{column: "name", reverse: true}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: [desc: :name]
+ end
+ def list_users(%{column: "name"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: :name
+ end
+ def list_users(%{column: "email", reverse: true}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: [desc: :email]
+ end
+ def list_users(%{column: "email"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: :email
+ end
+ def list_users(%{column: "login", reverse: true}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ join: s in Slug,
+ on: s.user_id == user.id,
+ preload: ^@list_preload,
+ order_by: [desc: s.slug]
+ end
+ def list_users(%{column: "login"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ join: s in Slug,
+ on: s.user_id == user.id,
+ preload: ^@list_preload,
+ order_by: s.slug
+ end
+ def list_users(%{column: "du", reverse: true}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: [desc: :disk_usage]
+ end
+ def list_users(%{column: "du"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: :disk_usage
+ end
+ def list_users(%{column: "mfa", reverse: true}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: [desc: user.totp_last == 0]
+ end
+ def list_users(%{column: "mfa"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: user.totp_last == 0
+ end
+ def list_users(%{column: "admin", reverse: true}) do
+ update_disk_usage()
Repo.all from user in User,
- preload: [:owned_repositories,
- :slug]
+ preload: ^@list_preload,
+ order_by: [desc: :is_admin]
+ end
+ def list_users(%{column: "admin"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: :is_admin
+ end
+ def list_users(%{column: "deploy", reverse: true}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: [desc: :deploy_only]
+ end
+ def list_users(%{column: "deploy"}) do
+ update_disk_usage()
+ Repo.all from user in User,
+ preload: ^@list_preload,
+ order_by: :deploy_only
+ end
+
+ def update_disk_usage() do
+ users = Repo.all(from user in User, preload: :slug)
+ |> Enum.map(fn user ->
+ user
+ |> Ecto.Changeset.cast(%{}, [])
+ |> Ecto.Changeset.put_change(:disk_usage, User.disk_usage(user))
+ |> Repo.update!()
+ end)
end
def put_disk_usage(user = %User{}) do
diff --git a/lib/kmxgit/user_manager/user.ex b/lib/kmxgit/user_manager/user.ex
index ed53e1d..d327d34 100644
--- a/lib/kmxgit/user_manager/user.ex
+++ b/lib/kmxgit/user_manager/user.ex
@@ -12,7 +12,7 @@ defmodule Kmxgit.UserManager.User do
field :confirmed_at, :utc_datetime
field :deploy_only, :boolean, null: false, default: false
field :description, :string, null: true
- field :disk_usage, :integer, virtual: true, default: 0
+ field :disk_usage, :integer, default: 0
field :email, :string
field :hashed_password, :string, redact: true
field :is_admin, :boolean, null: false, default: false
diff --git a/lib/kmxgit_web/controllers/admin/user_controller.ex b/lib/kmxgit_web/controllers/admin/user_controller.ex
index 2f6b4af..b527253 100644
--- a/lib/kmxgit_web/controllers/admin/user_controller.ex
+++ b/lib/kmxgit_web/controllers/admin/user_controller.ex
@@ -7,11 +7,12 @@ defmodule KmxgitWeb.Admin.UserController do
alias Kmxgit.UserManager.User
alias KmxgitWeb.ErrorView
- def index(conn, _params) do
- users = UserManager.list_users
- |> UserManager.put_disk_usage()
+ def index(conn, params) do
+ sort = KmxgitWeb.Admin.sort_param(params["sort"])
+ users = UserManager.list_users(sort)
conn
|> assign(:page_title, gettext("Users"))
+ |> assign(:sort, sort)
|> assign(:users, users)
|> 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 6492d81..37d7480 100644
--- a/lib/kmxgit_web/templates/admin/repository/index.html.heex
+++ b/lib/kmxgit_web/templates/admin/repository/index.html.heex
@@ -2,30 +2,34 @@
<h1>Repositories</h1>
<table class="table admin-index">
- <tr>
- <th><%= link gettext("Id"), to: Routes.admin_repository_path(@conn, :index, sort: "id#{if @sort.column == "id" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "id" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
- <th><%= link gettext("Owner"), to: Routes.admin_repository_path(@conn, :index, sort: "owner#{if @sort.column == "owner" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "owner" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
- <th><%= link gettext("Slug"), to: Routes.admin_repository_path(@conn, :index, sort: "slug#{if @sort.column == "slug" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "slug" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
- <th><%= link gettext("Disk usage"), to: Routes.admin_repository_path(@conn, :index, sort: "du#{if @sort.column == "du" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "du" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
- <th><%= gettext("Actions") %></th>
- </tr>
- <%= Enum.map @repos, fn(repo) -> %>
+ <thead>
<tr>
- <td><%= link repo.id, to: Routes.admin_repository_path(@conn, :show, repo) %></td>
- <td>
- <%= case owner = Repository.owner(repo) do %>
- <% %Organisation{} -> %>
- <%= link owner.name || owner.slug.slug, to: Routes.admin_organisation_path(@conn, :show, owner) %>
- <% %User{} -> %>
- <%= link owner.slug.slug, to: Routes.admin_user_path(@conn, :show, owner) %>
- <% end %>
- </td>
- <td><%= link Repository.full_slug(repo), to: Routes.admin_repository_path(@conn, :show, repo) %></td>
- <td><%= disk_usage(repo.disk_usage) %></td>
- <td>
- <%= link gettext("Show"), to: Routes.repository_path(@conn, :show, Repository.owner_slug(repo), Repository.splat(repo)), class: "btn btn-sm btn-primary" %>
- </td>
+ <th><%= link gettext("Id"), to: Routes.admin_repository_path(@conn, :index, sort: "id#{if @sort.column == "id" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "id" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Owner"), to: Routes.admin_repository_path(@conn, :index, sort: "owner#{if @sort.column == "owner" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "owner" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Slug"), to: Routes.admin_repository_path(@conn, :index, sort: "slug#{if @sort.column == "slug" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "slug" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Disk usage"), to: Routes.admin_repository_path(@conn, :index, sort: "du#{if @sort.column == "du" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "du" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= gettext("Actions") %></th>
</tr>
- <% end %>
+ </thead>
+ <tbody>
+ <%= Enum.map @repos, fn(repo) -> %>
+ <tr>
+ <td><%= link repo.id, to: Routes.admin_repository_path(@conn, :show, repo) %></td>
+ <td>
+ <%= case owner = Repository.owner(repo) do %>
+ <% %Organisation{} -> %>
+ <%= link owner.name || owner.slug.slug, to: Routes.admin_organisation_path(@conn, :show, owner) %>
+ <% %User{} -> %>
+ <%= link owner.slug.slug, to: Routes.admin_user_path(@conn, :show, owner) %>
+ <% end %>
+ </td>
+ <td><%= link Repository.full_slug(repo), to: Routes.admin_repository_path(@conn, :show, repo) %></td>
+ <td><%= disk_usage(repo.disk_usage) %></td>
+ <td>
+ <%= link gettext("Show"), to: Routes.repository_path(@conn, :show, Repository.owner_slug(repo), Repository.splat(repo)), class: "btn btn-sm btn-primary" %>
+ </td>
+ </tr>
+ <% end %>
+ </tbody>
</table>
</div>
diff --git a/lib/kmxgit_web/templates/admin/user/index.html.heex b/lib/kmxgit_web/templates/admin/user/index.html.heex
index 5f9089b..9e88f77 100644
--- a/lib/kmxgit_web/templates/admin/user/index.html.heex
+++ b/lib/kmxgit_web/templates/admin/user/index.html.heex
@@ -9,30 +9,33 @@
</div>
<table class="table admin-index">
- <tr>
- <th><%= gettext "Id" %></th>
- <th><%= gettext "Name" %></th>
- <th><%= gettext "Email" %></th>
- <th><%= gettext "Login" %></th>
- <th><%= gettext "Disk usage" %></th>
- <th><%= gettext "2FA" %></th>
- <th><%= gettext "Admin" %></th>
- <th><%= gettext "Deploy" %></th>
- <th><%= gettext "Actions" %></th>
- </tr>
- <%= Enum.map @users, fn(user) -> %>
+ <thead>
<tr>
- <td><%= link user.id, to: Routes.admin_user_path(@conn, :show, user) %></td>
- <td><%= link user.name, to: Routes.admin_user_path(@conn, :show, user) %></td>
- <td><%= link user.email, to: "mailto:#{user.email}" %></td>
- <td><%= link User.login(user), to: Routes.admin_user_path(@conn, :show, user) %></td>
- <td><%= disk_usage(user.disk_usage) %></td>
- <td><%= if user.totp_last != 0, do: "TOTP", else: "none" %></td>
- <td><%= user.is_admin %></td>
- <td><%= user.deploy_only %></td>
- <td><%= link gettext("Show"), to: Routes.slug_path(@conn, :show, User.login(user) || ""), class: "btn btn-sm btn-primary" %></td>
+ <th><%= link gettext("Id"), to: Routes.admin_user_path(@conn, :index, sort: "id#{if @sort.column == "id" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "id" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Name"), to: Routes.admin_user_path(@conn, :index, sort: "name#{if @sort.column == "name" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "name" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Email"), to: Routes.admin_user_path(@conn, :index, sort: "email#{if @sort.column == "email" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "email" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Login"), to: Routes.admin_user_path(@conn, :index, sort: "login#{if @sort.column == "login" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "login" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Disk usage"), to: Routes.admin_user_path(@conn, :index, sort: "du#{if @sort.column == "du" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "du" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("2FA"), to: Routes.admin_user_path(@conn, :index, sort: "mfa#{if @sort.column == "mfa" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "mfa" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Admin"), to: Routes.admin_user_path(@conn, :index, sort: "admin#{if @sort.column == "admin" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "admin" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= link gettext("Deploy"), to: Routes.admin_user_path(@conn, :index, sort: "deploy#{if @sort.column == "deploy" && !@sort.reverse, do: "-"}") %><%= if @sort.column == "deploy" do %><%= if @sort.reverse do %> <i class="fa fa-angle-down"></i><% else %> <i class="fa fa-angle-up"></i><% end %><% end %></th>
+ <th><%= gettext "Actions" %></th>
</tr>
- <% end %>
+ </thead>
+ <tbody>
+ <%= Enum.map @users, fn(user) -> %>
+ <tr>
+ <td><%= link user.id, to: Routes.admin_user_path(@conn, :show, user) %></td>
+ <td><%= link user.name, to: Routes.admin_user_path(@conn, :show, user) %></td>
+ <td><%= link user.email, to: "mailto:#{user.email}" %></td>
+ <td><%= link User.login(user), to: Routes.admin_user_path(@conn, :show, user) %></td>
+ <td><%= disk_usage(user.disk_usage) %></td>
+ <td><%= if user.totp_last != 0, do: "TOTP", else: "none" %></td>
+ <td><%= user.is_admin %></td>
+ <td><%= user.deploy_only %></td>
+ <td><%= link gettext("Show"), to: Routes.slug_path(@conn, :show, User.login(user) || ""), class: "btn btn-sm btn-primary" %></td>
+ </tr>
+ <% end %>
+ </tbody>
</table>
-
</div>
diff --git a/priv/repo/migrations/20220127154904_add_disk_usage_to_users.exs b/priv/repo/migrations/20220127154904_add_disk_usage_to_users.exs
new file mode 100644
index 0000000..f2d7d76
--- /dev/null
+++ b/priv/repo/migrations/20220127154904_add_disk_usage_to_users.exs
@@ -0,0 +1,9 @@
+defmodule Kmxgit.Repo.Migrations.AddDiskUsageToUsers do
+ use Ecto.Migration
+
+ def change do
+ alter table(:users) do
+ add :disk_usage, :integer, default: 0
+ end
+ end
+end