Skip to content

Commit ce6fc03

Browse files
committed
feat(front): add members download button
- Add members download button on people page - Implement export members as csv endpoint - Add export members test
1 parent ade15ba commit ce6fc03

File tree

4 files changed

+84
-3
lines changed

4 files changed

+84
-3
lines changed

front/lib/front_web/controllers/people_controller.ex

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ defmodule FrontWeb.PeopleController do
2424
plug(FetchPermissions, [scope: "org"] when action in @person_action)
2525
plug(PageAccess, [permissions: "organization.view"] when action in @person_action)
2626

27-
plug(FetchPermissions, [scope: "org"] when action in [:organization])
28-
plug(PageAccess, [permissions: "organization.view"] when action in [:organization])
27+
plug(FetchPermissions, [scope: "org"] when action in [:organization, :organization_users])
28+
29+
plug(
30+
PageAccess,
31+
[permissions: "organization.view"] when action in [:organization, :organization_users]
32+
)
2933

3034
plug(
3135
FetchPermissions,
@@ -1061,6 +1065,51 @@ defmodule FrontWeb.PeopleController do
10611065
end)
10621066
end
10631067

1068+
def organization_users(conn, _params) do
1069+
Watchman.benchmark("people.organization_users.duration", fn ->
1070+
org_id = conn.assigns.organization_id
1071+
1072+
page_size = 100
1073+
1074+
data =
1075+
Stream.unfold(0, fn
1076+
nil ->
1077+
nil
1078+
1079+
page_no ->
1080+
case Members.list_org_members(org_id, page_no: page_no, page_size: page_size) do
1081+
{:ok, {[_ | _] = members, total_pages}} ->
1082+
{members, next_valid_page_or_nil(total_pages, page_no)}
1083+
1084+
_ ->
1085+
nil
1086+
end
1087+
end)
1088+
|> Enum.flat_map(& &1)
1089+
|> Enum.map(fn e ->
1090+
%{
1091+
"name" => e.name,
1092+
"email" => e.email,
1093+
"github_login" => e.github_login,
1094+
"bitbucket_login" => e.bitbucket_login,
1095+
"gitlab_login" => e.gitlab_login
1096+
}
1097+
end)
1098+
|> CSV.encode(
1099+
headers: [
1100+
"name",
1101+
"email",
1102+
"github_login",
1103+
"bitbucket_login",
1104+
"gitlab_login"
1105+
]
1106+
)
1107+
|> Enum.to_list()
1108+
1109+
send_download(conn, {:binary, data}, filename: "users.csv")
1110+
end)
1111+
end
1112+
10641113
def sync(conn, %{"format" => "json"}) do
10651114
Watchman.benchmark("sync.organization.duration", fn ->
10661115
org_id = conn.assigns.organization_id
@@ -1213,4 +1262,14 @@ defmodule FrontWeb.PeopleController do
12131262
email_regex = ~r/^[^\s@]+@[^\s@]+\.[^\s@]+$/
12141263
Regex.match?(email_regex, email)
12151264
end
1265+
1266+
defp next_valid_page_or_nil(total_pages, page) do
1267+
next_page_no = page + 1
1268+
1269+
if next_page_no <= total_pages do
1270+
next_page_no
1271+
else
1272+
nil
1273+
end
1274+
end
12161275
end

front/lib/front_web/router.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ defmodule FrontWeb.Router do
152152

153153
scope "/people" do
154154
get("/", PeopleController, :organization)
155+
get("/export", PeopleController, :organization_users)
155156
post("/", PeopleController, :create)
156157
post("/refresh", PeopleController, :refresh)
157158
post("/assign_role", PeopleController, :assign_role)

front/lib/front_web/templates/people/members/members_list.html.eex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@
3232
<div class="b">People</div>
3333
</div>
3434
</div>
35-
<%= render "members/_add_people_button.html", conn: @conn, org_scope?: @org_scope?, permissions: @permissions %>
35+
<div class="flex">
36+
<%= if @org_scope? do %>
37+
<%= link to: people_path(@conn, :organization_users), class: "pointer flex items-center btn-secondary btn nowrap mr2", aria_label: "Download members as CSV", title: "Download members as CSV" do %>
38+
<span class="material-symbols-outlined ">download</span>
39+
<% end %>
40+
<% end %>
41+
<%= render "members/_add_people_button.html", conn: @conn, org_scope?: @org_scope?, permissions: @permissions %>
42+
</div>
3643
</div>
3744

3845
<div id="members">

front/test/front_web/controllers/people_controller_test.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ defmodule FrontWeb.PeopleControllerTest do
3636
]
3737
end
3838

39+
describe "GET organization_users" do
40+
test "when the user can't access the org => returns 404", %{
41+
conn: conn
42+
} do
43+
PermissionPatrol.remove_all_permissions()
44+
45+
conn =
46+
conn
47+
|> get("/people/export")
48+
49+
assert html_response(conn, 404) =~ "404"
50+
end
51+
end
52+
3953
describe "GET show" do
4054
test "when the user can't access the org => returns 404", %{
4155
conn: conn,

0 commit comments

Comments
 (0)