Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/src/common/data-injection.tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,6 @@ export enum UseCaseType {
CREATE_TABLE_FILTERS = 'CREATE_TABLE_FILTERS',
FIND_TABLE_FILTERS = 'FIND_TABLE_FILTERS',
DELETE_TABLE_FILTERS = 'DELETE_TABLE_FILTERS',
FIND_TABLE_FILTER_BY_ID = 'FIND_TABLE_FILTER_BY_ID',
DELETE_TABLE_FILTER_BY_ID = 'DELETE_TABLE_FILTER_BY_ID',
}
4 changes: 3 additions & 1 deletion backend/src/decorators/slug-uuid.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export type SlugUuidParameter =
| 'eventId'
| 'apiKeyId'
| 'companyId'
| 'threadId';
| 'threadId'
| 'filterId';
export const SlugUuid = createParamDecorator(
(parameterName: SlugUuidParameter = 'slug', ctx: ExecutionContext): string => {
const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest();
Expand All @@ -28,6 +29,7 @@ export const SlugUuid = createParamDecorator(
'eventId',
'companyId',
'threadId',
'filterId'
];
if (!availableSlagParameters.includes(parameterName)) {
throw new BadRequestException(Messages.UUID_INVALID);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
export class CreateTableFiltersDto {
import { FilterCriteriaEnum } from '../../../../enums/filter-criteria.enum.js';

export class DynamicTableFiltersDs {
column_name: string;
comparator: FilterCriteriaEnum;
}
export class CreateTableFilterDs {
table_name: string;
connection_id: string;
filters: Record<string, any>;
masterPwd: string;
filter_name: string;
dynamic_filtered_column: DynamicTableFiltersDs | null;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export class FindTableFiltersDs {
table_name: string;
connection_id: string;
}

export class FindTableFilterByIdDs {
filter_id: string;
connection_id: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsObject, IsOptional, IsString, MaxLength, MinLength, ValidateNested } from 'class-validator';
import { FilterCriteriaEnum } from '../../../../enums/filter-criteria.enum.js';

export class DynamicTableFilterDto {
@ApiProperty({ type: 'string' })
@IsString()
@MinLength(1)
@MaxLength(255)
column_name: string;

@ApiProperty({ enum: FilterCriteriaEnum })
comparator: FilterCriteriaEnum;
}

export class CreateTableFilterDto {
@ApiProperty({ type: 'string' })
@IsString()
@MinLength(1)
@MaxLength(255)
name: string;

@ApiProperty({
type: 'object',
properties: {
id: {
type: 'object',
properties: {
eq: { type: 'number' },
},
},
name: {
type: 'object',
properties: {
startswith: { type: 'string' },
},
},
age: {
type: 'object',
properties: {
gt: { type: 'number' },
lt: { type: 'number' },
},
},
},
example: {
id: {
eq: 1,
},
name: {
startswith: 'A',
},
age: {
gt: 18,
lt: 30,
},
},
})
@IsObject()
filters: Record<string, unknown>;

@ApiProperty({ type: DynamicTableFilterDto, required: false })
@IsOptional()
@ValidateNested()
dynamic_column: DynamicTableFilterDto;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { ApiProperty } from '@nestjs/swagger';
import { CreateTableFilterDto } from './create-table-filters.dto.js';

export class CreatedTableFiltersRO {
@ApiProperty()
export class CreatedTableFilterRO extends CreateTableFilterDto {
@ApiProperty({ type: 'string' })
id: string;

@ApiProperty()
tableName: string;
@ApiProperty({ type: 'string' })
table_name: string;

@ApiProperty()
connectionId: string;
@ApiProperty({ type: Date })
createdAt: Date;

@ApiProperty({ type: Object })
filters: Record<string, any>;
@ApiProperty({ type: Date })
updatedAt: Date;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,25 @@ import { TableFiltersEntity } from '../table-filters.entity.js';
import { ITableFiltersCustomRepository } from './table-filters-custom-repository.interface.js';

export const tableFiltersCustomRepositoryExtension: ITableFiltersCustomRepository = {
async findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise<TableFiltersEntity> {
async findTableFiltersForTableInConnection(
tableName: string,
connectionId: string,
): Promise<Array<TableFiltersEntity>> {
const qb = this.createQueryBuilder('table_filters')
.leftJoin('table_filters.connection', 'connection')
.where('table_filters.table_name = :tableName', { tableName: tableName })
.andWhere('connection.id = :connectionId', { connectionId: connectionId });
return await qb.getMany();
},

async findTableFiltersByIdAndConnectionId(
filterId: string,
connectionId: string,
): Promise<TableFiltersEntity> {
const qb = this.createQueryBuilder('table_filters')
.leftJoin('table_filters.connection', 'connection')
.where('table_filters.id = :filterId', { filterId: filterId })
.andWhere('connection.id = :connectionId', { connectionId: connectionId });
return await qb.getOne();
},
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { TableFiltersEntity } from '../table-filters.entity.js';

export interface ITableFiltersCustomRepository {
findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise<TableFiltersEntity>;
findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise<Array<TableFiltersEntity>>;

findTableFiltersByIdAndConnectionId(filterId: string, connectionId: string): Promise<TableFiltersEntity>;
}
93 changes: 72 additions & 21 deletions backend/src/entities/table-filters/table-filters.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ import { Messages } from '../../exceptions/text/messages.js';
import { ConnectionEditGuard } from '../../guards/connection-edit.guard.js';
import { ConnectionReadGuard } from '../../guards/connection-read.guard.js';
import { SentryInterceptor } from '../../interceptors/index.js';
import { FindAllRowsWithBodyFiltersDto } from '../table/dto/find-rows-with-body-filters.dto.js';
import { CreateTableFiltersDto } from './application/data-structures/create-table-filters.ds.js';
import { FindTableFiltersDs } from './application/data-structures/find-table-filters.ds.js';
import { CreatedTableFiltersRO } from './application/response-objects/created-table-filters.ro.js';
import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js';
import { CreateTableFilterDs } from './application/data-structures/create-table-filters.ds.js';
import { FindTableFilterByIdDs, FindTableFiltersDs } from './application/data-structures/find-table-filters.ds.js';
import { CreateTableFilterDto } from './application/response-objects/create-table-filters.dto.js';
import { CreatedTableFilterRO } from './application/response-objects/created-table-filters.ro.js';
import {
ICreateTableFilters,
IDeleteTableFilterById,
IDeleteTableFilters,
IFindTableFilterById,
IFindTableFilters,
} from './use-cases/table-filters-use-cases.interface.js';

Expand All @@ -43,55 +46,61 @@ export class TableFiltersController {
private readonly findTableFiltersUseCase: IFindTableFilters,
@Inject(UseCaseType.DELETE_TABLE_FILTERS)
private readonly deleteTableFiltersUseCase: IDeleteTableFilters,
@Inject(UseCaseType.FIND_TABLE_FILTER_BY_ID)
private readonly findTableFilterByIdUseCase: IFindTableFilterById,
@Inject(UseCaseType.DELETE_TABLE_FILTER_BY_ID)
private readonly deleteTableFilterByIdUseCase: IDeleteTableFilterById,
) {}

@ApiOperation({ summary: 'Add new table filters' })
@ApiBody({ type: FindAllRowsWithBodyFiltersDto })
@ApiOperation({ summary: 'Add new table filters object' })
@ApiBody({ type: CreateTableFilterDto })
@ApiResponse({
status: 201,
description: 'Table filters created.',
type: CreatedTableFiltersRO,
type: CreatedTableFilterRO,
})
@ApiQuery({ name: 'tableName', required: true })
@ApiParam({ name: 'connectionId', required: true })
@UseGuards(ConnectionEditGuard)
@Post('/:connectionId')
async addTableFilters(
@QueryTableName() tableName: string,
@Body() body: FindAllRowsWithBodyFiltersDto,
@Body() body: CreateTableFilterDto,
@SlugUuid('connectionId') connectionId: string,
@MasterPassword() masterPwd: string,
): Promise<CreatedTableFiltersRO> {
): Promise<CreatedTableFilterRO> {
if (!tableName) {
throw new BadRequestException(Messages.TABLE_NAME_MISSING);
}
if (!body.filters) {
throw new BadRequestException(Messages.FILTERS_MISSING);
}
const inputData: CreateTableFiltersDto = {
const inputData: CreateTableFilterDs = {
table_name: tableName,
connection_id: connectionId,
filters: body.filters,
masterPwd: masterPwd,
filter_name: body.name,
dynamic_filtered_column: body.dynamic_column ?? null,
};
return await this.createTableFiltersUseCase.execute(inputData, InTransactionEnum.ON);
}

@ApiOperation({ summary: 'Find table filters' })
@ApiBody({ type: FindAllRowsWithBodyFiltersDto })
@ApiOperation({ summary: 'Find all table filters' })
@ApiResponse({
status: 200,
description: 'Table filters found.',
type: CreatedTableFiltersRO,
type: CreatedTableFilterRO,
isArray: true,
})
@ApiQuery({ name: 'tableName', required: true })
@ApiParam({ name: 'connectionId', required: true })
@UseGuards(ConnectionReadGuard)
@Get('/:connectionId')
@Get('/:connectionId/all')
async findTableFilters(
@QueryTableName() tableName: string,
@SlugUuid('connectionId') connectionId: string,
): Promise<CreatedTableFiltersRO> {
): Promise<Array<CreatedTableFilterRO>> {
if (!tableName) {
throw new BadRequestException(Messages.TABLE_NAME_MISSING);
}
Expand All @@ -102,21 +111,42 @@ export class TableFiltersController {
return await this.findTableFiltersUseCase.execute(inputData, InTransactionEnum.OFF);
}

@ApiOperation({ summary: 'Delete table filters' })
@ApiBody({ type: FindAllRowsWithBodyFiltersDto })
@ApiOperation({ summary: 'Find table filter set by id' })
@ApiResponse({
status: 200,
description: 'Table filters Deleted.',
type: CreatedTableFiltersRO,
description: 'Table filter found.',
type: CreatedTableFilterRO,
isArray: true,
})
@ApiParam({ name: 'connectionId', required: true })
@ApiParam({ name: 'filterId', required: true })
@UseGuards(ConnectionReadGuard)
@Get('/:connectionId/:filterId')
async findTableFilterById(
@SlugUuid('connectionId') connectionId: string,
@SlugUuid('filterId') filterId: string,
): Promise<CreatedTableFilterRO> {
const inputData: FindTableFilterByIdDs = {
filter_id: filterId,
connection_id: connectionId,
};
return await this.findTableFilterByIdUseCase.execute(inputData, InTransactionEnum.OFF);
}

@ApiOperation({ summary: 'Delete table all filters for table' })
@ApiResponse({
status: 200,
description: 'All table filters deleted.',
type: SuccessResponse,
})
@ApiQuery({ name: 'tableName', required: true })
@ApiParam({ name: 'connectionId', required: true })
@UseGuards(ConnectionEditGuard)
@Delete('/:connectionId')
@Delete('/:connectionId/all')
async deleteTableFilters(
@QueryTableName() tableName: string,
@SlugUuid('connectionId') connectionId: string,
): Promise<CreatedTableFiltersRO> {
): Promise<SuccessResponse> {
if (!tableName) {
throw new BadRequestException(Messages.TABLE_NAME_MISSING);
}
Expand All @@ -126,4 +156,25 @@ export class TableFiltersController {
};
return await this.deleteTableFiltersUseCase.execute(inputData, InTransactionEnum.OFF);
}

@ApiOperation({ summary: 'Delete filter set by id' })
@ApiResponse({
status: 200,
description: 'Table filter set deleted.',
type: SuccessResponse,
})
@ApiParam({ name: 'connectionId', required: true })
@ApiParam({ name: 'filterId', required: true })
@UseGuards(ConnectionEditGuard)
@Delete('/:connectionId/:filterId')
async deleteTableFiltersById(
@SlugUuid('connectionId') connectionId: string,
@SlugUuid('filterId') filterId: string,
): Promise<SuccessResponse> {
const inputData: FindTableFilterByIdDs = {
filter_id: filterId,
connection_id: connectionId,
};
return await this.deleteTableFilterByIdUseCase.execute(inputData, InTransactionEnum.ON);
}
}
Loading