Skip to content

Commit b1bc842

Browse files
authored
Merge pull request #1554 from rocket-admin/backend_dashboards_properties-rework
refactor: move widget properties from dashboard to saved query
2 parents 2aa16e1 + 9dee26e commit b1bc842

24 files changed

+302
-321
lines changed
Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
import sjson from 'secure-json-parse';
2-
import {
3-
AfterLoad,
4-
BeforeInsert,
5-
BeforeUpdate,
6-
Column,
7-
Entity,
8-
JoinColumn,
9-
ManyToOne,
10-
PrimaryGeneratedColumn,
11-
Relation,
12-
} from 'typeorm';
13-
import { DashboardWidgetTypeEnum } from '../../../enums/dashboard-widget-type.enum.js';
1+
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, Relation } from 'typeorm';
142
import { DashboardEntity } from '../dashboard/dashboard.entity.js';
153
import { SavedDbQueryEntity } from '../saved-db-query/saved-db-query.entity.js';
164

@@ -19,18 +7,6 @@ export class DashboardWidgetEntity {
197
@PrimaryGeneratedColumn('uuid')
208
id: string;
219

22-
@Column({ type: 'varchar' })
23-
widget_type: DashboardWidgetTypeEnum;
24-
25-
@Column({ type: 'varchar', default: null, nullable: true })
26-
chart_type: string | null;
27-
28-
@Column({ default: null, nullable: true })
29-
name: string | null;
30-
31-
@Column({ type: 'text', default: null, nullable: true })
32-
description: string | null;
33-
3410
@Column({ type: 'int', default: 0 })
3511
position_x: number;
3612

@@ -43,9 +19,6 @@ export class DashboardWidgetEntity {
4319
@Column({ type: 'int', default: 3 })
4420
height: number;
4521

46-
@Column('json', { default: null, nullable: true })
47-
widget_options: string | null;
48-
4922
@Column({ type: 'uuid' })
5023
dashboard_id: string;
5124

@@ -63,40 +36,4 @@ export class DashboardWidgetEntity {
6336
@ManyToOne(() => SavedDbQueryEntity, { onDelete: 'SET NULL', nullable: true })
6437
@JoinColumn({ name: 'query_id' })
6538
query: Relation<SavedDbQueryEntity> | null;
66-
67-
@BeforeUpdate()
68-
stringifyOptionsOnUpdate(): void {
69-
try {
70-
if (this.widget_options && typeof this.widget_options === 'object') {
71-
this.widget_options = JSON.stringify(this.widget_options);
72-
}
73-
} catch (e) {
74-
console.error('-> Error widget options stringify ' + e.message);
75-
}
76-
}
77-
78-
@BeforeInsert()
79-
stringifyOptions(): void {
80-
try {
81-
if (this.widget_options && typeof this.widget_options === 'object') {
82-
this.widget_options = JSON.stringify(this.widget_options);
83-
}
84-
} catch (e) {
85-
console.error('-> Error widget options stringify ' + e.message);
86-
}
87-
}
88-
89-
@AfterLoad()
90-
parseOptions(): void {
91-
try {
92-
if (this.widget_options && typeof this.widget_options === 'string') {
93-
this.widget_options = sjson.parse(this.widget_options, null, {
94-
protoAction: 'remove',
95-
constructorAction: 'remove',
96-
});
97-
}
98-
} catch (e) {
99-
console.error('-> Error widget options parse ' + e.message);
100-
}
101-
}
10239
}

backend/src/entities/visualizations/dashboard-widget/dashboard-widgets.controller.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,11 @@ export class DashboardWidgetController {
7070
connectionId,
7171
masterPassword: masterPwd,
7272
userId,
73-
widget_type: createDto.widget_type,
74-
chart_type: createDto.chart_type,
75-
name: createDto.name,
76-
description: createDto.description,
73+
query_id: createDto.query_id,
7774
position_x: createDto.position_x,
7875
position_y: createDto.position_y,
7976
width: createDto.width,
8077
height: createDto.height,
81-
widget_options: createDto.widget_options,
82-
query_id: createDto.query_id,
8378
};
8479
return await this.createDashboardWidgetUseCase.execute(inputData, InTransactionEnum.ON);
8580
}
@@ -110,16 +105,11 @@ export class DashboardWidgetController {
110105
connectionId,
111106
masterPassword: masterPwd,
112107
userId,
113-
widget_type: updateDto.widget_type,
114-
chart_type: updateDto.chart_type,
115-
name: updateDto.name,
116-
description: updateDto.description,
108+
query_id: updateDto.query_id,
117109
position_x: updateDto.position_x,
118110
position_y: updateDto.position_y,
119111
width: updateDto.width,
120112
height: updateDto.height,
121-
widget_options: updateDto.widget_options,
122-
query_id: updateDto.query_id,
123113
};
124114
return await this.updateDashboardWidgetUseCase.execute(inputData, InTransactionEnum.ON);
125115
}
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
1-
import { DashboardWidgetTypeEnum } from '../../../../enums/dashboard-widget-type.enum.js';
2-
31
export class CreateDashboardWidgetDs {
42
dashboardId: string;
53
connectionId: string;
64
masterPassword: string;
75
userId: string;
8-
widget_type: DashboardWidgetTypeEnum;
9-
chart_type?: string;
10-
name?: string;
11-
description?: string;
6+
query_id?: string;
127
position_x?: number;
138
position_y?: number;
149
width?: number;
1510
height?: number;
16-
widget_options?: Record<string, unknown>;
17-
query_id?: string;
1811
}
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
1-
import { DashboardWidgetTypeEnum } from '../../../../enums/dashboard-widget-type.enum.js';
2-
31
export class UpdateDashboardWidgetDs {
42
widgetId: string;
53
dashboardId: string;
64
connectionId: string;
75
masterPassword: string;
86
userId: string;
9-
widget_type?: DashboardWidgetTypeEnum;
10-
chart_type?: string;
11-
name?: string;
12-
description?: string;
7+
query_id?: string;
138
position_x?: number;
149
position_y?: number;
1510
width?: number;
1611
height?: number;
17-
widget_options?: Record<string, unknown>;
18-
query_id?: string;
1912
}
Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
1-
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2-
import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString, IsUUID, Max, Min } from 'class-validator';
3-
import { DashboardWidgetTypeEnum } from '../../../../enums/dashboard-widget-type.enum.js';
1+
import { ApiPropertyOptional } from '@nestjs/swagger';
2+
import { IsInt, IsOptional, IsUUID, Max, Min } from 'class-validator';
43

