@hed-hog/core 0.0.163 → 0.0.166
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/dashboard/dashboard.controller.d.ts +13 -1
- package/dist/dashboard/dashboard/dashboard.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard/dashboard.controller.js +3 -4
- package/dist/dashboard/dashboard/dashboard.controller.js.map +1 -1
- package/dist/dashboard/dashboard/dashboard.service.d.ts +14 -4
- package/dist/dashboard/dashboard/dashboard.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard/dashboard.service.js +20 -10
- package/dist/dashboard/dashboard/dashboard.service.js.map +1 -1
- package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +15 -0
- package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +15 -2
- package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dashboard-component.service.js +25 -2
- package/dist/dashboard/dashboard-component/dashboard-component.service.js.map +1 -1
- package/dist/dashboard/dashboard-component/dto/create.dto.d.ts +4 -0
- package/dist/dashboard/dashboard-component/dto/create.dto.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dto/create.dto.js +15 -0
- package/dist/dashboard/dashboard-component/dto/create.dto.js.map +1 -1
- package/dist/dashboard/dashboard-component/dto/update.dto.d.ts +4 -0
- package/dist/dashboard/dashboard-component/dto/update.dto.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dto/update.dto.js +15 -0
- package/dist/dashboard/dashboard-component/dto/update.dto.js.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +27 -8
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.controller.js +8 -6
- package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +27 -8
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.service.js +98 -46
- package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
- package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts +3 -0
- package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts +3 -0
- package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-item/dto/index.d.ts +2 -0
- package/dist/dashboard/dashboard-item/dto/index.d.ts.map +1 -1
- package/dist/dashboard/dashboard-item/dto/index.js +4 -1
- package/dist/dashboard/dashboard-item/dto/index.js.map +1 -1
- package/dist/dashboard/dashboard-item/dto/update-layout.dto.d.ts +12 -0
- package/dist/dashboard/dashboard-item/dto/update-layout.dto.d.ts.map +1 -0
- package/dist/dashboard/dashboard-item/dto/update-layout.dto.js +52 -0
- package/dist/dashboard/dashboard-item/dto/update-layout.dto.js.map +1 -0
- package/hedhog/data/menu.yaml +28 -4
- package/hedhog/query/add-description-to-dashboard-component-locale.sql +99 -0
- package/hedhog/query/add-widget-metadata.sql +21 -0
- package/hedhog/query/fix-dashboard-stat-keys.sql +82 -0
- package/package.json +4 -4
- package/src/dashboard/dashboard/dashboard.controller.ts +2 -2
- package/src/dashboard/dashboard/dashboard.service.ts +25 -9
- package/src/dashboard/dashboard-component/dashboard-component.service.ts +30 -3
- package/src/dashboard/dashboard-component/dto/create.dto.ts +13 -1
- package/src/dashboard/dashboard-component/dto/update.dto.ts +13 -1
- package/src/dashboard/dashboard-core/dashboard-core.controller.ts +4 -2
- package/src/dashboard/dashboard-core/dashboard-core.service.ts +103 -49
- package/src/dashboard/dashboard-item/dashboard-item.service.ts +4 -4
- package/src/dashboard/dashboard-item/dto/index.ts +2 -0
- package/src/dashboard/dashboard-item/dto/update-layout.dto.ts +30 -0
|
@@ -29,11 +29,7 @@ export class DashboardCoreService {
|
|
|
29
29
|
const now = new Date();
|
|
30
30
|
const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
31
31
|
const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
|
|
32
|
-
|
|
33
|
-
// Total de usuários
|
|
34
32
|
const totalUsers = await this.prismaService.user.count();
|
|
35
|
-
|
|
36
|
-
// Usuários criados nos últimos 7 dias
|
|
37
33
|
const recentUsers = await this.prismaService.user.count({
|
|
38
34
|
where: {
|
|
39
35
|
created_at: {
|
|
@@ -42,7 +38,6 @@ export class DashboardCoreService {
|
|
|
42
38
|
},
|
|
43
39
|
});
|
|
44
40
|
|
|
45
|
-
// Usuários ativos (criados nos últimos 30 dias como aproximação)
|
|
46
41
|
const activeUsers = await this.prismaService.user.count({
|
|
47
42
|
where: {
|
|
48
43
|
created_at: {
|
|
@@ -51,14 +46,12 @@ export class DashboardCoreService {
|
|
|
51
46
|
},
|
|
52
47
|
});
|
|
53
48
|
|
|
54
|
-
// Total de roles
|
|
55
49
|
const totalRoles = await this.prismaService.role.count();
|
|
56
|
-
|
|
57
|
-
// Total de menus
|
|
58
50
|
const totalMenus = await this.prismaService.menu.count();
|
|
59
|
-
|
|
60
|
-
// Total de rotas
|
|
61
51
|
const totalRoutes = await this.prismaService.route.count();
|
|
52
|
+
const totalModules = await this.prismaService.dashboard_component.count();
|
|
53
|
+
const totalSettings = await this.prismaService.setting.count();
|
|
54
|
+
const totalContacts = await this.prismaService.person.count().catch(() => 0);
|
|
62
55
|
|
|
63
56
|
return {
|
|
64
57
|
totalUsers,
|
|
@@ -67,14 +60,15 @@ export class DashboardCoreService {
|
|
|
67
60
|
totalRoles,
|
|
68
61
|
totalMenus,
|
|
69
62
|
totalRoutes,
|
|
63
|
+
totalModules,
|
|
64
|
+
totalSettings,
|
|
65
|
+
totalContacts,
|
|
70
66
|
};
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
async getUserGrowth() {
|
|
74
70
|
const now = new Date();
|
|
75
71
|
const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
|
|
76
|
-
|
|
77
|
-
// Contagem de usuários criados por dia nos últimos 30 dias
|
|
78
72
|
const usersByDay = await this.prismaService.$queryRaw<
|
|
79
73
|
Array<{ date: Date; count: bigint }>
|
|
80
74
|
>`
|
|
@@ -91,39 +85,65 @@ export class DashboardCoreService {
|
|
|
91
85
|
}));
|
|
92
86
|
}
|
|
93
87
|
|
|
94
|
-
async getUserLayout(userId: number, slug: string) {
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
async getUserLayout(userId: number, slug: string, localeCode: string) {
|
|
89
|
+
const dashboard = await this.prismaService.dashboard.findFirst({
|
|
90
|
+
where: { slug },
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (!dashboard) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const userWidgets = await this.prismaService.dashboard_user.findMany({
|
|
97
98
|
where: {
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
user_id: userId,
|
|
100
|
+
dashboard_item: {
|
|
101
|
+
dashboard_id: dashboard.id,
|
|
100
102
|
},
|
|
101
103
|
},
|
|
102
104
|
include: {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
dashboard_item: {
|
|
106
|
+
include: {
|
|
107
|
+
dashboard_component: {
|
|
108
|
+
include: {
|
|
109
|
+
dashboard_component_locale: {
|
|
110
|
+
where: {
|
|
111
|
+
locale: {
|
|
112
|
+
code: localeCode,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
106
118
|
},
|
|
107
119
|
},
|
|
108
|
-
dashboard_component: true,
|
|
109
120
|
},
|
|
110
121
|
});
|
|
111
122
|
|
|
112
|
-
return
|
|
113
|
-
const
|
|
123
|
+
return userWidgets.map((userWidget) => {
|
|
124
|
+
const item = userWidget.dashboard_item;
|
|
125
|
+
const component = item.dashboard_component as any;
|
|
126
|
+
const locale = component.dashboard_component_locale?.[0];
|
|
127
|
+
|
|
114
128
|
return {
|
|
115
129
|
i: `widget-${item.id}`,
|
|
116
130
|
component_id: item.component_id,
|
|
117
|
-
slug:
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
slug: component.slug,
|
|
132
|
+
name: locale?.name || component.slug,
|
|
133
|
+
description: locale?.description || '',
|
|
134
|
+
path: component.path,
|
|
135
|
+
icon: component.icon || null,
|
|
136
|
+
stat_key: component.stat_key || null,
|
|
137
|
+
color: component.color || null,
|
|
138
|
+
x: userWidget.x_axis,
|
|
139
|
+
y: userWidget.y_axis,
|
|
140
|
+
w: userWidget.width,
|
|
141
|
+
h: userWidget.height,
|
|
142
|
+
minW: component.min_width,
|
|
143
|
+
maxW: component.max_width,
|
|
144
|
+
minH: component.min_height,
|
|
145
|
+
maxH: component.max_height,
|
|
146
|
+
isResizable: component.is_resizable ?? true,
|
|
127
147
|
};
|
|
128
148
|
});
|
|
129
149
|
}
|
|
@@ -139,7 +159,6 @@ export class DashboardCoreService {
|
|
|
139
159
|
h: number;
|
|
140
160
|
}>,
|
|
141
161
|
) {
|
|
142
|
-
// Busca o dashboard
|
|
143
162
|
const dashboard = await this.prismaService.dashboard.findFirst({
|
|
144
163
|
where: { slug },
|
|
145
164
|
});
|
|
@@ -148,12 +167,8 @@ export class DashboardCoreService {
|
|
|
148
167
|
throw new Error(`Dashboard with slug '${slug}' not found`);
|
|
149
168
|
}
|
|
150
169
|
|
|
151
|
-
// Para cada item do layout, salva ou atualiza o dashboard_user
|
|
152
170
|
for (const item of layout) {
|
|
153
|
-
// Extrai o ID do item do identificador
|
|
154
171
|
const itemId = parseInt(item.i.replace('widget-', ''));
|
|
155
|
-
|
|
156
|
-
// Verifica se o item existe
|
|
157
172
|
const dashboardItem = await this.prismaService.dashboard_item.findFirst({
|
|
158
173
|
where: {
|
|
159
174
|
id: itemId,
|
|
@@ -165,7 +180,6 @@ export class DashboardCoreService {
|
|
|
165
180
|
continue;
|
|
166
181
|
}
|
|
167
182
|
|
|
168
|
-
// Busca se já existe um dashboard_user para este item e usuário
|
|
169
183
|
const existingUserLayout =
|
|
170
184
|
await this.prismaService.dashboard_user.findFirst({
|
|
171
185
|
where: {
|
|
@@ -175,7 +189,6 @@ export class DashboardCoreService {
|
|
|
175
189
|
});
|
|
176
190
|
|
|
177
191
|
if (existingUserLayout) {
|
|
178
|
-
// Atualiza o layout existente
|
|
179
192
|
await this.prismaService.dashboard_user.update({
|
|
180
193
|
where: {
|
|
181
194
|
id: existingUserLayout.id,
|
|
@@ -188,7 +201,6 @@ export class DashboardCoreService {
|
|
|
188
201
|
},
|
|
189
202
|
});
|
|
190
203
|
} else {
|
|
191
|
-
// Cria um novo layout de usuário
|
|
192
204
|
await this.prismaService.dashboard_user.create({
|
|
193
205
|
data: {
|
|
194
206
|
item_id: itemId,
|
|
@@ -209,8 +221,8 @@ export class DashboardCoreService {
|
|
|
209
221
|
userId: number,
|
|
210
222
|
slug: string,
|
|
211
223
|
componentSlug: string,
|
|
224
|
+
localeCode: string,
|
|
212
225
|
) {
|
|
213
|
-
// Busca o dashboard
|
|
214
226
|
const dashboard = await this.prismaService.dashboard.findFirst({
|
|
215
227
|
where: { slug },
|
|
216
228
|
});
|
|
@@ -219,16 +231,23 @@ export class DashboardCoreService {
|
|
|
219
231
|
throw new Error(`Dashboard with slug '${slug}' not found`);
|
|
220
232
|
}
|
|
221
233
|
|
|
222
|
-
// Busca o componente
|
|
223
234
|
const component = await this.prismaService.dashboard_component.findFirst({
|
|
224
235
|
where: { slug: componentSlug },
|
|
236
|
+
include: {
|
|
237
|
+
dashboard_component_locale: {
|
|
238
|
+
where: {
|
|
239
|
+
locale: {
|
|
240
|
+
code: localeCode,
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
},
|
|
225
245
|
});
|
|
226
246
|
|
|
227
247
|
if (!component) {
|
|
228
248
|
throw new Error(`Component with slug '${componentSlug}' not found`);
|
|
229
249
|
}
|
|
230
250
|
|
|
231
|
-
// Verifica se já existe um item para este componente no dashboard
|
|
232
251
|
let dashboardItem = await this.prismaService.dashboard_item.findFirst({
|
|
233
252
|
where: {
|
|
234
253
|
dashboard_id: dashboard.id,
|
|
@@ -236,7 +255,6 @@ export class DashboardCoreService {
|
|
|
236
255
|
},
|
|
237
256
|
});
|
|
238
257
|
|
|
239
|
-
// Se não existe, cria um novo item
|
|
240
258
|
if (!dashboardItem) {
|
|
241
259
|
dashboardItem = await this.prismaService.dashboard_item.create({
|
|
242
260
|
data: {
|
|
@@ -250,7 +268,37 @@ export class DashboardCoreService {
|
|
|
250
268
|
});
|
|
251
269
|
}
|
|
252
270
|
|
|
253
|
-
|
|
271
|
+
const existingUserWidget = await this.prismaService.dashboard_user.findFirst({
|
|
272
|
+
where: {
|
|
273
|
+
item_id: dashboardItem.id,
|
|
274
|
+
user_id: userId,
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
if (existingUserWidget) {
|
|
279
|
+
throw new Error('Widget already added to dashboard');
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const maxYWidget = await this.prismaService.dashboard_user.findFirst({
|
|
283
|
+
where: {
|
|
284
|
+
user_id: userId,
|
|
285
|
+
dashboard_item: {
|
|
286
|
+
dashboard_id: dashboard.id,
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
orderBy: {
|
|
290
|
+
y_axis: 'desc',
|
|
291
|
+
},
|
|
292
|
+
include: {
|
|
293
|
+
dashboard_item: true,
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
let newY = 0;
|
|
298
|
+
if (maxYWidget) {
|
|
299
|
+
newY = maxYWidget.y_axis + maxYWidget.height;
|
|
300
|
+
}
|
|
301
|
+
|
|
254
302
|
const userLayout = await this.prismaService.dashboard_user.create({
|
|
255
303
|
data: {
|
|
256
304
|
item_id: dashboardItem.id,
|
|
@@ -258,14 +306,22 @@ export class DashboardCoreService {
|
|
|
258
306
|
width: component.width,
|
|
259
307
|
height: component.height,
|
|
260
308
|
x_axis: 0,
|
|
261
|
-
y_axis:
|
|
309
|
+
y_axis: newY,
|
|
262
310
|
},
|
|
263
311
|
});
|
|
264
312
|
|
|
313
|
+
const locale = (component as any).dashboard_component_locale?.[0];
|
|
314
|
+
|
|
265
315
|
return {
|
|
266
316
|
i: `widget-${dashboardItem.id}`,
|
|
267
317
|
component_id: component.id,
|
|
268
318
|
slug: component.slug,
|
|
319
|
+
name: locale?.name || component.slug,
|
|
320
|
+
description: locale?.description || '',
|
|
321
|
+
path: component.path,
|
|
322
|
+
icon: (component as any).icon || null,
|
|
323
|
+
stat_key: (component as any).stat_key || null,
|
|
324
|
+
color: (component as any).color || null,
|
|
269
325
|
x: userLayout.x_axis,
|
|
270
326
|
y: userLayout.y_axis,
|
|
271
327
|
w: userLayout.width,
|
|
@@ -284,8 +340,6 @@ export class DashboardCoreService {
|
|
|
284
340
|
widgetId: string,
|
|
285
341
|
) {
|
|
286
342
|
const itemId = parseInt(widgetId.replace('widget-', ''));
|
|
287
|
-
|
|
288
|
-
// Remove o dashboard_user
|
|
289
343
|
await this.prismaService.dashboard_user.deleteMany({
|
|
290
344
|
where: {
|
|
291
345
|
item_id: itemId,
|
|
@@ -2,10 +2,10 @@ import { getLocaleText, LocaleService } from '@hed-hog/api-locale';
|
|
|
2
2
|
import { PaginationService } from '@hed-hog/api-pagination';
|
|
3
3
|
import { PrismaService } from '@hed-hog/api-prisma';
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
forwardRef,
|
|
6
|
+
Inject,
|
|
7
|
+
Injectable,
|
|
8
|
+
NotFoundException
|
|
9
9
|
} from '@nestjs/common';
|
|
10
10
|
import { CreateDashboardItemDTO } from './dto';
|
|
11
11
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './create.dto';
|
|
2
|
+
export * from './update-layout.dto';
|
|
2
3
|
export * from './update.dto';
|
|
3
4
|
|
|
4
5
|
// Aliases para compatibilidade
|
|
5
6
|
export { CreateDTO as CreateDashboardItemDTO } from './create.dto';
|
|
7
|
+
export { UpdateDashboardLayoutDTO } from './update-layout.dto';
|
|
6
8
|
export { UpdateDTO as UpdateDashboardItemDTO } from './update.dto';
|
|
7
9
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getLocaleText } from '@hed-hog/api-locale';
|
|
2
|
+
import { Type } from 'class-transformer';
|
|
3
|
+
import { IsArray, IsNumber, ValidateNested } from 'class-validator';
|
|
4
|
+
|
|
5
|
+
export class DashboardItemLayoutDTO {
|
|
6
|
+
@IsNumber({}, { message: (args) => getLocaleText('validation.numberRequired', args.value) })
|
|
7
|
+
id: number;
|
|
8
|
+
|
|
9
|
+
@IsNumber({}, { message: (args) => getLocaleText('validation.numberRequired', args.value) })
|
|
10
|
+
width: number;
|
|
11
|
+
|
|
12
|
+
@IsNumber({}, { message: (args) => getLocaleText('validation.numberRequired', args.value) })
|
|
13
|
+
height: number;
|
|
14
|
+
|
|
15
|
+
@IsNumber({}, { message: (args) => getLocaleText('validation.numberRequired', args.value) })
|
|
16
|
+
x_axis: number;
|
|
17
|
+
|
|
18
|
+
@IsNumber({}, { message: (args) => getLocaleText('validation.numberRequired', args.value) })
|
|
19
|
+
y_axis: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class UpdateDashboardLayoutDTO {
|
|
23
|
+
@IsNumber({}, { message: (args) => getLocaleText('validation.numberRequired', args.value) })
|
|
24
|
+
dashboard_id: number;
|
|
25
|
+
|
|
26
|
+
@IsArray({ message: (args) => getLocaleText('validation.arrayRequired', args.value) })
|
|
27
|
+
@ValidateNested({ each: true })
|
|
28
|
+
@Type(() => DashboardItemLayoutDTO)
|
|
29
|
+
items: DashboardItemLayoutDTO[];
|
|
30
|
+
}
|