From 88bca2057abe1fffa6d777b6c4f24b0ff4ff21a6 Mon Sep 17 00:00:00 2001 From: mirarifhasan Date: Thu, 25 Jan 2024 16:22:30 +0600 Subject: [PATCH] feat: added pagination on fetchInvitedUsers --- .../src/admin/admin.resolver.ts | 9 --------- .../src/admin/admin.service.spec.ts | 11 +++++++++-- .../src/admin/admin.service.ts | 8 +++++++- .../src/admin/infra.resolver.ts | 15 +++++++++++---- .../src/types/input-types.args.ts | 18 ++++++++++++++++++ 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/packages/hoppscotch-backend/src/admin/admin.resolver.ts b/packages/hoppscotch-backend/src/admin/admin.resolver.ts index 0894fdd4d..d9fd5bde7 100644 --- a/packages/hoppscotch-backend/src/admin/admin.resolver.ts +++ b/packages/hoppscotch-backend/src/admin/admin.resolver.ts @@ -89,15 +89,6 @@ export class AdminResolver { return users; } - @ResolveField(() => [InvitedUser], { - description: 'Returns a list of all the invited users', - deprecationReason: 'Use `infra` query instead', - }) - async invitedUsers(@Parent() admin: Admin): Promise { - const users = await this.adminService.fetchInvitedUsers(); - return users; - } - @ResolveField(() => [Team], { description: 'Returns a list of all the teams in the infra', deprecationReason: 'Use `infra` query instead', diff --git a/packages/hoppscotch-backend/src/admin/admin.service.spec.ts b/packages/hoppscotch-backend/src/admin/admin.service.spec.ts index 0c0be2f5e..66b8f7186 100644 --- a/packages/hoppscotch-backend/src/admin/admin.service.spec.ts +++ b/packages/hoppscotch-backend/src/admin/admin.service.spec.ts @@ -18,6 +18,7 @@ import { } from '../errors'; import { ShortcodeService } from 'src/shortcode/shortcode.service'; import { ConfigService } from '@nestjs/config'; +import { OffsetPaginationArgs } from 'src/types/input-types.args'; const mockPrisma = mockDeep(); const mockPubSub = mockDeep(); @@ -62,17 +63,23 @@ const invitedUsers: InvitedUsers[] = [ describe('AdminService', () => { describe('fetchInvitedUsers', () => { test('should resolve right and return an array of invited users', async () => { + const paginationArgs: OffsetPaginationArgs = { take: 10, skip: 0 }; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore + mockPrisma.user.findMany.mockResolvedValue([]); + // @ts-ignore mockPrisma.invitedUsers.findMany.mockResolvedValue(invitedUsers); - const results = await adminService.fetchInvitedUsers(); + const results = await adminService.fetchInvitedUsers(paginationArgs); expect(results).toEqual(invitedUsers); }); test('should resolve left and return an empty array if invited users not found', async () => { + const paginationArgs: OffsetPaginationArgs = { take: 10, skip: 0 }; + mockPrisma.invitedUsers.findMany.mockResolvedValue([]); - const results = await adminService.fetchInvitedUsers(); + const results = await adminService.fetchInvitedUsers(paginationArgs); expect(results).toEqual([]); }); }); diff --git a/packages/hoppscotch-backend/src/admin/admin.service.ts b/packages/hoppscotch-backend/src/admin/admin.service.ts index e2409a657..6ba983a12 100644 --- a/packages/hoppscotch-backend/src/admin/admin.service.ts +++ b/packages/hoppscotch-backend/src/admin/admin.service.ts @@ -27,6 +27,7 @@ import { TeamInvitationService } from '../team-invitation/team-invitation.servic import { TeamMemberRole } from '../team/team.model'; import { ShortcodeService } from 'src/shortcode/shortcode.service'; import { ConfigService } from '@nestjs/config'; +import { OffsetPaginationArgs } from 'src/types/input-types.args'; @Injectable() export class AdminService { @@ -144,7 +145,7 @@ export class AdminService { * Fetch the list of invited users by the admin. * @returns an Either of array of `InvitedUser` object or error */ - async fetchInvitedUsers() { + async fetchInvitedUsers(paginationOption: OffsetPaginationArgs) { const userEmailObjs = await this.prisma.user.findMany({ select: { email: true, @@ -152,6 +153,11 @@ export class AdminService { }); const pendingInvitedUsers = await this.prisma.invitedUsers.findMany({ + take: paginationOption.take, + skip: paginationOption.skip, + orderBy: { + invitedOn: 'desc', + }, where: { NOT: { inviteeEmail: { diff --git a/packages/hoppscotch-backend/src/admin/infra.resolver.ts b/packages/hoppscotch-backend/src/admin/infra.resolver.ts index 1ba557660..348ec6cf5 100644 --- a/packages/hoppscotch-backend/src/admin/infra.resolver.ts +++ b/packages/hoppscotch-backend/src/admin/infra.resolver.ts @@ -17,7 +17,10 @@ import { AuthUser } from 'src/types/AuthUser'; import { throwErr } from 'src/utils'; import * as E from 'fp-ts/Either'; import { Admin } from './admin.model'; -import { PaginationArgs } from 'src/types/input-types.args'; +import { + OffsetPaginationArgs, + PaginationArgs, +} from 'src/types/input-types.args'; import { InvitedUser } from './invited-user.model'; import { Team } from 'src/team/team.model'; import { TeamInvitation } from 'src/team-invitation/team-invitation.model'; @@ -86,8 +89,10 @@ export class InfraResolver { @ResolveField(() => [InvitedUser], { description: 'Returns a list of all the invited users', }) - async invitedUsers(): Promise { - const users = await this.adminService.fetchInvitedUsers(); + async invitedUsers( + @Args() args: OffsetPaginationArgs, + ): Promise { + const users = await this.adminService.fetchInvitedUsers(args); return users; } @@ -306,7 +311,9 @@ export class InfraResolver { }) providerInfo: EnableAndDisableSSOArgs[], ) { - const isUpdated = await this.infraConfigService.enableAndDisableSSO(providerInfo); + const isUpdated = await this.infraConfigService.enableAndDisableSSO( + providerInfo, + ); if (E.isLeft(isUpdated)) throwErr(isUpdated.left); return true; diff --git a/packages/hoppscotch-backend/src/types/input-types.args.ts b/packages/hoppscotch-backend/src/types/input-types.args.ts index 3e3f4d49f..14a324997 100644 --- a/packages/hoppscotch-backend/src/types/input-types.args.ts +++ b/packages/hoppscotch-backend/src/types/input-types.args.ts @@ -17,3 +17,21 @@ export class PaginationArgs { }) take: number; } + +@ArgsType() +@InputType() +export class OffsetPaginationArgs { + @Field({ + nullable: true, + defaultValue: 0, + description: 'Number of items to skip', + }) + skip: number; + + @Field({ + nullable: true, + defaultValue: 10, + description: 'Number of items to fetch', + }) + take: number; +}