mirror of
https://github.com/Shadowfita/docmost.git
synced 2025-11-12 15:52:32 +10:00
pagination - wip
This commit is contained in:
@ -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)
|
||||
|
||||
@ -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(
|
||||
|
||||
14
apps/server/src/helpers/pagination/paginated-result.ts
Normal file
14
apps/server/src/helpers/pagination/paginated-result.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
29
apps/server/src/helpers/pagination/pagination-meta-dto.ts
Normal file
29
apps/server/src/helpers/pagination/pagination-meta-dto.ts
Normal 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;
|
||||
}
|
||||
23
apps/server/src/helpers/pagination/pagination-options.ts
Normal file
23
apps/server/src/helpers/pagination/pagination-options.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,7 @@ async function bootstrap() {
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
stopAtFirstError: true,
|
||||
transform: true,
|
||||
}),
|
||||
);
|
||||
app.enableCors();
|
||||
|
||||
Reference in New Issue
Block a user