Skip to content

Commit 612dcf4

Browse files
taras-tyshkoTaras Tyshko
andauthored
Fix Audit Logs pagination on Device pages (#2257)
Fix pagination functionality for Audit Logs on Device pages in both old and new UI implementations. ### The Problem - Pagination buttons were not working on device pages - Old UI and new UI had different default page sizes causing incorrect page counts - URL parameters were not being read properly ### What was fixed ✅ **Old UI**: Fixed `handle_params` to read URL pagination parameters ✅ **New UI**: Fixed `ActivityTab.tab_params` to extract pagination from URL ✅ **Dynamic defaults**: `page_size=5` for old UI, `page_size=25` for new UI ✅ **URL handling**: Pagination now stays on correct pages ### Impact - Before: Pagination buttons did not work, always showed page 1 - After: Full pagination functionality with correct page counts for each UI --------- Co-authored-by: Taras Tyshko <[email protected]>
1 parent b5c45f2 commit 612dcf4

File tree

4 files changed

+165
-17
lines changed

4 files changed

+165
-17
lines changed

lib/nerves_hub_web/components/device_page/activity_tab.ex

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ defmodule NervesHubWeb.Components.DevicePage.ActivityTab do
55

66
alias NervesHubWeb.Components.Pager
77

8-
def tab_params(_params, _uri, socket) do
8+
def tab_params(params, _uri, socket) do
9+
page_number = String.to_integer(Map.get(params, "page_number", "1"))
10+
page_size = String.to_integer(Map.get(params, "page_size", "25"))
11+
912
socket
10-
|> logs_and_pager_assigns()
13+
|> logs_and_pager_assigns(page_number, page_size)
1114
|> cont()
1215
end
1316

1417
def cleanup() do
1518
[:activity, :audit_pager]
1619
end
1720

18-
defp logs_and_pager_assigns(socket, page_number \\ 1, page_size \\ 25) do
21+
defp logs_and_pager_assigns(socket, page_number, page_size) do
1922
{logs, audit_pager} =
2023
AuditLogs.logs_for_feed(socket.assigns.device, %{
2124
page: page_number,
@@ -96,7 +99,7 @@ defmodule NervesHubWeb.Components.DevicePage.ActivityTab do
9699
end
97100

98101
def hooked_event("set-paginate-opts", %{"page-size" => page_size}, socket) do
99-
params = %{"page_size" => page_size, "page_number" => 1}
102+
params = %{"page_size" => page_size, "page_number" => "1"}
100103

101104
%{org: org, product: product, device: device} = socket.assigns
102105

lib/nerves_hub_web/live/devices/show.ex

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,22 @@ defmodule NervesHubWeb.Live.Devices.Show do
6363
|> assign_metadata()
6464
|> schedule_health_check_timer()
6565
|> assign(:fwup_progress, nil)
66-
|> assign(:page_number, 1)
67-
|> assign(:page_size, 5)
6866
|> assign(:pinned?, Devices.device_pinned?(user.id, device.id))
69-
|> audit_log_assigns()
7067
|> assign_deployment_groups()
7168
|> setup_presence_tracking()
7269
|> setup_tab_components(@tab_components)
7370
|> ok()
7471
end
7572

76-
def handle_params(_params, _uri, socket) do
73+
def handle_params(params, _uri, socket) do
74+
default_page_size = if socket.assigns[:new_ui], do: "25", else: "5"
75+
page_number = String.to_integer(Map.get(params, "page_number", "1"))
76+
page_size = String.to_integer(Map.get(params, "page_size", default_page_size))
77+
7778
socket
79+
|> assign(:page_number, page_number)
80+
|> assign(:page_size, page_size)
81+
|> audit_log_assigns()
7882
|> update_tab_component_hooks()
7983
|> noreply()
8084
end
@@ -283,12 +287,11 @@ defmodule NervesHubWeb.Live.Devices.Show do
283287
end
284288
end
285289

286-
def handle_event("paginate", %{"page" => page_num}, socket) do
287-
params = %{"page_size" => socket.assigns.page_size, "page_number" => page_num}
288-
290+
def handle_event("paginate", %{"page" => page_number}, socket) do
291+
params = %{"page_size" => socket.assigns.page_size, "page_number" => page_number}
289292
%{org: org, product: product, device: device} = socket.assigns
290293

291-
url = ~p"/org/#{org}/#{product}/devices/#{device}/activity?#{params}"
294+
url = ~p"/org/#{org}/#{product}/devices/#{device}?#{params}"
292295

293296
socket
294297
|> push_patch(to: url)
@@ -484,11 +487,10 @@ defmodule NervesHubWeb.Live.Devices.Show do
484487
end
485488

486489
def handle_event("set-paginate-opts", %{"page-size" => page_size}, socket) do
487-
params = %{"page_size" => page_size, "page_number" => 1}
488-
490+
params = %{"page_size" => page_size, "page_number" => "1"}
489491
%{org: org, product: product, device: device} = socket.assigns
490492

491-
url = ~p"/org/#{org}/#{product}/devices/#{device}/activity?#{params}"
493+
url = ~p"/org/#{org}/#{product}/devices/#{device}?#{params}"
492494

493495
socket
494496
|> push_patch(to: url)

test/nerves_hub_web/live/devices/show_test.exs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,62 @@ defmodule NervesHubWeb.Live.Devices.ShowTest do
686686
end
687687
end
688688

689+
describe "audit logs pagination" do
690+
test "pagination works with URL parameters", %{
691+
conn: conn,
692+
org: org,
693+
product: product,
694+
device: device,
695+
user: user
696+
} do
697+
# Create multiple audit log entries for pagination testing
698+
Enum.each(1..12, fn i ->
699+
NervesHub.AuditLogs.audit!(user, device, "Test audit log entry #{i}")
700+
end)
701+
702+
# Test page 1 with default page_size=5
703+
conn
704+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}")
705+
|> assert_has("div.audit-log-item", count: 5)
706+
|> assert_has("button[phx-value-page=\"2\"]")
707+
708+
# Test page 2 with page_size=5
709+
conn
710+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}?page_number=2&page_size=5")
711+
# Still showing 5 per page
712+
|> assert_has("div.audit-log-item", count: 5)
713+
|> assert_has("button[phx-value-page=\"1\"]")
714+
715+
# Test custom page_size=10
716+
conn
717+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}?page_number=1&page_size=10")
718+
|> assert_has("div.audit-log-item", count: 10)
719+
end
720+
721+
test "pagination events work correctly", %{
722+
conn: conn,
723+
org: org,
724+
product: product,
725+
device: device,
726+
user: user
727+
} do
728+
# Create enough audit logs for pagination
729+
Enum.each(1..8, fn i ->
730+
NervesHub.AuditLogs.audit!(user, device, "Pagination test entry #{i}")
731+
end)
732+
733+
{:ok, view, _html} = live(conn, ~p"/org/#{org}/#{product}/devices/#{device}")
734+
735+
# Test paginate event
736+
view
737+
|> element("button[phx-click=\"paginate\"][phx-value-page=\"2\"]", "2")
738+
|> render_click()
739+
740+
# Should redirect to page 2 on same device page
741+
assert_patch(view, ~p"/org/#{org}/#{product}/devices/#{device}?page_number=2&page_size=5")
742+
end
743+
end
744+
689745
def device_show_path(%{device: device, org: org, product: product}) do
690746
~p"/org/#{org}/#{product}/devices/#{device}"
691747
end

