@hed-hog/core 0.0.168 → 0.0.170
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 +3 -15
- package/dist/dashboard/dashboard/dashboard.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard/dashboard.service.d.ts +3 -15
- package/dist/dashboard/dashboard/dashboard.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +6 -78
- package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dashboard-component.controller.js +8 -6
- package/dist/dashboard/dashboard-component/dashboard-component.controller.js.map +1 -1
- package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +3 -79
- package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dashboard-component.service.js +55 -13
- package/dist/dashboard/dashboard-component/dashboard-component.service.js.map +1 -1
- package/dist/dashboard/dashboard-component/dto/create.dto.d.ts +0 -4
- package/dist/dashboard/dashboard-component/dto/create.dto.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dto/create.dto.js +0 -19
- package/dist/dashboard/dashboard-component/dto/create.dto.js.map +1 -1
- package/dist/dashboard/dashboard-component/dto/update.dto.d.ts +0 -4
- package/dist/dashboard/dashboard-component/dto/update.dto.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component/dto/update.dto.js +0 -20
- package/dist/dashboard/dashboard-component/dto/update.dto.js.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +36 -22
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.controller.js +0 -9
- package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +36 -22
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.service.js +123 -51
- package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
- package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts +0 -4
- package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts +0 -4
- package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
- package/hedhog/data/dashboard_component.yaml +16 -16
- package/hedhog/data/dashboard_component_role.yaml +48 -0
- package/hedhog/data/dashboard_item.yaml +55 -15
- package/hedhog/data/menu.yaml +3 -3
- package/hedhog/table/dashboard_component_role.yaml +16 -0
- package/package.json +3 -3
- package/src/dashboard/dashboard-component/dashboard-component.controller.ts +9 -5
- package/src/dashboard/dashboard-component/dashboard-component.service.ts +64 -14
- package/src/dashboard/dashboard-component/dto/create.dto.ts +0 -15
- package/src/dashboard/dashboard-component/dto/update.dto.ts +0 -16
- package/src/dashboard/dashboard-core/dashboard-core.controller.ts +0 -5
- package/src/dashboard/dashboard-core/dashboard-core.service.ts +152 -54
|
@@ -27,68 +27,170 @@ export class DashboardCoreService {
|
|
|
27
27
|
|
|
28
28
|
async getStatistics() {
|
|
29
29
|
const now = new Date();
|
|
30
|
+
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
30
31
|
const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
const twelveMonthsAgo = new Date(now.getFullYear() - 1, now.getMonth(), 1);
|
|
33
|
+
const currentMonthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
34
|
+
const lastMonthStart = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
|
35
|
+
const lastMonthEnd = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59);
|
|
36
|
+
|
|
37
|
+
const [
|
|
38
|
+
sessionsTodayCount,
|
|
39
|
+
activeUsersCount,
|
|
40
|
+
emailsSentCount,
|
|
41
|
+
rolesCount,
|
|
42
|
+
sessionsCurrentMonth,
|
|
43
|
+
usersCurrentMonth,
|
|
44
|
+
emailsCurrentMonth,
|
|
45
|
+
rolesCurrentMonth,
|
|
46
|
+
sessionsLastMonth,
|
|
47
|
+
usersLastMonth,
|
|
48
|
+
emailsLastMonth,
|
|
49
|
+
rolesLastMonth,
|
|
50
|
+
] = await Promise.all([
|
|
51
|
+
this.prismaService.user_session.count({ where: { created_at: { gte: todayStart } } }),
|
|
52
|
+
this.prismaService.user.count(),
|
|
53
|
+
this.prismaService.mail_sent.count(),
|
|
54
|
+
this.prismaService.role.count(),
|
|
55
|
+
this.prismaService.user_session.count({ where: { created_at: { gte: currentMonthStart } } }),
|
|
56
|
+
this.prismaService.user.count({ where: { created_at: { gte: currentMonthStart } } }),
|
|
57
|
+
this.prismaService.mail_sent.count({ where: { created_at: { gte: currentMonthStart } } }),
|
|
58
|
+
this.prismaService.role.count({ where: { created_at: { gte: currentMonthStart } } }),
|
|
59
|
+
this.prismaService.user_session.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
|
|
60
|
+
this.prismaService.user.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
|
|
61
|
+
this.prismaService.mail_sent.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
|
|
62
|
+
this.prismaService.role.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
const calculateChange = (current: number, previous: number) => {
|
|
66
|
+
if (previous === 0) {
|
|
67
|
+
return current === 0 ? 0 : 100;
|
|
68
|
+
}
|
|
69
|
+
return Number((((current - previous) / previous) * 100).toFixed(1));
|
|
70
|
+
};
|
|
40
71
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
});
|
|
72
|
+
const sessionsChange = calculateChange(sessionsCurrentMonth, sessionsLastMonth);
|
|
73
|
+
const usersChange = calculateChange(usersCurrentMonth, usersLastMonth);
|
|
74
|
+
const emailsChange = calculateChange(emailsCurrentMonth, emailsLastMonth);
|
|
75
|
+
const rolesChange = calculateChange(rolesCurrentMonth, rolesLastMonth);
|
|
48
76
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
77
|
+
const emailsPerWeek = await this.prismaService.$queryRaw<
|
|
78
|
+
Array<{ day: Date; sent: bigint }>
|
|
79
|
+
>`
|
|
80
|
+
SELECT
|
|
81
|
+
DATE("created_at") as day,
|
|
82
|
+
COUNT(*) as sent
|
|
83
|
+
FROM "mail_sent"
|
|
84
|
+
WHERE "created_at" >= ${sevenDaysAgo}
|
|
85
|
+
GROUP BY DATE("created_at")
|
|
86
|
+
ORDER BY day ASC
|
|
87
|
+
`;
|
|
55
88
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
totalSettings,
|
|
65
|
-
totalContacts,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
89
|
+
const weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
90
|
+
const emailWeekData = emailsPerWeek.map((item) => {
|
|
91
|
+
const dayOfWeek = new Date(item.day).getDay();
|
|
92
|
+
return {
|
|
93
|
+
day: weekDays[dayOfWeek],
|
|
94
|
+
sent: Number(item.sent),
|
|
95
|
+
};
|
|
96
|
+
});
|
|
68
97
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
|
|
72
|
-
const usersByDay = await this.prismaService.$queryRaw<
|
|
73
|
-
Array<{ date: Date; count: bigint }>
|
|
98
|
+
const permissionDistribution = await this.prismaService.$queryRaw<
|
|
99
|
+
Array<{ name: string; value: bigint }>
|
|
74
100
|
>`
|
|
75
|
-
SELECT
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
SELECT
|
|
102
|
+
r.slug as name,
|
|
103
|
+
COUNT(ru.user_id) as value
|
|
104
|
+
FROM "role" r
|
|
105
|
+
LEFT JOIN "role_user" ru ON r.id = ru.role_id
|
|
106
|
+
GROUP BY r.id, r.slug
|
|
107
|
+
ORDER BY value DESC
|
|
80
108
|
`;
|
|
81
109
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
110
|
+
const colors = ['#6366f1', '#10b981', '#f59e0b', '#8b5cf6', '#ec4899', '#14b8a6'];
|
|
111
|
+
const permissionsData = permissionDistribution.map((item, index) => ({
|
|
112
|
+
name: item.name,
|
|
113
|
+
value: Number(item.value),
|
|
114
|
+
color: colors[index % colors.length],
|
|
85
115
|
}));
|
|
116
|
+
|
|
117
|
+
const sessionActivity = await this.prismaService.$queryRaw<
|
|
118
|
+
Array<{ hour: number; active: bigint; expired: bigint }>
|
|
119
|
+
>`
|
|
120
|
+
SELECT
|
|
121
|
+
FLOOR(EXTRACT(HOUR FROM "created_at" AT TIME ZONE 'America/Sao_Paulo') / 2) * 2 as hour,
|
|
122
|
+
COUNT(CASE WHEN "expires_at" > NOW() THEN 1 END) as active,
|
|
123
|
+
COUNT(CASE WHEN "expires_at" <= NOW() THEN 1 END) as expired
|
|
124
|
+
FROM "user_session"
|
|
125
|
+
WHERE "created_at" >= ${todayStart}
|
|
126
|
+
GROUP BY FLOOR(EXTRACT(HOUR FROM "created_at" AT TIME ZONE 'America/Sao_Paulo') / 2)
|
|
127
|
+
ORDER BY hour ASC
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
const sessionActivityData = [];
|
|
131
|
+
for (let h = 0; h < 24; h += 2) {
|
|
132
|
+
const found = sessionActivity.find((s) => Number(s.hour) === h);
|
|
133
|
+
sessionActivityData.push({
|
|
134
|
+
hour: `${h.toString().padStart(2, '0')}h`,
|
|
135
|
+
active: found ? Number(found.active) : 0,
|
|
136
|
+
expired: found ? Number(found.expired) : 0,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const userGrowth = await this.prismaService.$queryRaw<
|
|
141
|
+
Array<{ month: Date; users: bigint; sessions: bigint }>
|
|
142
|
+
>`
|
|
143
|
+
SELECT
|
|
144
|
+
DATE_TRUNC('month', u."created_at") as month,
|
|
145
|
+
COUNT(DISTINCT u.id) as users,
|
|
146
|
+
COUNT(s.id) as sessions
|
|
147
|
+
FROM "user" u
|
|
148
|
+
LEFT JOIN "user_session" s ON u.id = s.user_id AND DATE_TRUNC('month', u."created_at") = DATE_TRUNC('month', s."created_at")
|
|
149
|
+
WHERE u."created_at" >= ${twelveMonthsAgo}
|
|
150
|
+
GROUP BY DATE_TRUNC('month', u."created_at")
|
|
151
|
+
ORDER BY month ASC
|
|
152
|
+
`;
|
|
153
|
+
|
|
154
|
+
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
155
|
+
const userGrowthData = userGrowth.map((item) => {
|
|
156
|
+
const monthIndex = new Date(item.month).getMonth() + 1;
|
|
157
|
+
return {
|
|
158
|
+
month: monthNames[monthIndex],
|
|
159
|
+
users: Number(item.users),
|
|
160
|
+
sessions: Number(item.sessions),
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
cards: {
|
|
166
|
+
sessionsToday: {
|
|
167
|
+
value: sessionsTodayCount,
|
|
168
|
+
change: sessionsChange,
|
|
169
|
+
},
|
|
170
|
+
activeUsers: {
|
|
171
|
+
value: activeUsersCount,
|
|
172
|
+
change: usersChange,
|
|
173
|
+
},
|
|
174
|
+
emailsSent: {
|
|
175
|
+
value: emailsSentCount,
|
|
176
|
+
change: emailsChange,
|
|
177
|
+
},
|
|
178
|
+
roles: {
|
|
179
|
+
value: rolesCount,
|
|
180
|
+
change: rolesChange,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
charts: {
|
|
184
|
+
emailsPerWeek: emailWeekData,
|
|
185
|
+
permissionDistribution: permissionsData,
|
|
186
|
+
sessionActivity: sessionActivityData,
|
|
187
|
+
userGrowth: userGrowthData,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
86
190
|
}
|
|
87
191
|
|
|
88
192
|
async getUserLayout(userId: number, slug: string, localeCode: string) {
|
|
89
|
-
const dashboard = await this.prismaService.dashboard.findFirst({
|
|
90
|
-
where: { slug },
|
|
91
|
-
});
|
|
193
|
+
const dashboard = await this.prismaService.dashboard.findFirst({ where: { slug } });
|
|
92
194
|
|
|
93
195
|
if (!dashboard) {
|
|
94
196
|
return [];
|
|
@@ -318,10 +420,6 @@ export class DashboardCoreService {
|
|
|
318
420
|
slug: component.slug,
|
|
319
421
|
name: locale?.name || component.slug,
|
|
320
422
|
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,
|
|
325
423
|
x: userLayout.x_axis,
|
|
326
424
|
y: userLayout.y_axis,
|
|
327
425
|
w: userLayout.width,
|