diff --git a/app/components/Collaborators.tsx b/app/components/Collaborators.tsx index a67ac265d..a58c9340b 100644 --- a/app/components/Collaborators.tsx +++ b/app/components/Collaborators.tsx @@ -52,18 +52,14 @@ function Collaborators(props: Props) { // load any users we don't yet have in memory React.useEffect(() => { - const userIdsToFetch = uniq([ - ...document.collaboratorIds, - ...presentIds, - ]).filter((userId) => !users.get(userId)); + const ids = uniq([...document.collaboratorIds, ...presentIds]) + .filter((userId) => !users.get(userId)) + .sort(); - if (!isEqual(requestedUserIds, userIdsToFetch)) { - setRequestedUserIds(userIdsToFetch); + if (!isEqual(requestedUserIds, ids) && ids.length > 0) { + setRequestedUserIds(ids); + users.fetchPage({ ids, limit: 100 }); } - - userIdsToFetch - .filter((userId) => requestedUserIds.includes(userId)) - .forEach((userId) => users.fetch(userId)); }, [document, users, presentIds, document.collaboratorIds, requestedUserIds]); const popover = usePopoverState({ diff --git a/app/stores/BaseStore.ts b/app/stores/BaseStore.ts index c858d3a1d..6d4cfbc79 100644 --- a/app/stores/BaseStore.ts +++ b/app/stores/BaseStore.ts @@ -19,11 +19,7 @@ export enum RPCAction { Count = "count", } -type FetchPageParams = PaginationParams & { - documentId?: string; - query?: string; - filter?: string; -}; +type FetchPageParams = PaginationParams & Record; function modelNameFromClassName(string: string) { return string.charAt(0).toLowerCase() + string.slice(1); diff --git a/server/routes/api/users.test.ts b/server/routes/api/users.test.ts index ac86dedf3..ff0db93e5 100644 --- a/server/routes/api/users.test.ts +++ b/server/routes/api/users.test.ts @@ -87,6 +87,20 @@ describe("#users.list", () => { expect(body.data[1].id).toEqual(admin.id); }); + it("should allow filtering by id", async () => { + const { admin, user } = await seed(); + const res = await server.post("/api/users.list", { + body: { + token: admin.getJwtToken(), + ids: [user.id], + }, + }); + const body = await res.json(); + expect(res.status).toEqual(200); + expect(body.data.length).toEqual(1); + expect(body.data[0].id).toEqual(user.id); + }); + it("should require admin for detailed info", async () => { const { user, admin } = await seed(); const res = await server.post("/api/users.list", { diff --git a/server/routes/api/users.ts b/server/routes/api/users.ts index c5ebbba5c..8d53795b2 100644 --- a/server/routes/api/users.ts +++ b/server/routes/api/users.ts @@ -19,7 +19,7 @@ const router = new Router(); router.post("users.list", auth(), pagination(), async (ctx) => { let { direction } = ctx.body; - const { sort = "createdAt", query, filter } = ctx.body; + const { sort = "createdAt", query, filter, ids } = ctx.body; if (direction !== "ASC") { direction = "DESC"; } @@ -88,6 +88,14 @@ router.post("users.list", auth(), pagination(), async (ctx) => { }; } + if (ids) { + assertArray(ids, "ids must be an array of UUIDs"); + where = { + ...where, + id: ids, + }; + } + const [users, total] = await Promise.all([ User.findAll({ where,