test/nerves_hub_web/live/new_ui/devices/activity_tab_test.exs

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ defmodule NervesHubWeb.Live.NewUI.Devices.ActivityTabTest do
1414
device: device
1515
} do
1616
conn
17-
|> visit("/org/#{org.name}/#{product.name}/devices/#{device.identifier}/activity")
17+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}/activity")
1818
|> assert_has("span", text: "No audit logs found for the device.")
1919
end
2020

@@ -29,7 +29,94 @@ defmodule NervesHubWeb.Live.NewUI.Devices.ActivityTabTest do
2929
DeviceTemplates.audit_reboot(user, device)
3030

3131
conn
32-
|> visit("/org/#{org.name}/#{product.name}/devices/#{device.identifier}/activity")
32+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}/activity")
3333
|> assert_has("div", text: "User #{user.name} rebooted device #{device.identifier}")
3434
end
35+
36+
describe "pagination" do
37+
test "pagination works with URL parameters", %{
38+
conn: conn,
39+
org: org,
40+
product: product,
41+
device: device,
42+
user: user
43+
} do
44+
# Create multiple audit log entries for pagination testing (30 entries)
45+
Enum.each(1..30, fn i ->
46+
NervesHub.AuditLogs.audit!(user, device, "New UI test audit log entry #{i}")
47+
end)
48+
49+
# Test page 1 with default page_size=25
50+
conn
51+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}/activity")
52+
|> assert_has("div.flex.items-center.gap-6", count: 25)
53+
|> assert_has("button[phx-value-page=\"2\"]")
54+
55+
# Test page 2 with page_size=25
56+
conn
57+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}/activity?page_number=2&page_size=25")
58+
# Remaining 5 entries
59+
|> assert_has("div.flex.items-center.gap-6", count: 5)
60+
|> assert_has("button[phx-value-page=\"1\"]")
61+
62+
# Test custom page_size=10
63+
conn
64+
|> visit(~p"/org/#{org}/#{product}/devices/#{device}/activity?page_number=1&page_size=10")
65+
|> assert_has("div.flex.items-center.gap-6", count: 10)
66+
|> assert_has("button[phx-value-page=\"2\"]")
67+
|> assert_has("button[phx-value-page=\"3\"]")
68+
end
69+
70+
test "pagination events work correctly", %{
71+
conn: conn,
72+
org: org,
73+
product: product,
74+
device: device,
75+
user: user
76+
} do
77+
# Create enough audit logs for pagination
78+
Enum.each(1..30, fn i ->
79+
NervesHub.AuditLogs.audit!(user, device, "New UI pagination test entry #{i}")
80+
end)
81+
82+
{:ok, view, _html} = live(conn, ~p"/org/#{org}/#{product}/devices/#{device}/activity")
83+
84+
# Test paginate event
85+
view
86+
|> element("button[phx-click=\"paginate\"][phx-value-page=\"2\"]", "2")
87+
|> render_click()
88+
89+
# Should redirect to page 2 on activity page
90+
assert_patch(
91+
view,
92+
~p"/org/#{org}/#{product}/devices/#{device}/activity?page_number=2&page_size=25"
93+
)
94+
end
95+
96+
test "page size selection works correctly", %{
97+
conn: conn,
98+
org: org,
99+
product: product,
100+
device: device,
101+
user: user
102+
} do
103+
# Create 60 audit logs for testing page size changes
104+
Enum.each(1..60, fn i ->
105+
NervesHub.AuditLogs.audit!(user, device, "Page size test entry #{i}")
106+
end)
107+
108+
{:ok, view, _html} = live(conn, ~p"/org/#{org}/#{product}/devices/#{device}/activity")
109+
110+
# Test changing page size to 50
111+
view
112+
|> element("button[phx-click=\"set-paginate-opts\"][phx-value-page-size=\"50\"]")
113+
|> render_click()
114+
115+
# Should redirect to page 1 with page_size=50
116+
assert_patch(
117+
view,
118+
~p"/org/#{org}/#{product}/devices/#{device}/activity?page_number=1&page_size=50"
119+
)
120+
end
121+
end
35122
end

0 commit comments

Comments
 (0)