feat(SPG-5) Filter
parent
5684bfdcbf
commit
e78d1c90d1
|
@ -0,0 +1,63 @@
|
||||||
|
import { Brackets, SelectQueryBuilder } from 'typeorm';
|
||||||
|
|
||||||
|
export interface Param {
|
||||||
|
cols: string;
|
||||||
|
data: string[];
|
||||||
|
additional?: any[];
|
||||||
|
leftJoin?: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SpecificSearchFilter<Entity = any> {
|
||||||
|
constructor(
|
||||||
|
private query: SelectQueryBuilder<Entity>,
|
||||||
|
private readonly table: string,
|
||||||
|
private readonly params: Param[],
|
||||||
|
) {}
|
||||||
|
|
||||||
|
getFilter() {
|
||||||
|
const params = this.params?.filter((item) => {
|
||||||
|
return item.data !== undefined;
|
||||||
|
});
|
||||||
|
return this.bySearch(this.query, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
bySearch(query: SelectQueryBuilder<Entity>, params: Param[]) {
|
||||||
|
query.andWhere(
|
||||||
|
new Brackets((qb) => {
|
||||||
|
params.forEach((param) => {
|
||||||
|
const { cols, data, additional, leftJoin } = param;
|
||||||
|
|
||||||
|
const arr = data?.map((el) =>
|
||||||
|
el.includes("'")
|
||||||
|
? `'%${el.trim().replace(/'/g, "''").replace(/\s+/g, ' ')}%'`
|
||||||
|
: `'%${el.trim().replace(/\s+/g, ' ')}%'`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const aliases = !cols.match(/\./g)
|
||||||
|
? this.table.concat(`.${cols}`)
|
||||||
|
: cols;
|
||||||
|
|
||||||
|
qb['andWhere'](`${aliases} ILIKE ANY(ARRAY[${arr}])`);
|
||||||
|
|
||||||
|
if (additional?.length > 0) {
|
||||||
|
qb['orWhere'](
|
||||||
|
new Brackets((subQb) => {
|
||||||
|
for (const addition of additional) {
|
||||||
|
subQb['orWhere'](`${addition}`);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftJoin?.length) {
|
||||||
|
for (const join of leftJoin) {
|
||||||
|
qb['leftJoinAndSelect'](`${join.relations}`, `${join.alias}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { ORDER_TYPE, STATUS } from "src/core/strings/constants/base.constants";
|
||||||
|
|
||||||
|
export interface BaseFilterEntity {
|
||||||
|
page: number;
|
||||||
|
limit: number;
|
||||||
|
q?: string;
|
||||||
|
names: string[];
|
||||||
|
entity_ids: string[];
|
||||||
|
order_by: string;
|
||||||
|
order_type: ORDER_TYPE;
|
||||||
|
statuses: STATUS[];
|
||||||
|
created_ids: string[];
|
||||||
|
created_from: number;
|
||||||
|
created_to: number;
|
||||||
|
updated_ids: string[];
|
||||||
|
updated_from: number;
|
||||||
|
updated_to: number;
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import { BaseFilterEntity } from "../../domain/entities/base-filter.entity";
|
||||||
|
import { Transform } from "class-transformer";
|
||||||
|
import { IsArray, IsEnum, IsNumber, IsString, ValidateIf } from "class-validator";
|
||||||
|
import { ORDER_TYPE, STATUS } from "src/core/strings/constants/base.constants";
|
||||||
|
|
||||||
|
export class BaseFilterDto implements BaseFilterEntity {
|
||||||
|
@ApiProperty({ type: Number, required: false, default: 1 })
|
||||||
|
@Transform((body) => Number(body.value))
|
||||||
|
@ValidateIf((body) => body.page)
|
||||||
|
@IsNumber()
|
||||||
|
page = 1;
|
||||||
|
|
||||||
|
@ApiProperty({ type: Number, required: false, default: 10 })
|
||||||
|
@Transform((body) => Number(body.value))
|
||||||
|
@ValidateIf((body) => body.limit)
|
||||||
|
@IsNumber()
|
||||||
|
limit = 10;
|
||||||
|
|
||||||
|
@ApiProperty({ type: String, required: false })
|
||||||
|
q: string;
|
||||||
|
|
||||||
|
@ApiProperty({ type: ['string'], required: false })
|
||||||
|
@Transform((body) => {
|
||||||
|
return Array.isArray(body.value) ? body.value : [body.value];
|
||||||
|
})
|
||||||
|
names: string[];
|
||||||
|
|
||||||
|
@ApiProperty({ type: String, required: false })
|
||||||
|
order_by: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
description: `Select ("${ORDER_TYPE.ASC}", "${ORDER_TYPE.DESC}")`,
|
||||||
|
})
|
||||||
|
@ValidateIf((body) => body.order_type)
|
||||||
|
@IsEnum(ORDER_TYPE, {
|
||||||
|
message: `order_type must be a valid enum ${JSON.stringify(
|
||||||
|
Object.values(ORDER_TYPE),
|
||||||
|
)}`,
|
||||||
|
})
|
||||||
|
order_type: ORDER_TYPE;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: ['string'],
|
||||||
|
required: false,
|
||||||
|
description: `Select ["${STATUS.ACTIVE}"]`,
|
||||||
|
})
|
||||||
|
@Transform((body) => {
|
||||||
|
return Array.isArray(body.value) ? body.value : [body.value];
|
||||||
|
})
|
||||||
|
@ValidateIf((body) => {
|
||||||
|
return body.status;
|
||||||
|
})
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
@IsEnum(STATUS, {
|
||||||
|
message: `Status must be a valid enum ${JSON.stringify(
|
||||||
|
Object.values(STATUS),
|
||||||
|
)}`,
|
||||||
|
each: true,
|
||||||
|
})
|
||||||
|
statuses: STATUS[];
|
||||||
|
|
||||||
|
@ApiProperty({ type: [String], required: false })
|
||||||
|
@Transform((body) => {
|
||||||
|
return Array.isArray(body.value) ? body.value : [body.value];
|
||||||
|
})
|
||||||
|
@ValidateIf((body) => body.created_ids)
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
created_ids: string[];
|
||||||
|
|
||||||
|
@ApiProperty({ type: 'integer', required: false })
|
||||||
|
@ValidateIf((body) => body.created_from)
|
||||||
|
created_from: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: 'integer', required: false })
|
||||||
|
@ValidateIf((body) => body.created_to)
|
||||||
|
created_to: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: [String], required: false })
|
||||||
|
@Transform((body) => {
|
||||||
|
return Array.isArray(body.value) ? body.value : [body.value];
|
||||||
|
})
|
||||||
|
@ValidateIf((body) => body.updated_ids)
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
updated_ids: string[];
|
||||||
|
|
||||||
|
@ApiProperty({ type: 'integer', required: false })
|
||||||
|
@Transform((body) => {
|
||||||
|
return typeof body.value == 'string' ? Number(body.value) : body.value;
|
||||||
|
})
|
||||||
|
@ValidateIf((body) => body.updated_from)
|
||||||
|
updated_from: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: 'integer', required: false })
|
||||||
|
@Transform((body) => {
|
||||||
|
return typeof body.value == 'string' ? Number(body.value) : body.value;
|
||||||
|
})
|
||||||
|
@ValidateIf((body) => body.updated_to)
|
||||||
|
updated_to: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: [String], required: false })
|
||||||
|
@Transform((body) => {
|
||||||
|
return Array.isArray(body.value) ? body.value : [body.value];
|
||||||
|
})
|
||||||
|
@ValidateIf((body) => body.entity_ids)
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
entity_ids: string[];
|
||||||
|
}
|
Loading…
Reference in New Issue