54
export class CreateDashboardWidgetDto {
6-
@ApiProperty({ description: 'Widget type', enum: DashboardWidgetTypeEnum })
7-
@IsNotEmpty()
8-
@IsEnum(DashboardWidgetTypeEnum)
9-
widget_type: DashboardWidgetTypeEnum;
10-
11-
@ApiPropertyOptional({ description: 'Chart type for chart widgets' })
12-
@IsOptional()
13-
@IsString()
14-
chart_type?: string;
15-
16-
@ApiPropertyOptional({ description: 'Widget name' })
17-
@IsOptional()
18-
@IsString()
19-
name?: string;
20-
21-
@ApiPropertyOptional({ description: 'Widget description' })
5+
@ApiPropertyOptional({ description: 'Associated saved query ID' })
226
@IsOptional()
23-
@IsString()
24-
description?: string;
7+
@IsUUID()
8+
query_id?: string;
259

2610
@ApiPropertyOptional({ description: 'Position X in grid', default: 0 })
2711
@IsOptional()
@@ -48,13 +32,4 @@ export class CreateDashboardWidgetDto {
4832
@Min(1)
4933
@Max(12)
5034
height?: number;
51-
52-
@ApiPropertyOptional({ description: 'Visualization options as JSON' })
53-
@IsOptional()
54-
widget_options?: Record<string, unknown>;
55-
56-
@ApiPropertyOptional({ description: 'Associated saved query ID' })
57-
@IsOptional()
58-
@IsUUID()
59-
query_id?: string;
6035
}

backend/src/entities/visualizations/dashboard-widget/dto/found-dashboard-widget.dto.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2-
import { DashboardWidgetTypeEnum } from '../../../../enums/dashboard-widget-type.enum.js';
32

43
export class FoundDashboardWidgetDto {
54
@ApiProperty({ description: 'Widget ID' })
65
id: string;
76

8-
@ApiProperty({ description: 'Widget type', enum: DashboardWidgetTypeEnum })
9-
widget_type: DashboardWidgetTypeEnum;
10-
11-
@ApiPropertyOptional({ description: 'Chart type for chart widgets' })
12-
chart_type: string | null;
13-
14-
@ApiPropertyOptional({ description: 'Widget name' })
15-
name: string | null;
16-
17-
@ApiPropertyOptional({ description: 'Widget description' })
18-
description: string | null;
19-
207
@ApiProperty({ description: 'Position X in grid' })
218
position_x: number;
229

@@ -29,9 +16,6 @@ export class FoundDashboardWidgetDto {
2916
@ApiProperty({ description: 'Widget height in grid units' })
3017
height: number;
3118

32-
@ApiPropertyOptional({ description: 'Visualization options' })
33-
widget_options: Record<string, unknown> | null;
34-
3519
@ApiProperty({ description: 'Dashboard ID' })
3620
dashboard_id: string;
3721

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
import { ApiPropertyOptional } from '@nestjs/swagger';
2-
import { IsEnum, IsInt, IsOptional, IsString, IsUUID, Max, Min } from 'class-validator';
3-
import { DashboardWidgetTypeEnum } from '../../../../enums/dashboard-widget-type.enum.js';
2+
import { IsInt, IsOptional, IsUUID, Max, Min } from 'class-validator';
43

54
export class UpdateDashboardWidgetDto {
6-
@ApiPropertyOptional({ description: 'Widget type', enum: DashboardWidgetTypeEnum })
7-
@IsOptional()
8-
@IsEnum(DashboardWidgetTypeEnum)
9-
widget_type?: DashboardWidgetTypeEnum;
10-
11-
@ApiPropertyOptional({ description: 'Chart type for chart widgets' })
12-
@IsOptional()
13-
@IsString()
14-
chart_type?: string;
15-
16-
@ApiPropertyOptional({ description: 'Widget name' })
17-
@IsOptional()
18-
@IsString()
19-
name?: string;
20-
21-
@ApiPropertyOptional({ description: 'Widget description' })
5+
@ApiPropertyOptional({ description: 'Associated saved query ID' })
226
@IsOptional()
23-
@IsString()
24-
description?: string;
7+
@IsUUID()
8+
query_id?: string;
259

2610
@ApiPropertyOptional({ description: 'Position X in grid' })
2711
@IsOptional()
@@ -48,13 +32,4 @@ export class UpdateDashboardWidgetDto {
4832
@Min(1)
4933
@Max(12)
5034
height?: number;
51-
52-
@ApiPropertyOptional({ description: 'Visualization options as JSON' })
53-
@IsOptional()
54-
widget_options?: Record<string, unknown>;
55-
56-
@ApiPropertyOptional({ description: 'Associated saved query ID' })
57-
@IsOptional()
58-
@IsUUID()
59-
query_id?: string;
6035
}

backend/src/entities/visualizations/dashboard-widget/use-cases/create-dashboard-widget.use.case.ts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,7 @@ export class CreateDashboardWidgetUseCase
2222
}
2323

2424
public async implementation(inputData: CreateDashboardWidgetDs): Promise<FoundDashboardWidgetDto> {
25-
const {
26-
dashboardId,
27-
connectionId,
28-
masterPassword,
29-
widget_type,
30-
chart_type,
31-
name,
32-
description,
33-
position_x,
34-
position_y,
35-
width,
36-
height,
37-
widget_options,
38-
query_id,
39-
} = inputData;
25+
const { dashboardId, connectionId, masterPassword, query_id, position_x, position_y, width, height } = inputData;
4026

4127
const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection(
4228
connectionId,
@@ -68,15 +54,10 @@ export class CreateDashboardWidgetUseCase
6854
}
6955

7056
const newWidget = new DashboardWidgetEntity();
71-
newWidget.widget_type = widget_type;
72-
newWidget.chart_type = chart_type || null;
73-
newWidget.name = name || null;
74-
newWidget.description = description || null;
7557
newWidget.position_x = position_x ?? 0;
7658
newWidget.position_y = position_y ?? 0;
7759
newWidget.width = width ?? 4;
7860
newWidget.height = height ?? 3;
79-
newWidget.widget_options = widget_options ? JSON.stringify(widget_options) : null;
8061
newWidget.dashboard_id = dashboardId;
8162
newWidget.query_id = query_id || null;
8263

backend/src/entities/visualizations/dashboard-widget/use-cases/update-dashboard-widget.use.case.ts

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,8 @@ export class UpdateDashboardWidgetUseCase
2121
}
2222

2323
public async implementation(inputData: UpdateDashboardWidgetDs): Promise<FoundDashboardWidgetDto> {
24-
const {
25-
widgetId,
26-
dashboardId,
27-
connectionId,
28-
masterPassword,
29-
widget_type,
30-
chart_type,
31-
name,
32-
description,
33-
position_x,
34-
position_y,
35-
width,
36-
height,
37-
widget_options,
38-
query_id,
39-
} = inputData;
24+
const { widgetId, dashboardId, connectionId, masterPassword, query_id, position_x, position_y, width, height } =
25+
inputData;
4026

4127
const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection(
4228
connectionId,
@@ -74,20 +60,9 @@ export class UpdateDashboardWidgetUseCase
7460
if (!foundQuery) {
7561
throw new BadRequestException(Messages.SAVED_QUERY_NOT_FOUND);
7662
}
63+
foundWidget.query_id = query_id;
7764
}
7865

79-
if (widget_type !== undefined) {
80-
foundWidget.widget_type = widget_type;
81-
}
82-
if (chart_type !== undefined) {
83-
foundWidget.chart_type = chart_type;
84-
}
85-
if (name !== undefined) {
86-
foundWidget.name = name;
87-
}
88-
if (description !== undefined) {
89-
foundWidget.description = description;
90-
}
9166
if (position_x !== undefined) {
9267
foundWidget.position_x = position_x;
9368
}
@@ -100,12 +75,6 @@ export class UpdateDashboardWidgetUseCase
10075
if (height !== undefined) {
10176
foundWidget.height = height;
10277
}
103-
if (widget_options !== undefined) {
104-
foundWidget.widget_options = widget_options ? JSON.stringify(widget_options) : null;
105-
}
106-
if (query_id !== undefined) {
107-
foundWidget.query_id = query_id;
108-
}
10978

11079
const savedWidget = await this._dbContext.dashboardWidgetRepository.saveWidget(foundWidget);
11180
return buildFoundDashboardWidgetDto(savedWidget);

0 commit comments

Comments
 (0)