Skip to content

Commit cd3f3ac

Browse files
Merge branch 'main' into fixes
2 parents d0ceaa7 + 45927f5 commit cd3f3ac

27 files changed

Lines changed: 729 additions & 176 deletions

backend/src/common/data-injection.tokens.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,6 @@ export enum UseCaseType {
189189
CREATE_TABLE_FILTERS = 'CREATE_TABLE_FILTERS',
190190
FIND_TABLE_FILTERS = 'FIND_TABLE_FILTERS',
191191
DELETE_TABLE_FILTERS = 'DELETE_TABLE_FILTERS',
192+
FIND_TABLE_FILTER_BY_ID = 'FIND_TABLE_FILTER_BY_ID',
193+
DELETE_TABLE_FILTER_BY_ID = 'DELETE_TABLE_FILTER_BY_ID',
192194
}

backend/src/decorators/slug-uuid.decorator.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export type SlugUuidParameter =
1313
| 'eventId'
1414
| 'apiKeyId'
1515
| 'companyId'
16-
| 'threadId';
16+
| 'threadId'
17+
| 'filterId';
1718
export const SlugUuid = createParamDecorator(
1819
(parameterName: SlugUuidParameter = 'slug', ctx: ExecutionContext): string => {
1920
const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest();
@@ -28,6 +29,7 @@ export const SlugUuid = createParamDecorator(
2829
'eventId',
2930
'companyId',
3031
'threadId',
32+
'filterId'
3133
];
3234
if (!availableSlagParameters.includes(parameterName)) {
3335
throw new BadRequestException(Messages.UUID_INVALID);
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
export class CreateTableFiltersDto {
1+
import { FilterCriteriaEnum } from '../../../../enums/filter-criteria.enum.js';
2+
3+
export class DynamicTableFiltersDs {
4+
column_name: string;
5+
comparator: FilterCriteriaEnum;
6+
}
7+
export class CreateTableFilterDs {
28
table_name: string;
39
connection_id: string;
410
filters: Record<string, any>;
511
masterPwd: string;
12+
filter_name: string;
13+
dynamic_filtered_column: DynamicTableFiltersDs | null;
614
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
export class FindTableFiltersDs {
22
table_name: string;
33
connection_id: string;
4+
}
5+
6+
export class FindTableFilterByIdDs {
7+
filter_id: string;
8+
connection_id: string;
49
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsObject, IsOptional, IsString, MaxLength, MinLength, ValidateNested } from 'class-validator';
3+
import { FilterCriteriaEnum } from '../../../../enums/filter-criteria.enum.js';
4+
5+
export class DynamicTableFilterDto {
6+
@ApiProperty({ type: 'string' })
7+
@IsString()
8+
@MinLength(1)
9+
@MaxLength(255)
10+
column_name: string;
11+
12+
@ApiProperty({ enum: FilterCriteriaEnum })
13+
comparator: FilterCriteriaEnum;
14+
}
15+
16+
export class CreateTableFilterDto {
17+
@ApiProperty({ type: 'string' })
18+
@IsString()
19+
@MinLength(1)
20+
@MaxLength(255)
21+
name: string;
22+
23+
@ApiProperty({
24+
type: 'object',
25+
properties: {
26+
id: {
27+
type: 'object',
28+
properties: {
29+
eq: { type: 'number' },
30+
},
31+
},
32+
name: {
33+
type: 'object',
34+
properties: {
35+
startswith: { type: 'string' },
36+
},
37+
},
38+
age: {
39+
type: 'object',
40+
properties: {
41+
gt: { type: 'number' },
42+
lt: { type: 'number' },
43+
},
44+
},
45+
},
46+
example: {
47+
id: {
48+
eq: 1,
49+
},
50+
name: {
51+
startswith: 'A',
52+
},
53+
age: {
54+
gt: 18,
55+
lt: 30,
56+
},
57+
},
58+
})
59+
@IsObject()
60+
filters: Record<string, unknown>;
61+
62+
@ApiProperty({ type: DynamicTableFilterDto, required: false })
63+
@IsOptional()
64+
@ValidateNested()
65+
dynamic_column: DynamicTableFilterDto;
66+
}
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { ApiProperty } from '@nestjs/swagger';
2+
import { CreateTableFilterDto } from './create-table-filters.dto.js';
23

3-
export class CreatedTableFiltersRO {
4-
@ApiProperty()
4+
export class CreatedTableFilterRO extends CreateTableFilterDto {
5+
@ApiProperty({ type: 'string' })
56
id: string;
67

7-
@ApiProperty()
8-
tableName: string;
8+
@ApiProperty({ type: 'string' })
9+
table_name: string;
910

10-
@ApiProperty()
11-
connectionId: string;
11+
@ApiProperty({ type: Date })
12+
createdAt: Date;
1213

13-
@ApiProperty({ type: Object })
14-
filters: Record<string, any>;
14+
@ApiProperty({ type: Date })
15+
updatedAt: Date;
1516
}

backend/src/entities/table-filters/repository/table-filters-custom-repository-extension.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,25 @@ import { TableFiltersEntity } from '../table-filters.entity.js';
22
import { ITableFiltersCustomRepository } from './table-filters-custom-repository.interface.js';
33

44
export const tableFiltersCustomRepositoryExtension: ITableFiltersCustomRepository = {
5-
async findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise<TableFiltersEntity> {
5+
async findTableFiltersForTableInConnection(
6+
tableName: string,
7+
connectionId: string,
8+
): Promise<Array<TableFiltersEntity>> {
69
const qb = this.createQueryBuilder('table_filters')
710
.leftJoin('table_filters.connection', 'connection')
811
.where('table_filters.table_name = :tableName', { tableName: tableName })
912
.andWhere('connection.id = :connectionId', { connectionId: connectionId });
13+
return await qb.getMany();
14+
},
15+
16+
async findTableFiltersByIdAndConnectionId(
17+
filterId: string,
18+
connectionId: string,
19+
): Promise<TableFiltersEntity> {
20+
const qb = this.createQueryBuilder('table_filters')
21+
.leftJoin('table_filters.connection', 'connection')
22+
.where('table_filters.id = :filterId', { filterId: filterId })
23+
.andWhere('connection.id = :connectionId', { connectionId: connectionId });
1024
return await qb.getOne();
1125
},
1226
};
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { TableFiltersEntity } from '../table-filters.entity.js';
22

33
export interface ITableFiltersCustomRepository {
4-
findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise<TableFiltersEntity>;
4+
findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise<Array<TableFiltersEntity>>;
5+
6+
findTableFiltersByIdAndConnectionId(filterId: string, connectionId: string): Promise<TableFiltersEntity>;
57
}

backend/src/entities/table-filters/table-filters.controller.ts

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ import { Messages } from '../../exceptions/text/messages.js';
2020
import { ConnectionEditGuard } from '../../guards/connection-edit.guard.js';
2121
import { ConnectionReadGuard } from '../../guards/connection-read.guard.js';
2222
import { SentryInterceptor } from '../../interceptors/index.js';
23-
import { FindAllRowsWithBodyFiltersDto } from '../table/dto/find-rows-with-body-filters.dto.js';
24-
import { CreateTableFiltersDto } from './application/data-structures/create-table-filters.ds.js';
25-
import { FindTableFiltersDs } from './application/data-structures/find-table-filters.ds.js';
26-
import { CreatedTableFiltersRO } from './application/response-objects/created-table-filters.ro.js';
23+
import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js';
24+
import { CreateTableFilterDs } from './application/data-structures/create-table-filters.ds.js';
25+
import { FindTableFilterByIdDs, FindTableFiltersDs } from './application/data-structures/find-table-filters.ds.js';
26+
import { CreateTableFilterDto } from './application/response-objects/create-table-filters.dto.js';
27+
import { CreatedTableFilterRO } from './application/response-objects/created-table-filters.ro.js';
2728
import {
2829
ICreateTableFilters,
30+
IDeleteTableFilterById,
2931
IDeleteTableFilters,
32+
IFindTableFilterById,
3033
IFindTableFilters,
3134
} from './use-cases/table-filters-use-cases.interface.js';
3235

@@ -43,55 +46,61 @@ export class TableFiltersController {
4346
private readonly findTableFiltersUseCase: IFindTableFilters,
4447
@Inject(UseCaseType.DELETE_TABLE_FILTERS)
4548
private readonly deleteTableFiltersUseCase: IDeleteTableFilters,
49+
@Inject(UseCaseType.FIND_TABLE_FILTER_BY_ID)
50+
private readonly findTableFilterByIdUseCase: IFindTableFilterById,
51+
@Inject(UseCaseType.DELETE_TABLE_FILTER_BY_ID)
52+
private readonly deleteTableFilterByIdUseCase: IDeleteTableFilterById,
4653
) {}
4754

48-
@ApiOperation({ summary: 'Add new table filters' })
49-
@ApiBody({ type: FindAllRowsWithBodyFiltersDto })
55+
@ApiOperation({ summary: 'Add new table filters object' })
56+
@ApiBody({ type: CreateTableFilterDto })
5057
@ApiResponse({
5158
status: 201,
5259
description: 'Table filters created.',
53-
type: CreatedTableFiltersRO,
60+
type: CreatedTableFilterRO,
5461
})
5562
@ApiQuery({ name: 'tableName', required: true })
5663
@ApiParam({ name: 'connectionId', required: true })
5764
@UseGuards(ConnectionEditGuard)
5865
@Post('/:connectionId')
5966
async addTableFilters(
6067
@QueryTableName() tableName: string,
61-
@Body() body: FindAllRowsWithBodyFiltersDto,
68+
@Body() body: CreateTableFilterDto,
6269
@SlugUuid('connectionId') connectionId: string,
6370
@MasterPassword() masterPwd: string,
64-
): Promise<CreatedTableFiltersRO> {
71+
): Promise<CreatedTableFilterRO> {
6572
if (!tableName) {
6673
throw new BadRequestException(Messages.TABLE_NAME_MISSING);
6774
}
6875
if (!body.filters) {
6976
throw new BadRequestException(Messages.FILTERS_MISSING);
7077
}
71-
const inputData: CreateTableFiltersDto = {
78+
const inputData: CreateTableFilterDs = {
7279
table_name: tableName,
7380
connection_id: connectionId,
7481
filters: body.filters,
7582
masterPwd: masterPwd,
83+
filter_name: body.name,
84+
dynamic_filtered_column: body.dynamic_column ?? null,
7685
};
7786
return await this.createTableFiltersUseCase.execute(inputData, InTransactionEnum.ON);
7887
}
7988

80-
@ApiOperation({ summary: 'Find table filters' })
81-
@ApiBody({ type: FindAllRowsWithBodyFiltersDto })
89+
@ApiOperation({ summary: 'Find all table filters' })
8290
@ApiResponse({
8391
status: 200,
8492
description: 'Table filters found.',
85-
type: CreatedTableFiltersRO,
93+
type: CreatedTableFilterRO,
94+
isArray: true,
8695
})
8796
@ApiQuery({ name: 'tableName', required: true })
8897
@ApiParam({ name: 'connectionId', required: true })
8998
@UseGuards(ConnectionReadGuard)
90-
@Get('/:connectionId')
99+
@Get('/:connectionId/all')
91100
async findTableFilters(
92101
@QueryTableName() tableName: string,
93102
@SlugUuid('connectionId') connectionId: string,
94-
): Promise<CreatedTableFiltersRO> {
103+
): Promise<Array<CreatedTableFilterRO>> {
95104
if (!tableName) {
96105
throw new BadRequestException(Messages.TABLE_NAME_MISSING);
97106
}
@@ -102,21 +111,42 @@ export class TableFiltersController {
102111
return await this.findTableFiltersUseCase.execute(inputData, InTransactionEnum.OFF);
103112
}
104113

105-
@ApiOperation({ summary: 'Delete table filters' })
106-
@ApiBody({ type: FindAllRowsWithBodyFiltersDto })
114+
@ApiOperation({ summary: 'Find table filter set by id' })
107115
@ApiResponse({
108116
status: 200,
109-
description: 'Table filters Deleted.',
110-
type: CreatedTableFiltersRO,
117+
description: 'Table filter found.',
118+
type: CreatedTableFilterRO,
119+
isArray: true,
120+
})
121+
@ApiParam({ name: 'connectionId', required: true })
122+
@ApiParam({ name: 'filterId', required: true })
123+
@UseGuards(ConnectionReadGuard)
124+
@Get('/:connectionId/:filterId')
125+
async findTableFilterById(
126+
@SlugUuid('connectionId') connectionId: string,
127+
@SlugUuid('filterId') filterId: string,
128+
): Promise<CreatedTableFilterRO> {
129+
const inputData: FindTableFilterByIdDs = {
130+
filter_id: filterId,
131+
connection_id: connectionId,
132+
};
133+
return await this.findTableFilterByIdUseCase.execute(inputData, InTransactionEnum.OFF);
134+
}
135+
136+
@ApiOperation({ summary: 'Delete table all filters for table' })
137+
@ApiResponse({
138+
status: 200,
139+
description: 'All table filters deleted.',
140+
type: SuccessResponse,
111141
})
112142
@ApiQuery({ name: 'tableName', required: true })
113143
@ApiParam({ name: 'connectionId', required: true })
114144
@UseGuards(ConnectionEditGuard)
115-
@Delete('/:connectionId')
145+
@Delete('/:connectionId/all')
116146
async deleteTableFilters(
117147
@QueryTableName() tableName: string,
118148
@SlugUuid('connectionId') connectionId: string,
119-
): Promise<CreatedTableFiltersRO> {
149+
): Promise<SuccessResponse> {
120150
if (!tableName) {
121151
throw new BadRequestException(Messages.TABLE_NAME_MISSING);
122152
}
@@ -126,4 +156,25 @@ export class TableFiltersController {
126156
};
127157
return await this.deleteTableFiltersUseCase.execute(inputData, InTransactionEnum.OFF);
128158
}
159+
160+
@ApiOperation({ summary: 'Delete filter set by id' })
161+
@ApiResponse({
162+
status: 200,
163+
description: 'Table filter set deleted.',
164+
type: SuccessResponse,
165+
})
166+
@ApiParam({ name: 'connectionId', required: true })
167+
@ApiParam({ name: 'filterId', required: true })
168+
@UseGuards(ConnectionEditGuard)
169+
@Delete('/:connectionId/:filterId')
170+
async deleteTableFiltersById(
171+
@SlugUuid('connectionId') connectionId: string,
172+
@SlugUuid('filterId') filterId: string,
173+
): Promise<SuccessResponse> {
174+
const inputData: FindTableFilterByIdDs = {
175+
filter_id: filterId,
176+
connection_id: connectionId,
177+
};
178+
return await this.deleteTableFilterByIdUseCase.execute(inputData, InTransactionEnum.ON);
179+
}
129180
}

0 commit comments

Comments
 (0)