pagination - wip

This commit is contained in:
Philipinho
2024-02-28 16:36:41 +00:00
parent 299f682a3b
commit 41ecf2d082
6 changed files with 102 additions and 16 deletions

View File

@ -1,11 +1,14 @@
import {
Body,
Controller,
DefaultValuePipe,
Delete,
Get,
HttpCode,
HttpStatus,
ParseIntPipe,
Post,
Query,
UseGuards,
} from '@nestjs/common';
import { WorkspaceService } from '../services/workspace.service';
@ -20,9 +23,10 @@ import { AuthUser } from '../../../decorators/auth-user.decorator';
import { User } from '../../user/entities/user.entity';
import { CurrentWorkspace } from '../../../decorators/current-workspace.decorator';
import { Workspace } from '../entities/workspace.entity';
import { PaginationOptions } from '../../../helpers/pagination/pagination-options';
@UseGuards(JwtGuard)
@Controller('workspace')
@Controller('workspaces')
export class WorkspaceController {
constructor(private readonly workspaceService: WorkspaceService) {}
@ -51,9 +55,13 @@ export class WorkspaceController {
}
@HttpCode(HttpStatus.OK)
@Get('members')
async getWorkspaceMembers(@CurrentWorkspace() workspace: Workspace) {
return this.workspaceService.getWorkspaceUsers(workspace.id);
@Post('members')
async getWorkspaceMembers(
@Body()
pagination: PaginationOptions,
@CurrentWorkspace() workspace: Workspace,
) {
return this.workspaceService.getWorkspaceUsers(workspace.id, pagination);
}
@HttpCode(HttpStatus.OK)

View File

@ -15,6 +15,10 @@ import { UpdateWorkspaceDto } from '../dto/update-workspace.dto';
import { DeleteWorkspaceDto } from '../dto/delete-workspace.dto';
import { UpdateWorkspaceUserRoleDto } from '../dto/update-workspace-user-role.dto';
import { SpaceService } from '../../space/space.service';
import { UserWithRole } from '../../user/entities/user.entity';
import { PaginationOptions } from '../../../helpers/pagination/pagination-options';
import { PaginationMetaDto } from '../../../helpers/pagination/pagination-meta-dto';
import { PaginatedResult } from '../../../helpers/pagination/paginated-result';
@Injectable()
export class WorkspaceService {
@ -209,25 +213,32 @@ export class WorkspaceService {
);
}
async getWorkspaceUsers(workspaceId: string) {
const workspace = await this.workspaceRepository.findOne({
where: { id: workspaceId },
relations: ['workspaceUsers', 'workspaceUsers.user'],
async getWorkspaceUsers(
workspaceId: string,
paginationOptions: PaginationOptions,
): Promise<PaginatedResult<any>> {
const [workspaceUsers, count] =
await this.workspaceUserRepository.findAndCount({
relations: ['user'],
where: {
workspace: {
id: workspaceId,
},
},
take: paginationOptions.limit,
skip: paginationOptions.skip,
});
if (!workspace) {
throw new BadRequestException('Invalid workspace');
}
const users = workspace.workspaceUsers.map((workspaceUser) => {
const users = workspaceUsers.map((workspaceUser) => {
workspaceUser.user.password = '';
return {
...workspaceUser.user,
workspaceRole: workspaceUser.role,
role: workspaceUser.role,
};
});
return { users };
const paginationMeta = new PaginationMetaDto({ count, paginationOptions });
return new PaginatedResult(users, paginationMeta);
}
async validateWorkspaceMember(

View File

@ -0,0 +1,14 @@
import { IsArray } from 'class-validator';
import { PaginationMetaDto } from './pagination-meta-dto';
export class PaginatedResult<T> {
@IsArray()
readonly items: T[];
readonly pagination: PaginationMetaDto;
constructor(items: T[], pagination: PaginationMetaDto) {
this.items = items;
this.pagination = pagination;
}
}

View File

@ -0,0 +1,29 @@
import { PaginationOptions } from './pagination-options';
export class PaginationMetaDto {
readonly page: number;
readonly limit: number;
readonly total: number;
readonly pageCount: number;
readonly hasPreviousPage: boolean;
readonly hasNextPage: boolean;
constructor({ count, paginationOptions }: PageMetaDtoParameters) {
this.page = paginationOptions.page;
this.limit = paginationOptions.limit;
this.total = count;
this.pageCount = Math.ceil(this.total / this.limit);
this.hasPreviousPage = this.page > 1;
this.hasNextPage = this.page < this.pageCount;
}
}
export interface PageMetaDtoParameters {
count: number;
paginationOptions: PaginationOptions;
}

View File

@ -0,0 +1,23 @@
import { IsNumber, IsOptional, IsPositive, Max, Min } from 'class-validator';
export class PaginationOptions {
@IsOptional()
@IsNumber()
@Min(1)
page = 1;
@IsOptional()
@IsNumber()
@IsPositive()
@Min(1)
@Max(100)
limit = 25;
@IsOptional()
@IsNumber()
offset = 0;
get skip(): number {
return (this.page - 1) * this.limit;
}
}

View File

@ -25,6 +25,7 @@ async function bootstrap() {
new ValidationPipe({
whitelist: true,
stopAtFirstError: true,
transform: true,
}),
);
app.enableCors();