From 06919388b3a8f8ac96b3e49f9e7cd5aeba3bbddc Mon Sep 17 00:00:00 2001 From: Alban Bailly Date: Mon, 2 Mar 2026 13:22:11 +0100 Subject: [PATCH 1/3] fix --- .../AssignedEntitiesTable/AssignedEntitiesTable.tsx | 3 ++- packages/manager/src/hooks/usePaginationV2.test.ts | 8 ++++---- packages/manager/src/hooks/usePaginationV2.ts | 9 +++++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx b/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx index 0e4b7e62c19..afbe592bf76 100644 --- a/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx +++ b/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx @@ -76,6 +76,7 @@ export const AssignedEntitiesTable = ({ username }: Props) => { order: orderParam, selectedRole: selectedRoleSearchParam, orderBy: orderByParam, + page: pageParam, } = useSearch({ from: isDefaultDelegationRolesForChildAccount ? DEFAULTS_ENTITIES_URL @@ -231,7 +232,7 @@ export const AssignedEntitiesTable = ({ username }: Props) => { currentRoute: isDefaultDelegationRolesForChildAccount ? DEFAULTS_ENTITIES_URL : USER_ENTITIES_URL, - initialPage: 1, + initialPage: pageParam ?? 1, preferenceKey: ENTITIES_TABLE_PREFERENCE_KEY, clientSidePaginationData: filteredAndSortedRoles, }); diff --git a/packages/manager/src/hooks/usePaginationV2.test.ts b/packages/manager/src/hooks/usePaginationV2.test.ts index 67dde099a4d..03df3a581fc 100644 --- a/packages/manager/src/hooks/usePaginationV2.test.ts +++ b/packages/manager/src/hooks/usePaginationV2.test.ts @@ -804,7 +804,7 @@ describe('usePaginationV2', () => { expect(mockNavigate).not.toHaveBeenCalled(); }); - it('should handle page clamping to 1 for empty data', async () => { + it('should not reset page when data is empty (e.g. still loading) to preserve URL on reload', async () => { queryClient.setQueryData(['profile', 'preferences'], { pageSizes: { 'test-key': 25 }, }); @@ -826,9 +826,9 @@ describe('usePaginationV2', () => { expect(result.current.page).toBe(1); }); - await waitFor(() => { - expect(mockNavigate).toHaveBeenCalled(); - }); + // Should not trigger navigation when totalCount is 0 so that page from URL + // is preserved on reload while data is still loading + expect(mockNavigate).not.toHaveBeenCalled(); }); it('should auto-reset page when data changes and current page becomes invalid', async () => { diff --git a/packages/manager/src/hooks/usePaginationV2.ts b/packages/manager/src/hooks/usePaginationV2.ts index 09b224a0617..ae794ad1214 100644 --- a/packages/manager/src/hooks/usePaginationV2.ts +++ b/packages/manager/src/hooks/usePaginationV2.ts @@ -143,10 +143,15 @@ export const usePaginationV2 = ({ }, [clientSidePaginationData, clampedPage, pageSize]); React.useEffect(() => { - if (paginatedData !== undefined && clampedPage !== page) { + if ( + paginatedData !== undefined && + totalCount !== undefined && + totalCount > 0 && + clampedPage !== page + ) { setPage(clampedPage); } - }, [clampedPage, page, paginatedData, setPage]); + }, [clampedPage, page, paginatedData, setPage, totalCount]); return { handlePageChange: setPage, From 4ab56fe41d36daa20c8df54b7794465b9194830d Mon Sep 17 00:00:00 2001 From: Alban Bailly Date: Mon, 2 Mar 2026 13:42:22 +0100 Subject: [PATCH 2/3] cleanup --- .../IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx b/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx index afbe592bf76..0e4b7e62c19 100644 --- a/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx +++ b/packages/manager/src/features/IAM/Shared/AssignedEntitiesTable/AssignedEntitiesTable.tsx @@ -76,7 +76,6 @@ export const AssignedEntitiesTable = ({ username }: Props) => { order: orderParam, selectedRole: selectedRoleSearchParam, orderBy: orderByParam, - page: pageParam, } = useSearch({ from: isDefaultDelegationRolesForChildAccount ? DEFAULTS_ENTITIES_URL @@ -232,7 +231,7 @@ export const AssignedEntitiesTable = ({ username }: Props) => { currentRoute: isDefaultDelegationRolesForChildAccount ? DEFAULTS_ENTITIES_URL : USER_ENTITIES_URL, - initialPage: pageParam ?? 1, + initialPage: 1, preferenceKey: ENTITIES_TABLE_PREFERENCE_KEY, clientSidePaginationData: filteredAndSortedRoles, }); From c92521795dc6fdcfffe8db6c97dce3b89dae1b01 Mon Sep 17 00:00:00 2001 From: Alban Bailly Date: Mon, 2 Mar 2026 14:26:36 +0100 Subject: [PATCH 3/3] changeset --- packages/manager/.changeset/pr-13451-fixed-1772457963491.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-13451-fixed-1772457963491.md diff --git a/packages/manager/.changeset/pr-13451-fixed-1772457963491.md b/packages/manager/.changeset/pr-13451-fixed-1772457963491.md new file mode 100644 index 00000000000..16cedfd4ef6 --- /dev/null +++ b/packages/manager/.changeset/pr-13451-fixed-1772457963491.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Fixed +--- + +IAM / Entities & Roles client-side pagination on page refresh ([#13451](https://github.com/linode/manager/pull/13451))