Skip to content

Commit

Permalink
Merge pull request #70 from ti-broish/add-users-filters
Browse files Browse the repository at this point in the history
  • Loading branch information
hkdobrev authored Jun 30, 2021
2 parents 90b98f6 + abf2b18 commit 6201030
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 20 deletions.
41 changes: 41 additions & 0 deletions src/users/api/users-filters.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Type } from 'class-transformer';
import {
IsIn,
IsInt,
IsOptional,
IsString,
Length,
Min,
} from 'class-validator';
import { Role } from 'src/casl/role.enum';
import { IsOrganizationExists } from 'src/users/api/organization-exists.constraint';
import { PageDTO } from 'src/utils/page.dto';

export class UsersFilters extends PageDTO {
@IsOptional()
@IsString()
@Length(1, 255)
firstName: string;

@IsOptional()
@IsString()
@Length(1, 255)
lastName: string;

@IsOptional()
@IsString()
@Length(1, 255)
email: string;

@IsOptional()
@IsInt()
@Type(() => Number)
@Min(1)
@IsOrganizationExists()
organization: number;

@IsOptional()
@IsString()
@IsIn(Object.values(Role))
role: string;
}
23 changes: 15 additions & 8 deletions src/users/api/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { User } from '../entities';
import { UsersRepository } from '../entities/users.repository';
import RegistrationService, { RegistrationError } from './registration.service';
import { UserDto } from './user.dto';
import { UsersFilters } from './users-filters.dto';

@Controller('users')
export class UsersController {
Expand Down Expand Up @@ -91,15 +92,21 @@ export class UsersController {
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: Ability) => ability.can(Action.Manage, User))
@UsePipes(new ValidationPipe({ transform: true }))
async index(@Query() query: PageDTO): Promise<Pagination<User>> {
const pagination = await paginate(this.repo.getRepo(), {
page: query.page,
limit: 20,
route: '/users',
});
pagination.items.map((user: User) => UserDto.fromEntity(user));
async index(@Query() query: UsersFilters): Promise<Pagination<UserDto>> {
const pagination = await paginate(
this.repo.queryBuilderWithFilters(query),
{
page: query.page,
limit: 20,
route: '/users',
},
);

const items = pagination.items.map((user: User) =>
UserDto.fromEntity(user, [UserDto.ADMIN_READ]),
);

return pagination;
return new Pagination<UserDto>(items, pagination.meta, pagination.links);
}

@Patch(':id')
Expand Down
36 changes: 35 additions & 1 deletion src/users/entities/users.repository.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Repository, SelectQueryBuilder } from 'typeorm';
import { User } from './user.entity';
import { UsersFilters } from '../api/users-filters.dto';

@Injectable()
export class UsersRepository {
Expand Down Expand Up @@ -40,6 +41,39 @@ export class UsersRepository {
return this.repo.find();
}

queryBuilderWithFilters(filters: UsersFilters): SelectQueryBuilder<User> {
const qb = this.repo.createQueryBuilder('people');

qb.innerJoinAndSelect('people.organization', 'organization');
const { firstName, lastName, email, organization, role } = filters;

if (firstName) {
qb.andWhere('people.firstName LIKE :firstName', {
firstName: `%${firstName}%`,
});
}

if (lastName) {
qb.andWhere('people.lastName LIKE :lastName', {
lastName: `%${lastName}%`,
});
}

if (email) {
qb.andWhere('people.email LIKE :email', { email: `%${email}%` });
}

if (organization) {
qb.andWhere('organization.id = :organization', { organization });
}

if (role) {
qb.andWhere('people.roles::jsonb ? :role', { role });
}

return qb;
}

async save(user: User): Promise<User> {
return await this.repo.save(user);
}
Expand Down
27 changes: 16 additions & 11 deletions src/violations/api/violations.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,23 @@ export class ViolationsController {
{ page: query.page, limit: 100, route: '/violations' },
);

const processViolation = async (violation: Violation) => {
const dto = ViolationDto.fromEntity(violation, [
'violation.process',
UserDto.AUTHOR_READ,
]);
this.updatePicturesUrl(dto);

return dto;
};

const promises: Promise<ViolationDto>[] = pagination.items.map(
processViolation,
);
const violationDtoItems = await Promise.all(promises);

return new Pagination<ViolationDto>(
await Promise.all(
pagination.items.map(async (violation: Violation) => {
const dto = ViolationDto.fromEntity(violation, [
'violation.process',
UserDto.AUTHOR_READ,
]);
this.updatePicturesUrl(dto);

return dto;
}),
),
violationDtoItems,
pagination.meta,
pagination.links,
);
Expand Down

0 comments on commit 6201030

Please sign in to comment.