From 71eba56830a8272b981facc4b8238c760fef7f35 Mon Sep 17 00:00:00 2001 From: Sourav Jaiswal Date: Wed, 28 Jan 2026 00:33:57 +0530 Subject: [PATCH 1/2] Fetch next user batch if more users are present and current view has not loaded all user --- .../src/clients/changesetClient.ts | 12 +++-- .../ManageVersions/ManageVersions.test.tsx | 2 +- .../ManageVersions/ManageVersions.tsx | 52 ++++++++++++++----- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/packages/modules/manage-versions/src/clients/changesetClient.ts b/packages/modules/manage-versions/src/clients/changesetClient.ts index 78cb1a31..d6d2fa84 100644 --- a/packages/modules/manage-versions/src/clients/changesetClient.ts +++ b/packages/modules/manage-versions/src/clients/changesetClient.ts @@ -43,13 +43,16 @@ export class ChangesetClient { .then((resp) => resp.changesets); } - public async getUsers(imodelId: string): Promise { + public async getUsers( + imodelId: string, + requestOptions: RequestOptions = {} + ): Promise<{ users: User[]; hasMore: boolean }> { return this._http .get( `${UrlBuilder.buildGetUsersUrl( imodelId, this._serverEnvironmentPrefix - )}`, + )}${UrlBuilder.getQuery(requestOptions)}`, { headers: { [HttpHeaderNames.Prefer]: "return=representation", @@ -58,7 +61,10 @@ export class ChangesetClient { }, } ) - .then((resp) => resp.users); + .then((resp) => ({ + users: resp.users, + hasMore: !!resp._links?.next?.href, + })); } public async getChangesetCheckpoint( diff --git a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx index 69947e1a..63d76661 100644 --- a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx +++ b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.test.tsx @@ -65,7 +65,7 @@ describe("ManageVersions", () => { jest.clearAllMocks(); mockGetVersions.mockResolvedValue(MockedVersionList()); mockGetChangesets.mockResolvedValue(MockedChangesetList()); - mockGetUsers.mockResolvedValue(MockedUsers()); + mockGetUsers.mockResolvedValue({ users: MockedUsers(), hasMore: false }); }); it("should show versions table with data", async () => { diff --git a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx index 079ca716..c4b9091a 100644 --- a/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx +++ b/packages/modules/manage-versions/src/components/ManageVersions/ManageVersions.tsx @@ -111,6 +111,7 @@ export enum ManageVersionsTabs { const NAMED_VERSION_TOP = 100; const CHANGESET_TOP = 100; +const USERS_TOP = 100; const initialChangeset: Changeset = { id: "", @@ -231,18 +232,26 @@ const ManageVersionsComponent = (props: ManageVersionsProps) => { const usersRef = React.useRef<{ [key: string]: string } | undefined>( undefined ); + const hasMoreUsersRef = React.useRef(true); - const getUsers = React.useCallback(async () => { - const users = await changesetClient.getUsers(imodelId); - const userMapData = users.reduce((acc, user) => { - const userFullName = [user.givenName, user.surname].filter(Boolean); - acc[user.id] = userFullName.length - ? userFullName.join(" ") - : user.displayName; - return acc; - }, {} as { [key: string]: string }); - usersRef.current = userMapData; - }, [changesetClient, imodelId]); + const getUsers = React.useCallback( + async (skip?: number) => { + const { users, hasMore } = await changesetClient.getUsers(imodelId, { + top: USERS_TOP, + skip, + }); + const userMapData = users.reduce((acc, user) => { + const userFullName = [user.givenName, user.surname].filter(Boolean); + acc[user.id] = userFullName.length + ? userFullName.join(" ") + : user.displayName; + return acc; + }, {} as { [key: string]: string }); + usersRef.current = { ...usersRef.current, ...userMapData }; + hasMoreUsersRef.current = hasMore; + }, + [changesetClient, imodelId] + ); React.useEffect(() => { setCurrentTab(currentTab); @@ -446,9 +455,26 @@ const ManageVersionsComponent = (props: ManageVersionsProps) => { React.useEffect(() => { const loadUsers = async () => { - await getUsers(); + if (!hasMoreUsersRef.current) { + return; + } + + if (!usersRef.current) { + hasMoreUsersRef.current = false; + await getUsers(); + } else { + const hasMissingUsers = + versionsTableData?.some((td) => !td.version.createdBy) || + changesets?.some((cs) => !cs.createdBy); + + if (hasMissingUsers) { + hasMoreUsersRef.current = false; + await getUsers(Object.keys(usersRef.current).length); + } + } }; - if (!usersRef.current) { + + if (!usersRef.current || versionsTableData || changesets) { loadUsers() .then(() => { const updatedVersionsTableData = versionsTableData?.map((td) => { From 0998ccae0018c2d6442b0a684d65bc268710edbd Mon Sep 17 00:00:00 2001 From: Sourav Jaiswal Date: Wed, 28 Jan 2026 00:42:18 +0530 Subject: [PATCH 2/2] Add changelog --- .../sj-fix-users-fetch_2026-01-27-19-11.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@itwin/manage-versions-react/sj-fix-users-fetch_2026-01-27-19-11.json diff --git a/common/changes/@itwin/manage-versions-react/sj-fix-users-fetch_2026-01-27-19-11.json b/common/changes/@itwin/manage-versions-react/sj-fix-users-fetch_2026-01-27-19-11.json new file mode 100644 index 00000000..aaad602a --- /dev/null +++ b/common/changes/@itwin/manage-versions-react/sj-fix-users-fetch_2026-01-27-19-11.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/manage-versions-react", + "comment": "Fetch next user batch if current view has user that are not fetched yet.", + "type": "patch" + } + ], + "packageName": "@itwin/manage-versions-react" +}