@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.
Files changed (57) hide show
  1. package/dist/dashboard/dashboard/dashboard.controller.d.ts +13 -1
  2. package/dist/dashboard/dashboard/dashboard.controller.d.ts.map +1 -1
  3. package/dist/dashboard/dashboard/dashboard.controller.js +3 -4
  4. package/dist/dashboard/dashboard/dashboard.controller.js.map +1 -1
  5. package/dist/dashboard/dashboard/dashboard.service.d.ts +14 -4
  6. package/dist/dashboard/dashboard/dashboard.service.d.ts.map +1 -1
  7. package/dist/dashboard/dashboard/dashboard.service.js +20 -10
  8. package/dist/dashboard/dashboard/dashboard.service.js.map +1 -1
  9. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +15 -0
  10. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts.map +1 -1
  11. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +15 -2
  12. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts.map +1 -1
  13. package/dist/dashboard/dashboard-component/dashboard-component.service.js +25 -2
  14. package/dist/dashboard/dashboard-component/dashboard-component.service.js.map +1 -1
  15. package/dist/dashboard/dashboard-component/dto/create.dto.d.ts +4 -0
  16. package/dist/dashboard/dashboard-component/dto/create.dto.d.ts.map +1 -1
  17. package/dist/dashboard/dashboard-component/dto/create.dto.js +15 -0
  18. package/dist/dashboard/dashboard-component/dto/create.dto.js.map +1 -1
  19. package/dist/dashboard/dashboard-component/dto/update.dto.d.ts +4 -0
  20. package/dist/dashboard/dashboard-component/dto/update.dto.d.ts.map +1 -1
  21. package/dist/dashboard/dashboard-component/dto/update.dto.js +15 -0
  22. package/dist/dashboard/dashboard-component/dto/update.dto.js.map +1 -1
  23. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +27 -8
  24. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
  25. package/dist/dashboard/dashboard-core/dashboard-core.controller.js +8 -6
  26. package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
  27. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +27 -8
  28. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
  29. package/dist/dashboard/dashboard-core/dashboard-core.service.js +98 -46
  30. package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
  31. package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts +3 -0
  32. package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts.map +1 -1
  33. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts +3 -0
  34. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
  35. package/dist/dashboard/dashboard-item/dto/index.d.ts +2 -0
  36. package/dist/dashboard/dashboard-item/dto/index.d.ts.map +1 -1
  37. package/dist/dashboard/dashboard-item/dto/index.js +4 -1
  38. package/dist/dashboard/dashboard-item/dto/index.js.map +1 -1
  39. package/dist/dashboard/dashboard-item/dto/update-layout.dto.d.ts +12 -0
  40. package/dist/dashboard/dashboard-item/dto/update-layout.dto.d.ts.map +1 -0
  41. package/dist/dashboard/dashboard-item/dto/update-layout.dto.js +52 -0
  42. package/dist/dashboard/dashboard-item/dto/update-layout.dto.js.map +1 -0
  43. package/hedhog/data/menu.yaml +28 -4
  44. package/hedhog/query/add-description-to-dashboard-component-locale.sql +99 -0
  45. package/hedhog/query/add-widget-metadata.sql +21 -0
  46. package/hedhog/query/fix-dashboard-stat-keys.sql +82 -0
  47. package/package.json +4 -4
  48. package/src/dashboard/dashboard/dashboard.controller.ts +2 -2
  49. package/src/dashboard/dashboard/dashboard.service.ts +25 -9
  50. package/src/dashboard/dashboard-component/dashboard-component.service.ts +30 -3
  51. package/src/dashboard/dashboard-component/dto/create.dto.ts +13 -1
  52. package/src/dashboard/dashboard-component/dto/update.dto.ts +13 -1
  53. package/src/dashboard/dashboard-core/dashboard-core.controller.ts +4 -2
  54. package/src/dashboard/dashboard-core/dashboard-core.service.ts +103 -49
  55. package/src/dashboard/dashboard-item/dashboard-item.service.ts +4 -4
  56. package/src/dashboard/dashboard-item/dto/index.ts +2 -0
  57. 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
- // Busca os itens do dashboard para este slug
96
- const dashboardItems = await this.prismaService.dashboard_item.findMany({
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
- dashboard: {
99
- slug,
99
+ user_id: userId,
100
+ dashboard_item: {
101
+ dashboard_id: dashboard.id,
100
102
  },
101
103
  },
102
104
  include: {
103
- dashboard_user: {
104
- where: {
105
- user_id: userId,
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 dashboardItems.map((item) => {
113
- const userLayout = item.dashboard_user[0];
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: item.dashboard_component.slug,
118
- x: userLayout?.x_axis ?? item.x_axis ?? 0,
119
- y: userLayout?.y_axis ?? item.y_axis ?? 0,
120
- w: userLayout?.width ?? item.width ?? 2,
121
- h: userLayout?.height ?? item.height ?? 2,
122
- minW: item.dashboard_component.min_width,
123
- maxW: item.dashboard_component.max_width,
124
- minH: item.dashboard_component.min_height,
125
- maxH: item.dashboard_component.max_height,
126
- isResizable: item.dashboard_component.is_resizable ?? true,
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
- // Cria um registro de dashboard_user para este usuário
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: 999, // Coloca no final
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
- forwardRef,
6
- Inject,
7
- Injectable,
8
- NotFoundException
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
+ }